1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
27 /* Include insn-config.h before expr.h so that HAVE_conditional_move
28 is properly defined. */
29 #include "insn-config.h"
34 #include "insn-flags.h"
35 #include "insn-codes.h"
43 /* Each optab contains info on how this target machine
44 can perform a particular operation
45 for all sizes and kinds of operands.
47 The operation to be performed is often specified
48 by passing one of these optabs as an argument.
50 See expr.h for documentation of these optabs. */
52 optab optab_table[OTI_MAX];
54 rtx libfunc_table[LTI_MAX];
56 /* Tables of patterns for extending one integer mode to another. */
57 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
59 /* Tables of patterns for converting between fixed and floating point. */
60 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
61 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
62 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
64 /* Contains the optab used for each rtx code. */
65 optab code_to_optab[NUM_RTX_CODE + 1];
67 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
68 gives the gen_function to make a branch to test that condition. */
70 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
72 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
73 gives the insn code to make a store-condition insn
74 to test that condition. */
76 enum insn_code setcc_gen_code[NUM_RTX_CODE];
78 #ifdef HAVE_conditional_move
79 /* Indexed by the machine mode, gives the insn code to make a conditional
80 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
81 setcc_gen_code to cut down on the number of named patterns. Consider a day
82 when a lot more rtx codes are conditional (eg: for the ARM). */
84 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
87 static int add_equal_note PARAMS ((rtx, rtx, enum rtx_code, rtx, rtx));
88 static rtx widen_operand PARAMS ((rtx, enum machine_mode,
89 enum machine_mode, int, int));
90 static int expand_cmplxdiv_straight PARAMS ((rtx, rtx, rtx, rtx,
91 rtx, rtx, enum machine_mode,
92 int, enum optab_methods,
93 enum mode_class, optab));
94 static int expand_cmplxdiv_wide PARAMS ((rtx, rtx, rtx, rtx,
95 rtx, rtx, enum machine_mode,
96 int, enum optab_methods,
97 enum mode_class, optab));
98 static enum insn_code can_fix_p PARAMS ((enum machine_mode, enum machine_mode,
100 static enum insn_code can_float_p PARAMS ((enum machine_mode, enum machine_mode,
102 static rtx ftruncify PARAMS ((rtx));
103 static optab init_optab PARAMS ((enum rtx_code));
104 static void init_libfuncs PARAMS ((optab, int, int, const char *, int));
105 static void init_integral_libfuncs PARAMS ((optab, const char *, int));
106 static void init_floating_libfuncs PARAMS ((optab, const char *, int));
107 #ifdef HAVE_conditional_trap
108 static void init_traps PARAMS ((void));
110 static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode,
111 enum rtx_code, int, rtx));
112 static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
113 enum machine_mode *, int *));
115 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
116 the result of operation CODE applied to OP0 (and OP1 if it is a binary
119 If the last insn does not set TARGET, don't do anything, but return 1.
121 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
122 don't add the REG_EQUAL note but return 0. Our caller can then try
123 again, ensuring that TARGET is not one of the operands. */
126 add_equal_note (seq, target, code, op0, op1)
136 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
137 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
138 || GET_CODE (seq) != SEQUENCE
139 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
140 || GET_CODE (target) == ZERO_EXTRACT
141 || (! rtx_equal_p (SET_DEST (set), target)
142 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
144 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
145 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
149 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
150 besides the last insn. */
151 if (reg_overlap_mentioned_p (target, op0)
152 || (op1 && reg_overlap_mentioned_p (target, op1)))
153 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
154 if (reg_set_p (target, XVECEXP (seq, 0, i)))
157 if (GET_RTX_CLASS (code) == '1')
158 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
160 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
162 set_unique_reg_note (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1), REG_EQUAL, note);
167 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
168 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
169 not actually do a sign-extend or zero-extend, but can leave the
170 higher-order bits of the result rtx undefined, for example, in the case
171 of logical operations, but not right shifts. */
174 widen_operand (op, mode, oldmode, unsignedp, no_extend)
176 enum machine_mode mode, oldmode;
182 /* If we must extend do so. If OP is either a constant or a SUBREG
183 for a promoted object, also extend since it will be more efficient to
186 || GET_MODE (op) == VOIDmode
187 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
188 return convert_modes (mode, oldmode, op, unsignedp);
190 /* If MODE is no wider than a single word, we return a paradoxical
192 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
193 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
195 /* Otherwise, get an object of MODE, clobber it, and set the low-order
198 result = gen_reg_rtx (mode);
199 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
200 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
204 /* Generate code to perform a straightforward complex divide. */
207 expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
208 unsignedp, methods, class, binoptab)
209 rtx real0, real1, imag0, imag1, realr, imagr;
210 enum machine_mode submode;
212 enum optab_methods methods;
213 enum mode_class class;
220 optab this_add_optab = add_optab;
221 optab this_sub_optab = sub_optab;
222 optab this_neg_optab = neg_optab;
223 optab this_mul_optab = smul_optab;
225 if (binoptab == sdivv_optab)
227 this_add_optab = addv_optab;
228 this_sub_optab = subv_optab;
229 this_neg_optab = negv_optab;
230 this_mul_optab = smulv_optab;
233 /* Don't fetch these from memory more than once. */
234 real0 = force_reg (submode, real0);
235 real1 = force_reg (submode, real1);
238 imag0 = force_reg (submode, imag0);
240 imag1 = force_reg (submode, imag1);
242 /* Divisor: c*c + d*d. */
243 temp1 = expand_binop (submode, this_mul_optab, real1, real1,
244 NULL_RTX, unsignedp, methods);
246 temp2 = expand_binop (submode, this_mul_optab, imag1, imag1,
247 NULL_RTX, unsignedp, methods);
249 if (temp1 == 0 || temp2 == 0)
252 divisor = expand_binop (submode, this_add_optab, temp1, temp2,
253 NULL_RTX, unsignedp, methods);
259 /* Mathematically, ((a)(c-id))/divisor. */
260 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */
262 /* Calculate the dividend. */
263 real_t = expand_binop (submode, this_mul_optab, real0, real1,
264 NULL_RTX, unsignedp, methods);
266 imag_t = expand_binop (submode, this_mul_optab, real0, imag1,
267 NULL_RTX, unsignedp, methods);
269 if (real_t == 0 || imag_t == 0)
272 imag_t = expand_unop (submode, this_neg_optab, imag_t,
273 NULL_RTX, unsignedp);
277 /* Mathematically, ((a+ib)(c-id))/divider. */
278 /* Calculate the dividend. */
279 temp1 = expand_binop (submode, this_mul_optab, real0, real1,
280 NULL_RTX, unsignedp, methods);
282 temp2 = expand_binop (submode, this_mul_optab, imag0, imag1,
283 NULL_RTX, unsignedp, methods);
285 if (temp1 == 0 || temp2 == 0)
288 real_t = expand_binop (submode, this_add_optab, temp1, temp2,
289 NULL_RTX, unsignedp, methods);
291 temp1 = expand_binop (submode, this_mul_optab, imag0, real1,
292 NULL_RTX, unsignedp, methods);
294 temp2 = expand_binop (submode, this_mul_optab, real0, imag1,
295 NULL_RTX, unsignedp, methods);
297 if (temp1 == 0 || temp2 == 0)
300 imag_t = expand_binop (submode, this_sub_optab, temp1, temp2,
301 NULL_RTX, unsignedp, methods);
303 if (real_t == 0 || imag_t == 0)
307 if (class == MODE_COMPLEX_FLOAT)
308 res = expand_binop (submode, binoptab, real_t, divisor,
309 realr, unsignedp, methods);
311 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
312 real_t, divisor, realr, unsignedp);
318 emit_move_insn (realr, res);
320 if (class == MODE_COMPLEX_FLOAT)
321 res = expand_binop (submode, binoptab, imag_t, divisor,
322 imagr, unsignedp, methods);
324 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
325 imag_t, divisor, imagr, unsignedp);
331 emit_move_insn (imagr, res);
336 /* Generate code to perform a wide-input-range-acceptable complex divide. */
339 expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
340 unsignedp, methods, class, binoptab)
341 rtx real0, real1, imag0, imag1, realr, imagr;
342 enum machine_mode submode;
344 enum optab_methods methods;
345 enum mode_class class;
350 rtx temp1, temp2, lab1, lab2;
351 enum machine_mode mode;
354 optab this_add_optab = add_optab;
355 optab this_sub_optab = sub_optab;
356 optab this_neg_optab = neg_optab;
357 optab this_mul_optab = smul_optab;
359 if (binoptab == sdivv_optab)
361 this_add_optab = addv_optab;
362 this_sub_optab = subv_optab;
363 this_neg_optab = negv_optab;
364 this_mul_optab = smulv_optab;
367 /* Don't fetch these from memory more than once. */
368 real0 = force_reg (submode, real0);
369 real1 = force_reg (submode, real1);
372 imag0 = force_reg (submode, imag0);
374 imag1 = force_reg (submode, imag1);
376 /* XXX What's an "unsigned" complex number? */
384 temp1 = expand_abs (submode, real1, NULL_RTX, unsignedp, 1);
385 temp2 = expand_abs (submode, imag1, NULL_RTX, unsignedp, 1);
388 if (temp1 == 0 || temp2 == 0)
391 mode = GET_MODE (temp1);
392 align = GET_MODE_ALIGNMENT (mode);
393 lab1 = gen_label_rtx ();
394 emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX,
395 mode, unsignedp, align, lab1);
397 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */
399 if (class == MODE_COMPLEX_FLOAT)
400 ratio = expand_binop (submode, binoptab, imag1, real1,
401 NULL_RTX, unsignedp, methods);
403 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
404 imag1, real1, NULL_RTX, unsignedp);
409 /* Calculate divisor. */
411 temp1 = expand_binop (submode, this_mul_optab, imag1, ratio,
412 NULL_RTX, unsignedp, methods);
417 divisor = expand_binop (submode, this_add_optab, temp1, real1,
418 NULL_RTX, unsignedp, methods);
423 /* Calculate dividend. */
429 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */
431 imag_t = expand_binop (submode, this_mul_optab, real0, ratio,
432 NULL_RTX, unsignedp, methods);
437 imag_t = expand_unop (submode, this_neg_optab, imag_t,
438 NULL_RTX, unsignedp);
440 if (real_t == 0 || imag_t == 0)
445 /* Compute (a+ib)/(c+id) as
446 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */
448 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
449 NULL_RTX, unsignedp, methods);
454 real_t = expand_binop (submode, this_add_optab, temp1, real0,
455 NULL_RTX, unsignedp, methods);
457 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
458 NULL_RTX, unsignedp, methods);
463 imag_t = expand_binop (submode, this_sub_optab, imag0, temp1,
464 NULL_RTX, unsignedp, methods);
466 if (real_t == 0 || imag_t == 0)
470 if (class == MODE_COMPLEX_FLOAT)
471 res = expand_binop (submode, binoptab, real_t, divisor,
472 realr, unsignedp, methods);
474 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
475 real_t, divisor, realr, unsignedp);
481 emit_move_insn (realr, res);
483 if (class == MODE_COMPLEX_FLOAT)
484 res = expand_binop (submode, binoptab, imag_t, divisor,
485 imagr, unsignedp, methods);
487 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
488 imag_t, divisor, imagr, unsignedp);
494 emit_move_insn (imagr, res);
496 lab2 = gen_label_rtx ();
497 emit_jump_insn (gen_jump (lab2));
502 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */
504 if (class == MODE_COMPLEX_FLOAT)
505 ratio = expand_binop (submode, binoptab, real1, imag1,
506 NULL_RTX, unsignedp, methods);
508 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
509 real1, imag1, NULL_RTX, unsignedp);
514 /* Calculate divisor. */
516 temp1 = expand_binop (submode, this_mul_optab, real1, ratio,
517 NULL_RTX, unsignedp, methods);
522 divisor = expand_binop (submode, this_add_optab, temp1, imag1,
523 NULL_RTX, unsignedp, methods);
528 /* Calculate dividend. */
532 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */
534 real_t = expand_binop (submode, this_mul_optab, real0, ratio,
535 NULL_RTX, unsignedp, methods);
537 imag_t = expand_unop (submode, this_neg_optab, real0,
538 NULL_RTX, unsignedp);
540 if (real_t == 0 || imag_t == 0)
545 /* Compute (a+ib)/(c+id) as
546 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */
548 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
549 NULL_RTX, unsignedp, methods);
554 real_t = expand_binop (submode, this_add_optab, temp1, imag0,
555 NULL_RTX, unsignedp, methods);
557 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
558 NULL_RTX, unsignedp, methods);
563 imag_t = expand_binop (submode, this_sub_optab, temp1, real0,
564 NULL_RTX, unsignedp, methods);
566 if (real_t == 0 || imag_t == 0)
570 if (class == MODE_COMPLEX_FLOAT)
571 res = expand_binop (submode, binoptab, real_t, divisor,
572 realr, unsignedp, methods);
574 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
575 real_t, divisor, realr, unsignedp);
581 emit_move_insn (realr, res);
583 if (class == MODE_COMPLEX_FLOAT)
584 res = expand_binop (submode, binoptab, imag_t, divisor,
585 imagr, unsignedp, methods);
587 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
588 imag_t, divisor, imagr, unsignedp);
594 emit_move_insn (imagr, res);
601 /* Generate code to perform an operation specified by BINOPTAB
602 on operands OP0 and OP1, with result having machine-mode MODE.
604 UNSIGNEDP is for the case where we have to widen the operands
605 to perform the operation. It says to use zero-extension.
607 If TARGET is nonzero, the value
608 is generated there, if it is convenient to do so.
609 In all cases an rtx is returned for the locus of the value;
610 this may or may not be TARGET. */
613 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
614 enum machine_mode mode;
619 enum optab_methods methods;
621 enum optab_methods next_methods
622 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
623 ? OPTAB_WIDEN : methods);
624 enum mode_class class;
625 enum machine_mode wider_mode;
627 int commutative_op = 0;
628 int shift_op = (binoptab->code == ASHIFT
629 || binoptab->code == ASHIFTRT
630 || binoptab->code == LSHIFTRT
631 || binoptab->code == ROTATE
632 || binoptab->code == ROTATERT);
633 rtx entry_last = get_last_insn ();
636 class = GET_MODE_CLASS (mode);
638 op0 = protect_from_queue (op0, 0);
639 op1 = protect_from_queue (op1, 0);
641 target = protect_from_queue (target, 1);
645 op0 = force_not_mem (op0);
646 op1 = force_not_mem (op1);
649 /* If subtracting an integer constant, convert this into an addition of
650 the negated constant. */
652 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
654 op1 = negate_rtx (mode, op1);
655 binoptab = add_optab;
658 /* If we are inside an appropriately-short loop and one operand is an
659 expensive constant, force it into a register. */
660 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
661 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
662 op0 = force_reg (mode, op0);
664 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
665 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
666 op1 = force_reg (mode, op1);
668 /* Record where to delete back to if we backtrack. */
669 last = get_last_insn ();
671 /* If operation is commutative,
672 try to make the first operand a register.
673 Even better, try to make it the same as the target.
674 Also try to make the last operand a constant. */
675 if (GET_RTX_CLASS (binoptab->code) == 'c'
676 || binoptab == smul_widen_optab
677 || binoptab == umul_widen_optab
678 || binoptab == smul_highpart_optab
679 || binoptab == umul_highpart_optab)
683 if (((target == 0 || GET_CODE (target) == REG)
684 ? ((GET_CODE (op1) == REG
685 && GET_CODE (op0) != REG)
687 : rtx_equal_p (op1, target))
688 || GET_CODE (op0) == CONST_INT)
696 /* If we can do it with a three-operand insn, do so. */
698 if (methods != OPTAB_MUST_WIDEN
699 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
701 int icode = (int) binoptab->handlers[(int) mode].insn_code;
702 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
703 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
705 rtx xop0 = op0, xop1 = op1;
710 temp = gen_reg_rtx (mode);
712 /* If it is a commutative operator and the modes would match
713 if we would swap the operands, we can save the conversions. */
716 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
717 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
721 tmp = op0; op0 = op1; op1 = tmp;
722 tmp = xop0; xop0 = xop1; xop1 = tmp;
726 /* In case the insn wants input operands in modes different from
727 the result, convert the operands. */
729 if (GET_MODE (op0) != VOIDmode
730 && GET_MODE (op0) != mode0
731 && mode0 != VOIDmode)
732 xop0 = convert_to_mode (mode0, xop0, unsignedp);
734 if (GET_MODE (xop1) != VOIDmode
735 && GET_MODE (xop1) != mode1
736 && mode1 != VOIDmode)
737 xop1 = convert_to_mode (mode1, xop1, unsignedp);
739 /* Now, if insn's predicates don't allow our operands, put them into
742 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)
743 && mode0 != VOIDmode)
744 xop0 = copy_to_mode_reg (mode0, xop0);
746 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
747 && mode1 != VOIDmode)
748 xop1 = copy_to_mode_reg (mode1, xop1);
750 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
751 temp = gen_reg_rtx (mode);
753 pat = GEN_FCN (icode) (temp, xop0, xop1);
756 /* If PAT is a multi-insn sequence, try to add an appropriate
757 REG_EQUAL note to it. If we can't because TEMP conflicts with an
758 operand, call ourselves again, this time without a target. */
759 if (GET_CODE (pat) == SEQUENCE
760 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
762 delete_insns_since (last);
763 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
771 delete_insns_since (last);
774 /* If this is a multiply, see if we can do a widening operation that
775 takes operands of this mode and makes a wider mode. */
777 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
778 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
779 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
780 != CODE_FOR_nothing))
782 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
783 unsignedp ? umul_widen_optab : smul_widen_optab,
784 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
788 if (GET_MODE_CLASS (mode) == MODE_INT)
789 return gen_lowpart (mode, temp);
791 return convert_to_mode (mode, temp, unsignedp);
795 /* Look for a wider mode of the same class for which we think we
796 can open-code the operation. Check for a widening multiply at the
797 wider mode as well. */
799 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
800 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
801 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
802 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
804 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
805 || (binoptab == smul_optab
806 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
807 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
808 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
809 != CODE_FOR_nothing)))
811 rtx xop0 = op0, xop1 = op1;
814 /* For certain integer operations, we need not actually extend
815 the narrow operands, as long as we will truncate
816 the results to the same narrowness. */
818 if ((binoptab == ior_optab || binoptab == and_optab
819 || binoptab == xor_optab
820 || binoptab == add_optab || binoptab == sub_optab
821 || binoptab == smul_optab || binoptab == ashl_optab)
822 && class == MODE_INT)
825 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
827 /* The second operand of a shift must always be extended. */
828 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
829 no_extend && binoptab != ashl_optab);
831 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
832 unsignedp, OPTAB_DIRECT);
835 if (class != MODE_INT)
838 target = gen_reg_rtx (mode);
839 convert_move (target, temp, 0);
843 return gen_lowpart (mode, temp);
846 delete_insns_since (last);
850 /* These can be done a word at a time. */
851 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
853 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
854 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
860 /* If TARGET is the same as one of the operands, the REG_EQUAL note
861 won't be accurate, so use a new target. */
862 if (target == 0 || target == op0 || target == op1)
863 target = gen_reg_rtx (mode);
867 /* Do the actual arithmetic. */
868 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
870 rtx target_piece = operand_subword (target, i, 1, mode);
871 rtx x = expand_binop (word_mode, binoptab,
872 operand_subword_force (op0, i, mode),
873 operand_subword_force (op1, i, mode),
874 target_piece, unsignedp, next_methods);
879 if (target_piece != x)
880 emit_move_insn (target_piece, x);
883 insns = get_insns ();
886 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
888 if (binoptab->code != UNKNOWN)
890 = gen_rtx_fmt_ee (binoptab->code, mode,
891 copy_rtx (op0), copy_rtx (op1));
895 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
900 /* Synthesize double word shifts from single word shifts. */
901 if ((binoptab == lshr_optab || binoptab == ashl_optab
902 || binoptab == ashr_optab)
904 && GET_CODE (op1) == CONST_INT
905 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
906 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
907 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
908 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
910 rtx insns, inter, equiv_value;
911 rtx into_target, outof_target;
912 rtx into_input, outof_input;
913 int shift_count, left_shift, outof_word;
915 /* If TARGET is the same as one of the operands, the REG_EQUAL note
916 won't be accurate, so use a new target. */
917 if (target == 0 || target == op0 || target == op1)
918 target = gen_reg_rtx (mode);
922 shift_count = INTVAL (op1);
924 /* OUTOF_* is the word we are shifting bits away from, and
925 INTO_* is the word that we are shifting bits towards, thus
926 they differ depending on the direction of the shift and
929 left_shift = binoptab == ashl_optab;
930 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
932 outof_target = operand_subword (target, outof_word, 1, mode);
933 into_target = operand_subword (target, 1 - outof_word, 1, mode);
935 outof_input = operand_subword_force (op0, outof_word, mode);
936 into_input = operand_subword_force (op0, 1 - outof_word, mode);
938 if (shift_count >= BITS_PER_WORD)
940 inter = expand_binop (word_mode, binoptab,
942 GEN_INT (shift_count - BITS_PER_WORD),
943 into_target, unsignedp, next_methods);
945 if (inter != 0 && inter != into_target)
946 emit_move_insn (into_target, inter);
948 /* For a signed right shift, we must fill the word we are shifting
949 out of with copies of the sign bit. Otherwise it is zeroed. */
950 if (inter != 0 && binoptab != ashr_optab)
951 inter = CONST0_RTX (word_mode);
953 inter = expand_binop (word_mode, binoptab,
955 GEN_INT (BITS_PER_WORD - 1),
956 outof_target, unsignedp, next_methods);
958 if (inter != 0 && inter != outof_target)
959 emit_move_insn (outof_target, inter);
964 optab reverse_unsigned_shift, unsigned_shift;
966 /* For a shift of less then BITS_PER_WORD, to compute the carry,
967 we must do a logical shift in the opposite direction of the
970 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
972 /* For a shift of less than BITS_PER_WORD, to compute the word
973 shifted towards, we need to unsigned shift the orig value of
976 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
978 carries = expand_binop (word_mode, reverse_unsigned_shift,
980 GEN_INT (BITS_PER_WORD - shift_count),
981 0, unsignedp, next_methods);
986 inter = expand_binop (word_mode, unsigned_shift, into_input,
987 op1, 0, unsignedp, next_methods);
990 inter = expand_binop (word_mode, ior_optab, carries, inter,
991 into_target, unsignedp, next_methods);
993 if (inter != 0 && inter != into_target)
994 emit_move_insn (into_target, inter);
997 inter = expand_binop (word_mode, binoptab, outof_input,
998 op1, outof_target, unsignedp, next_methods);
1000 if (inter != 0 && inter != outof_target)
1001 emit_move_insn (outof_target, inter);
1004 insns = get_insns ();
1009 if (binoptab->code != UNKNOWN)
1010 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1014 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1019 /* Synthesize double word rotates from single word shifts. */
1020 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1021 && class == MODE_INT
1022 && GET_CODE (op1) == CONST_INT
1023 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1024 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1025 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1027 rtx insns, equiv_value;
1028 rtx into_target, outof_target;
1029 rtx into_input, outof_input;
1031 int shift_count, left_shift, outof_word;
1033 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1034 won't be accurate, so use a new target. */
1035 if (target == 0 || target == op0 || target == op1)
1036 target = gen_reg_rtx (mode);
1040 shift_count = INTVAL (op1);
1042 /* OUTOF_* is the word we are shifting bits away from, and
1043 INTO_* is the word that we are shifting bits towards, thus
1044 they differ depending on the direction of the shift and
1045 WORDS_BIG_ENDIAN. */
1047 left_shift = (binoptab == rotl_optab);
1048 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1050 outof_target = operand_subword (target, outof_word, 1, mode);
1051 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1053 outof_input = operand_subword_force (op0, outof_word, mode);
1054 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1056 if (shift_count == BITS_PER_WORD)
1058 /* This is just a word swap. */
1059 emit_move_insn (outof_target, into_input);
1060 emit_move_insn (into_target, outof_input);
1065 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1066 rtx first_shift_count, second_shift_count;
1067 optab reverse_unsigned_shift, unsigned_shift;
1069 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1070 ? lshr_optab : ashl_optab);
1072 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1073 ? ashl_optab : lshr_optab);
1075 if (shift_count > BITS_PER_WORD)
1077 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1078 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
1082 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1083 second_shift_count = GEN_INT (shift_count);
1086 into_temp1 = expand_binop (word_mode, unsigned_shift,
1087 outof_input, first_shift_count,
1088 NULL_RTX, unsignedp, next_methods);
1089 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1090 into_input, second_shift_count,
1091 into_target, unsignedp, next_methods);
1093 if (into_temp1 != 0 && into_temp2 != 0)
1094 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1095 into_target, unsignedp, next_methods);
1099 if (inter != 0 && inter != into_target)
1100 emit_move_insn (into_target, inter);
1102 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1103 into_input, first_shift_count,
1104 NULL_RTX, unsignedp, next_methods);
1105 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1106 outof_input, second_shift_count,
1107 outof_target, unsignedp, next_methods);
1109 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1110 inter = expand_binop (word_mode, ior_optab,
1111 outof_temp1, outof_temp2,
1112 outof_target, unsignedp, next_methods);
1114 if (inter != 0 && inter != outof_target)
1115 emit_move_insn (outof_target, inter);
1118 insns = get_insns ();
1123 if (binoptab->code != UNKNOWN)
1124 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1128 /* We can't make this a no conflict block if this is a word swap,
1129 because the word swap case fails if the input and output values
1130 are in the same register. */
1131 if (shift_count != BITS_PER_WORD)
1132 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1141 /* These can be done a word at a time by propagating carries. */
1142 if ((binoptab == add_optab || binoptab == sub_optab)
1143 && class == MODE_INT
1144 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1145 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1148 rtx carry_tmp = gen_reg_rtx (word_mode);
1149 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1150 unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1151 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1154 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1155 value is one of those, use it. Otherwise, use 1 since it is the
1156 one easiest to get. */
1157 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1158 int normalizep = STORE_FLAG_VALUE;
1163 /* Prepare the operands. */
1164 xop0 = force_reg (mode, op0);
1165 xop1 = force_reg (mode, op1);
1167 if (target == 0 || GET_CODE (target) != REG
1168 || target == xop0 || target == xop1)
1169 target = gen_reg_rtx (mode);
1171 /* Indicate for flow that the entire target reg is being set. */
1172 if (GET_CODE (target) == REG)
1173 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
1175 /* Do the actual arithmetic. */
1176 for (i = 0; i < nwords; i++)
1178 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1179 rtx target_piece = operand_subword (target, index, 1, mode);
1180 rtx op0_piece = operand_subword_force (xop0, index, mode);
1181 rtx op1_piece = operand_subword_force (xop1, index, mode);
1184 /* Main add/subtract of the input operands. */
1185 x = expand_binop (word_mode, binoptab,
1186 op0_piece, op1_piece,
1187 target_piece, unsignedp, next_methods);
1193 /* Store carry from main add/subtract. */
1194 carry_out = gen_reg_rtx (word_mode);
1195 carry_out = emit_store_flag_force (carry_out,
1196 (binoptab == add_optab
1199 word_mode, 1, normalizep);
1204 /* Add/subtract previous carry to main result. */
1205 x = expand_binop (word_mode,
1206 normalizep == 1 ? binoptab : otheroptab,
1208 target_piece, 1, next_methods);
1211 else if (target_piece != x)
1212 emit_move_insn (target_piece, x);
1216 /* THIS CODE HAS NOT BEEN TESTED. */
1217 /* Get out carry from adding/subtracting carry in. */
1218 carry_tmp = emit_store_flag_force (carry_tmp,
1219 binoptab == add_optab
1222 word_mode, 1, normalizep);
1224 /* Logical-ior the two poss. carry together. */
1225 carry_out = expand_binop (word_mode, ior_optab,
1226 carry_out, carry_tmp,
1227 carry_out, 0, next_methods);
1233 carry_in = carry_out;
1236 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1238 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1240 rtx temp = emit_move_insn (target, target);
1242 set_unique_reg_note (temp,
1244 gen_rtx_fmt_ee (binoptab->code, mode,
1253 delete_insns_since (last);
1256 /* If we want to multiply two two-word values and have normal and widening
1257 multiplies of single-word values, we can do this with three smaller
1258 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1259 because we are not operating on one word at a time.
1261 The multiplication proceeds as follows:
1262 _______________________
1263 [__op0_high_|__op0_low__]
1264 _______________________
1265 * [__op1_high_|__op1_low__]
1266 _______________________________________________
1267 _______________________
1268 (1) [__op0_low__*__op1_low__]
1269 _______________________
1270 (2a) [__op0_low__*__op1_high_]
1271 _______________________
1272 (2b) [__op0_high_*__op1_low__]
1273 _______________________
1274 (3) [__op0_high_*__op1_high_]
1277 This gives a 4-word result. Since we are only interested in the
1278 lower 2 words, partial result (3) and the upper words of (2a) and
1279 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1280 calculated using non-widening multiplication.
1282 (1), however, needs to be calculated with an unsigned widening
1283 multiplication. If this operation is not directly supported we
1284 try using a signed widening multiplication and adjust the result.
1285 This adjustment works as follows:
1287 If both operands are positive then no adjustment is needed.
1289 If the operands have different signs, for example op0_low < 0 and
1290 op1_low >= 0, the instruction treats the most significant bit of
1291 op0_low as a sign bit instead of a bit with significance
1292 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1293 with 2**BITS_PER_WORD - op0_low, and two's complements the
1294 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1297 Similarly, if both operands are negative, we need to add
1298 (op0_low + op1_low) * 2**BITS_PER_WORD.
1300 We use a trick to adjust quickly. We logically shift op0_low right
1301 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1302 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1303 logical shift exists, we do an arithmetic right shift and subtract
1306 if (binoptab == smul_optab
1307 && class == MODE_INT
1308 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1309 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1310 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1311 && ((umul_widen_optab->handlers[(int) mode].insn_code
1312 != CODE_FOR_nothing)
1313 || (smul_widen_optab->handlers[(int) mode].insn_code
1314 != CODE_FOR_nothing)))
1316 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1317 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1318 rtx op0_high = operand_subword_force (op0, high, mode);
1319 rtx op0_low = operand_subword_force (op0, low, mode);
1320 rtx op1_high = operand_subword_force (op1, high, mode);
1321 rtx op1_low = operand_subword_force (op1, low, mode);
1323 rtx op0_xhigh = NULL_RTX;
1324 rtx op1_xhigh = NULL_RTX;
1326 /* If the target is the same as one of the inputs, don't use it. This
1327 prevents problems with the REG_EQUAL note. */
1328 if (target == op0 || target == op1
1329 || (target != 0 && GET_CODE (target) != REG))
1332 /* Multiply the two lower words to get a double-word product.
1333 If unsigned widening multiplication is available, use that;
1334 otherwise use the signed form and compensate. */
1336 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1338 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1339 target, 1, OPTAB_DIRECT);
1341 /* If we didn't succeed, delete everything we did so far. */
1343 delete_insns_since (last);
1345 op0_xhigh = op0_high, op1_xhigh = op1_high;
1349 && smul_widen_optab->handlers[(int) mode].insn_code
1350 != CODE_FOR_nothing)
1352 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1353 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1354 target, 1, OPTAB_DIRECT);
1355 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1356 NULL_RTX, 1, next_methods);
1358 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1359 op0_xhigh, op0_xhigh, 0, next_methods);
1362 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1363 NULL_RTX, 0, next_methods);
1365 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1366 op0_xhigh, op0_xhigh, 0,
1370 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1371 NULL_RTX, 1, next_methods);
1373 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1374 op1_xhigh, op1_xhigh, 0, next_methods);
1377 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1378 NULL_RTX, 0, next_methods);
1380 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1381 op1_xhigh, op1_xhigh, 0,
1386 /* If we have been able to directly compute the product of the
1387 low-order words of the operands and perform any required adjustments
1388 of the operands, we proceed by trying two more multiplications
1389 and then computing the appropriate sum.
1391 We have checked above that the required addition is provided.
1392 Full-word addition will normally always succeed, especially if
1393 it is provided at all, so we don't worry about its failure. The
1394 multiplication may well fail, however, so we do handle that. */
1396 if (product && op0_xhigh && op1_xhigh)
1398 rtx product_high = operand_subword (product, high, 1, mode);
1399 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1400 NULL_RTX, 0, OPTAB_DIRECT);
1403 temp = expand_binop (word_mode, add_optab, temp, product_high,
1404 product_high, 0, next_methods);
1406 if (temp != 0 && temp != product_high)
1407 emit_move_insn (product_high, temp);
1410 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1411 NULL_RTX, 0, OPTAB_DIRECT);
1414 temp = expand_binop (word_mode, add_optab, temp,
1415 product_high, product_high,
1418 if (temp != 0 && temp != product_high)
1419 emit_move_insn (product_high, temp);
1423 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1425 temp = emit_move_insn (product, product);
1426 set_unique_reg_note (temp,
1428 gen_rtx_fmt_ee (MULT, mode,
1437 /* If we get here, we couldn't do it for some reason even though we
1438 originally thought we could. Delete anything we've emitted in
1441 delete_insns_since (last);
1444 /* We need to open-code the complex type operations: '+, -, * and /' */
1446 /* At this point we allow operations between two similar complex
1447 numbers, and also if one of the operands is not a complex number
1448 but rather of MODE_FLOAT or MODE_INT. However, the caller
1449 must make sure that the MODE of the non-complex operand matches
1450 the SUBMODE of the complex operand. */
1452 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1454 rtx real0 = 0, imag0 = 0;
1455 rtx real1 = 0, imag1 = 0;
1456 rtx realr, imagr, res;
1461 /* Find the correct mode for the real and imaginary parts */
1462 enum machine_mode submode
1463 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1464 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1467 if (submode == BLKmode)
1471 target = gen_reg_rtx (mode);
1475 realr = gen_realpart (submode, target);
1476 imagr = gen_imagpart (submode, target);
1478 if (GET_MODE (op0) == mode)
1480 real0 = gen_realpart (submode, op0);
1481 imag0 = gen_imagpart (submode, op0);
1486 if (GET_MODE (op1) == mode)
1488 real1 = gen_realpart (submode, op1);
1489 imag1 = gen_imagpart (submode, op1);
1494 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1497 switch (binoptab->code)
1500 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1502 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1503 res = expand_binop (submode, binoptab, real0, real1,
1504 realr, unsignedp, methods);
1508 else if (res != realr)
1509 emit_move_insn (realr, res);
1512 res = expand_binop (submode, binoptab, imag0, imag1,
1513 imagr, unsignedp, methods);
1516 else if (binoptab->code == MINUS)
1517 res = expand_unop (submode,
1518 binoptab == subv_optab ? negv_optab : neg_optab,
1519 imag1, imagr, unsignedp);
1525 else if (res != imagr)
1526 emit_move_insn (imagr, res);
1532 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1538 /* Don't fetch these from memory more than once. */
1539 real0 = force_reg (submode, real0);
1540 real1 = force_reg (submode, real1);
1541 imag0 = force_reg (submode, imag0);
1542 imag1 = force_reg (submode, imag1);
1544 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1545 unsignedp, methods);
1547 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1548 unsignedp, methods);
1550 if (temp1 == 0 || temp2 == 0)
1555 binoptab == smulv_optab ? subv_optab : sub_optab,
1556 temp1, temp2, realr, unsignedp, methods));
1560 else if (res != realr)
1561 emit_move_insn (realr, res);
1563 temp1 = expand_binop (submode, binoptab, real0, imag1,
1564 NULL_RTX, unsignedp, methods);
1566 temp2 = expand_binop (submode, binoptab, real1, imag0,
1567 NULL_RTX, unsignedp, methods);
1569 if (temp1 == 0 || temp2 == 0)
1574 binoptab == smulv_optab ? addv_optab : add_optab,
1575 temp1, temp2, imagr, unsignedp, methods));
1579 else if (res != imagr)
1580 emit_move_insn (imagr, res);
1586 /* Don't fetch these from memory more than once. */
1587 real0 = force_reg (submode, real0);
1588 real1 = force_reg (submode, real1);
1590 res = expand_binop (submode, binoptab, real0, real1,
1591 realr, unsignedp, methods);
1594 else if (res != realr)
1595 emit_move_insn (realr, res);
1598 res = expand_binop (submode, binoptab,
1599 real1, imag0, imagr, unsignedp, methods);
1601 res = expand_binop (submode, binoptab,
1602 real0, imag1, imagr, unsignedp, methods);
1606 else if (res != imagr)
1607 emit_move_insn (imagr, res);
1614 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1618 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1620 /* Don't fetch these from memory more than once. */
1621 real1 = force_reg (submode, real1);
1623 /* Simply divide the real and imaginary parts by `c' */
1624 if (class == MODE_COMPLEX_FLOAT)
1625 res = expand_binop (submode, binoptab, real0, real1,
1626 realr, unsignedp, methods);
1628 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1629 real0, real1, realr, unsignedp);
1633 else if (res != realr)
1634 emit_move_insn (realr, res);
1636 if (class == MODE_COMPLEX_FLOAT)
1637 res = expand_binop (submode, binoptab, imag0, real1,
1638 imagr, unsignedp, methods);
1640 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1641 imag0, real1, imagr, unsignedp);
1645 else if (res != imagr)
1646 emit_move_insn (imagr, res);
1652 switch (flag_complex_divide_method)
1655 ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
1656 realr, imagr, submode,
1662 ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
1663 realr, imagr, submode,
1683 if (binoptab->code != UNKNOWN)
1685 = gen_rtx_fmt_ee (binoptab->code, mode,
1686 copy_rtx (op0), copy_rtx (op1));
1690 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1696 /* It can't be open-coded in this mode.
1697 Use a library call if one is available and caller says that's ok. */
1699 if (binoptab->handlers[(int) mode].libfunc
1700 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1704 enum machine_mode op1_mode = mode;
1711 op1_mode = word_mode;
1712 /* Specify unsigned here,
1713 since negative shift counts are meaningless. */
1714 op1x = convert_to_mode (word_mode, op1, 1);
1717 if (GET_MODE (op0) != VOIDmode
1718 && GET_MODE (op0) != mode)
1719 op0 = convert_to_mode (mode, op0, unsignedp);
1721 /* Pass 1 for NO_QUEUE so we don't lose any increments
1722 if the libcall is cse'd or moved. */
1723 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1724 NULL_RTX, LCT_CONST, mode, 2,
1725 op0, mode, op1x, op1_mode);
1727 insns = get_insns ();
1730 target = gen_reg_rtx (mode);
1731 emit_libcall_block (insns, target, value,
1732 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1737 delete_insns_since (last);
1739 /* It can't be done in this mode. Can we do it in a wider mode? */
1741 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1742 || methods == OPTAB_MUST_WIDEN))
1744 /* Caller says, don't even try. */
1745 delete_insns_since (entry_last);
1749 /* Compute the value of METHODS to pass to recursive calls.
1750 Don't allow widening to be tried recursively. */
1752 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1754 /* Look for a wider mode of the same class for which it appears we can do
1757 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1759 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1760 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1762 if ((binoptab->handlers[(int) wider_mode].insn_code
1763 != CODE_FOR_nothing)
1764 || (methods == OPTAB_LIB
1765 && binoptab->handlers[(int) wider_mode].libfunc))
1767 rtx xop0 = op0, xop1 = op1;
1770 /* For certain integer operations, we need not actually extend
1771 the narrow operands, as long as we will truncate
1772 the results to the same narrowness. */
1774 if ((binoptab == ior_optab || binoptab == and_optab
1775 || binoptab == xor_optab
1776 || binoptab == add_optab || binoptab == sub_optab
1777 || binoptab == smul_optab || binoptab == ashl_optab)
1778 && class == MODE_INT)
1781 xop0 = widen_operand (xop0, wider_mode, mode,
1782 unsignedp, no_extend);
1784 /* The second operand of a shift must always be extended. */
1785 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1786 no_extend && binoptab != ashl_optab);
1788 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1789 unsignedp, methods);
1792 if (class != MODE_INT)
1795 target = gen_reg_rtx (mode);
1796 convert_move (target, temp, 0);
1800 return gen_lowpart (mode, temp);
1803 delete_insns_since (last);
1808 delete_insns_since (entry_last);
1812 /* Expand a binary operator which has both signed and unsigned forms.
1813 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1816 If we widen unsigned operands, we may use a signed wider operation instead
1817 of an unsigned wider operation, since the result would be the same. */
1820 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1821 enum machine_mode mode;
1822 optab uoptab, soptab;
1823 rtx op0, op1, target;
1825 enum optab_methods methods;
1828 optab direct_optab = unsignedp ? uoptab : soptab;
1829 struct optab wide_soptab;
1831 /* Do it without widening, if possible. */
1832 temp = expand_binop (mode, direct_optab, op0, op1, target,
1833 unsignedp, OPTAB_DIRECT);
1834 if (temp || methods == OPTAB_DIRECT)
1837 /* Try widening to a signed int. Make a fake signed optab that
1838 hides any signed insn for direct use. */
1839 wide_soptab = *soptab;
1840 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1841 wide_soptab.handlers[(int) mode].libfunc = 0;
1843 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1844 unsignedp, OPTAB_WIDEN);
1846 /* For unsigned operands, try widening to an unsigned int. */
1847 if (temp == 0 && unsignedp)
1848 temp = expand_binop (mode, uoptab, op0, op1, target,
1849 unsignedp, OPTAB_WIDEN);
1850 if (temp || methods == OPTAB_WIDEN)
1853 /* Use the right width lib call if that exists. */
1854 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1855 if (temp || methods == OPTAB_LIB)
1858 /* Must widen and use a lib call, use either signed or unsigned. */
1859 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1860 unsignedp, methods);
1864 return expand_binop (mode, uoptab, op0, op1, target,
1865 unsignedp, methods);
1869 /* Generate code to perform an operation specified by BINOPTAB
1870 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1871 We assume that the order of the operands for the instruction
1872 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1873 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1875 Either TARG0 or TARG1 may be zero, but what that means is that
1876 the result is not actually wanted. We will generate it into
1877 a dummy pseudo-reg and discard it. They may not both be zero.
1879 Returns 1 if this operation can be performed; 0 if not. */
1882 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1888 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1889 enum mode_class class;
1890 enum machine_mode wider_mode;
1891 rtx entry_last = get_last_insn ();
1894 class = GET_MODE_CLASS (mode);
1896 op0 = protect_from_queue (op0, 0);
1897 op1 = protect_from_queue (op1, 0);
1901 op0 = force_not_mem (op0);
1902 op1 = force_not_mem (op1);
1905 /* If we are inside an appropriately-short loop and one operand is an
1906 expensive constant, force it into a register. */
1907 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1908 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
1909 op0 = force_reg (mode, op0);
1911 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1912 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
1913 op1 = force_reg (mode, op1);
1916 targ0 = protect_from_queue (targ0, 1);
1918 targ0 = gen_reg_rtx (mode);
1920 targ1 = protect_from_queue (targ1, 1);
1922 targ1 = gen_reg_rtx (mode);
1924 /* Record where to go back to if we fail. */
1925 last = get_last_insn ();
1927 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1929 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1930 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1931 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1933 rtx xop0 = op0, xop1 = op1;
1935 /* In case this insn wants input operands in modes different from the
1936 result, convert the operands. */
1937 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1938 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1940 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1941 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1943 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1944 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
1945 xop0 = copy_to_mode_reg (mode0, xop0);
1947 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
1948 xop1 = copy_to_mode_reg (mode1, xop1);
1950 /* We could handle this, but we should always be called with a pseudo
1951 for our targets and all insns should take them as outputs. */
1952 if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
1953 || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
1956 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1963 delete_insns_since (last);
1966 /* It can't be done in this mode. Can we do it in a wider mode? */
1968 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1970 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1971 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1973 if (binoptab->handlers[(int) wider_mode].insn_code
1974 != CODE_FOR_nothing)
1976 register rtx t0 = gen_reg_rtx (wider_mode);
1977 register rtx t1 = gen_reg_rtx (wider_mode);
1979 if (expand_twoval_binop (binoptab,
1980 convert_modes (wider_mode, mode, op0,
1982 convert_modes (wider_mode, mode, op1,
1986 convert_move (targ0, t0, unsignedp);
1987 convert_move (targ1, t1, unsignedp);
1991 delete_insns_since (last);
1996 delete_insns_since (entry_last);
2000 /* Generate code to perform an operation specified by UNOPTAB
2001 on operand OP0, with result having machine-mode MODE.
2003 UNSIGNEDP is for the case where we have to widen the operands
2004 to perform the operation. It says to use zero-extension.
2006 If TARGET is nonzero, the value
2007 is generated there, if it is convenient to do so.
2008 In all cases an rtx is returned for the locus of the value;
2009 this may or may not be TARGET. */
2012 expand_unop (mode, unoptab, op0, target, unsignedp)
2013 enum machine_mode mode;
2019 enum mode_class class;
2020 enum machine_mode wider_mode;
2022 rtx last = get_last_insn ();
2025 class = GET_MODE_CLASS (mode);
2027 op0 = protect_from_queue (op0, 0);
2031 op0 = force_not_mem (op0);
2035 target = protect_from_queue (target, 1);
2037 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2039 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2040 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2046 temp = gen_reg_rtx (mode);
2048 if (GET_MODE (xop0) != VOIDmode
2049 && GET_MODE (xop0) != mode0)
2050 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2052 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2054 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2055 xop0 = copy_to_mode_reg (mode0, xop0);
2057 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
2058 temp = gen_reg_rtx (mode);
2060 pat = GEN_FCN (icode) (temp, xop0);
2063 if (GET_CODE (pat) == SEQUENCE
2064 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2066 delete_insns_since (last);
2067 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2075 delete_insns_since (last);
2078 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2080 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2081 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2082 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2084 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2088 /* For certain operations, we need not actually extend
2089 the narrow operand, as long as we will truncate the
2090 results to the same narrowness. */
2092 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2093 (unoptab == neg_optab
2094 || unoptab == one_cmpl_optab)
2095 && class == MODE_INT);
2097 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2102 if (class != MODE_INT)
2105 target = gen_reg_rtx (mode);
2106 convert_move (target, temp, 0);
2110 return gen_lowpart (mode, temp);
2113 delete_insns_since (last);
2117 /* These can be done a word at a time. */
2118 if (unoptab == one_cmpl_optab
2119 && class == MODE_INT
2120 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2121 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2126 if (target == 0 || target == op0)
2127 target = gen_reg_rtx (mode);
2131 /* Do the actual arithmetic. */
2132 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2134 rtx target_piece = operand_subword (target, i, 1, mode);
2135 rtx x = expand_unop (word_mode, unoptab,
2136 operand_subword_force (op0, i, mode),
2137 target_piece, unsignedp);
2138 if (target_piece != x)
2139 emit_move_insn (target_piece, x);
2142 insns = get_insns ();
2145 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2146 gen_rtx_fmt_e (unoptab->code, mode,
2151 /* Open-code the complex negation operation. */
2152 else if (unoptab->code == NEG
2153 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2159 /* Find the correct mode for the real and imaginary parts */
2160 enum machine_mode submode
2161 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2162 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2165 if (submode == BLKmode)
2169 target = gen_reg_rtx (mode);
2173 target_piece = gen_imagpart (submode, target);
2174 x = expand_unop (submode, unoptab,
2175 gen_imagpart (submode, op0),
2176 target_piece, unsignedp);
2177 if (target_piece != x)
2178 emit_move_insn (target_piece, x);
2180 target_piece = gen_realpart (submode, target);
2181 x = expand_unop (submode, unoptab,
2182 gen_realpart (submode, op0),
2183 target_piece, unsignedp);
2184 if (target_piece != x)
2185 emit_move_insn (target_piece, x);
2190 emit_no_conflict_block (seq, target, op0, 0,
2191 gen_rtx_fmt_e (unoptab->code, mode,
2196 /* Now try a library call in this mode. */
2197 if (unoptab->handlers[(int) mode].libfunc)
2204 /* Pass 1 for NO_QUEUE so we don't lose any increments
2205 if the libcall is cse'd or moved. */
2206 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2207 NULL_RTX, LCT_CONST, mode, 1, op0, mode);
2208 insns = get_insns ();
2211 target = gen_reg_rtx (mode);
2212 emit_libcall_block (insns, target, value,
2213 gen_rtx_fmt_e (unoptab->code, mode, op0));
2218 /* It can't be done in this mode. Can we do it in a wider mode? */
2220 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2222 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2223 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2225 if ((unoptab->handlers[(int) wider_mode].insn_code
2226 != CODE_FOR_nothing)
2227 || unoptab->handlers[(int) wider_mode].libfunc)
2231 /* For certain operations, we need not actually extend
2232 the narrow operand, as long as we will truncate the
2233 results to the same narrowness. */
2235 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2236 (unoptab == neg_optab
2237 || unoptab == one_cmpl_optab)
2238 && class == MODE_INT);
2240 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2245 if (class != MODE_INT)
2248 target = gen_reg_rtx (mode);
2249 convert_move (target, temp, 0);
2253 return gen_lowpart (mode, temp);
2256 delete_insns_since (last);
2261 /* If there is no negate operation, try doing a subtract from zero.
2262 The US Software GOFAST library needs this. */
2263 if (unoptab->code == NEG)
2266 temp = expand_binop (mode,
2267 unoptab == negv_optab ? subv_optab : sub_optab,
2268 CONST0_RTX (mode), op0,
2269 target, unsignedp, OPTAB_LIB_WIDEN);
2277 /* Emit code to compute the absolute value of OP0, with result to
2278 TARGET if convenient. (TARGET may be 0.) The return value says
2279 where the result actually is to be found.
2281 MODE is the mode of the operand; the mode of the result is
2282 different but can be deduced from MODE.
2287 expand_abs (mode, op0, target, result_unsignedp, safe)
2288 enum machine_mode mode;
2291 int result_unsignedp;
2297 result_unsignedp = 1;
2299 /* First try to do it with a special abs instruction. */
2300 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2305 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2306 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2308 rtx last = get_last_insn ();
2310 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2312 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2318 delete_insns_since (last);
2321 /* If this machine has expensive jumps, we can do integer absolute
2322 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2323 where W is the width of MODE. */
2325 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2327 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2328 size_int (GET_MODE_BITSIZE (mode) - 1),
2331 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2334 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2335 temp, extended, target, 0, OPTAB_LIB_WIDEN);
2341 /* If that does not win, use conditional jump and negate. */
2343 /* It is safe to use the target if it is the same
2344 as the source if this is also a pseudo register */
2345 if (op0 == target && GET_CODE (op0) == REG
2346 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2349 op1 = gen_label_rtx ();
2350 if (target == 0 || ! safe
2351 || GET_MODE (target) != mode
2352 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2353 || (GET_CODE (target) == REG
2354 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2355 target = gen_reg_rtx (mode);
2357 emit_move_insn (target, op0);
2360 /* If this mode is an integer too wide to compare properly,
2361 compare word by word. Rely on CSE to optimize constant cases. */
2362 if (GET_MODE_CLASS (mode) == MODE_INT
2363 && ! can_compare_p (GE, mode, ccp_jump))
2364 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2367 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2368 NULL_RTX, 0, NULL_RTX, op1);
2370 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2373 emit_move_insn (target, op0);
2379 /* Emit code to compute the absolute value of OP0, with result to
2380 TARGET if convenient. (TARGET may be 0.) The return value says
2381 where the result actually is to be found.
2383 MODE is the mode of the operand; the mode of the result is
2384 different but can be deduced from MODE.
2386 UNSIGNEDP is relevant for complex integer modes. */
2389 expand_complex_abs (mode, op0, target, unsignedp)
2390 enum machine_mode mode;
2395 enum mode_class class = GET_MODE_CLASS (mode);
2396 enum machine_mode wider_mode;
2398 rtx entry_last = get_last_insn ();
2401 optab this_abs_optab;
2403 /* Find the correct mode for the real and imaginary parts. */
2404 enum machine_mode submode
2405 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2406 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2409 if (submode == BLKmode)
2412 op0 = protect_from_queue (op0, 0);
2416 op0 = force_not_mem (op0);
2419 last = get_last_insn ();
2422 target = protect_from_queue (target, 1);
2424 this_abs_optab = ! unsignedp && flag_trapv
2425 && (GET_MODE_CLASS(mode) == MODE_INT)
2426 ? absv_optab : abs_optab;
2428 if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2430 int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
2431 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2437 temp = gen_reg_rtx (submode);
2439 if (GET_MODE (xop0) != VOIDmode
2440 && GET_MODE (xop0) != mode0)
2441 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2443 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2445 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2446 xop0 = copy_to_mode_reg (mode0, xop0);
2448 if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
2449 temp = gen_reg_rtx (submode);
2451 pat = GEN_FCN (icode) (temp, xop0);
2454 if (GET_CODE (pat) == SEQUENCE
2455 && ! add_equal_note (pat, temp, this_abs_optab->code, xop0,
2458 delete_insns_since (last);
2459 return expand_unop (mode, this_abs_optab, op0, NULL_RTX,
2468 delete_insns_since (last);
2471 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2473 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2474 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2476 if (this_abs_optab->handlers[(int) wider_mode].insn_code
2477 != CODE_FOR_nothing)
2481 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2482 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2486 if (class != MODE_COMPLEX_INT)
2489 target = gen_reg_rtx (submode);
2490 convert_move (target, temp, 0);
2494 return gen_lowpart (submode, temp);
2497 delete_insns_since (last);
2501 /* Open-code the complex absolute-value operation
2502 if we can open-code sqrt. Otherwise it's not worth while. */
2503 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
2506 rtx real, imag, total;
2508 real = gen_realpart (submode, op0);
2509 imag = gen_imagpart (submode, op0);
2511 /* Square both parts. */
2512 real = expand_mult (submode, real, real, NULL_RTX, 0);
2513 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2515 /* Sum the parts. */
2516 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2517 0, OPTAB_LIB_WIDEN);
2519 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2520 target = expand_unop (submode, sqrt_optab, total, target, 0);
2522 delete_insns_since (last);
2527 /* Now try a library call in this mode. */
2528 if (this_abs_optab->handlers[(int) mode].libfunc)
2535 /* Pass 1 for NO_QUEUE so we don't lose any increments
2536 if the libcall is cse'd or moved. */
2537 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2538 NULL_RTX, LCT_CONST, submode, 1, op0, mode);
2539 insns = get_insns ();
2542 target = gen_reg_rtx (submode);
2543 emit_libcall_block (insns, target, value,
2544 gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
2549 /* It can't be done in this mode. Can we do it in a wider mode? */
2551 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2552 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2554 if ((this_abs_optab->handlers[(int) wider_mode].insn_code
2555 != CODE_FOR_nothing)
2556 || this_abs_optab->handlers[(int) wider_mode].libfunc)
2560 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2562 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2566 if (class != MODE_COMPLEX_INT)
2569 target = gen_reg_rtx (submode);
2570 convert_move (target, temp, 0);
2574 return gen_lowpart (submode, temp);
2577 delete_insns_since (last);
2581 delete_insns_since (entry_last);
2585 /* Generate an instruction whose insn-code is INSN_CODE,
2586 with two operands: an output TARGET and an input OP0.
2587 TARGET *must* be nonzero, and the output is always stored there.
2588 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2589 the value that is stored into TARGET. */
2592 emit_unop_insn (icode, target, op0, code)
2599 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2602 temp = target = protect_from_queue (target, 1);
2604 op0 = protect_from_queue (op0, 0);
2606 /* Sign and zero extension from memory is often done specially on
2607 RISC machines, so forcing into a register here can pessimize
2609 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2610 op0 = force_not_mem (op0);
2612 /* Now, if insn does not accept our operands, put them into pseudos. */
2614 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2615 op0 = copy_to_mode_reg (mode0, op0);
2617 if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
2618 || (flag_force_mem && GET_CODE (temp) == MEM))
2619 temp = gen_reg_rtx (GET_MODE (temp));
2621 pat = GEN_FCN (icode) (temp, op0);
2623 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2624 add_equal_note (pat, temp, code, op0, NULL_RTX);
2629 emit_move_insn (target, temp);
2632 /* Emit code to perform a series of operations on a multi-word quantity, one
2635 Such a block is preceded by a CLOBBER of the output, consists of multiple
2636 insns, each setting one word of the output, and followed by a SET copying
2637 the output to itself.
2639 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2640 note indicating that it doesn't conflict with the (also multi-word)
2641 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2644 INSNS is a block of code generated to perform the operation, not including
2645 the CLOBBER and final copy. All insns that compute intermediate values
2646 are first emitted, followed by the block as described above.
2648 TARGET, OP0, and OP1 are the output and inputs of the operations,
2649 respectively. OP1 may be zero for a unary operation.
2651 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2654 If TARGET is not a register, INSNS is simply emitted with no special
2655 processing. Likewise if anything in INSNS is not an INSN or if
2656 there is a libcall block inside INSNS.
2658 The final insn emitted is returned. */
2661 emit_no_conflict_block (insns, target, op0, op1, equiv)
2667 rtx prev, next, first, last, insn;
2669 if (GET_CODE (target) != REG || reload_in_progress)
2670 return emit_insns (insns);
2672 for (insn = insns; insn; insn = NEXT_INSN (insn))
2673 if (GET_CODE (insn) != INSN
2674 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2675 return emit_insns (insns);
2677 /* First emit all insns that do not store into words of the output and remove
2678 these from the list. */
2679 for (insn = insns; insn; insn = next)
2684 next = NEXT_INSN (insn);
2686 if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
2687 || GET_CODE (PATTERN (insn)) == CLOBBER)
2688 set = PATTERN (insn);
2689 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2691 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2692 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2694 set = XVECEXP (PATTERN (insn), 0, i);
2702 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2704 if (PREV_INSN (insn))
2705 NEXT_INSN (PREV_INSN (insn)) = next;
2710 PREV_INSN (next) = PREV_INSN (insn);
2716 prev = get_last_insn ();
2718 /* Now write the CLOBBER of the output, followed by the setting of each
2719 of the words, followed by the final copy. */
2720 if (target != op0 && target != op1)
2721 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2723 for (insn = insns; insn; insn = next)
2725 next = NEXT_INSN (insn);
2728 if (op1 && GET_CODE (op1) == REG)
2729 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2732 if (op0 && GET_CODE (op0) == REG)
2733 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2737 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2738 != CODE_FOR_nothing)
2740 last = emit_move_insn (target, target);
2742 set_unique_reg_note (last, REG_EQUAL, equiv);
2746 last = get_last_insn ();
2748 /* Remove any existing REG_EQUAL note from "last", or else it will
2749 be mistaken for a note referring to the full contents of the
2750 alleged libcall value when found together with the REG_RETVAL
2751 note added below. An existing note can come from an insn
2752 expansion at "last". */
2753 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2757 first = get_insns ();
2759 first = NEXT_INSN (prev);
2761 /* Encapsulate the block so it gets manipulated as a unit. */
2762 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2764 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2769 /* Emit code to make a call to a constant function or a library call.
2771 INSNS is a list containing all insns emitted in the call.
2772 These insns leave the result in RESULT. Our block is to copy RESULT
2773 to TARGET, which is logically equivalent to EQUIV.
2775 We first emit any insns that set a pseudo on the assumption that these are
2776 loading constants into registers; doing so allows them to be safely cse'ed
2777 between blocks. Then we emit all the other insns in the block, followed by
2778 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2779 note with an operand of EQUIV.
2781 Moving assignments to pseudos outside of the block is done to improve
2782 the generated code, but is not required to generate correct code,
2783 hence being unable to move an assignment is not grounds for not making
2784 a libcall block. There are two reasons why it is safe to leave these
2785 insns inside the block: First, we know that these pseudos cannot be
2786 used in generated RTL outside the block since they are created for
2787 temporary purposes within the block. Second, CSE will not record the
2788 values of anything set inside a libcall block, so we know they must
2789 be dead at the end of the block.
2791 Except for the first group of insns (the ones setting pseudos), the
2792 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2795 emit_libcall_block (insns, target, result, equiv)
2801 rtx final_dest = target;
2802 rtx prev, next, first, last, insn;
2804 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
2805 into a MEM later. Protect the libcall block from this change. */
2806 if (! REG_P (target) || REG_USERVAR_P (target))
2807 target = gen_reg_rtx (GET_MODE (target));
2809 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2810 reg note to indicate that this call cannot throw or execute a nonlocal
2811 goto (unless there is already a REG_EH_REGION note, in which case
2812 we update it). Also set the CONST_CALL_P flag. */
2814 for (insn = insns; insn; insn = NEXT_INSN (insn))
2815 if (GET_CODE (insn) == CALL_INSN)
2817 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2819 CONST_CALL_P (insn) = 1;
2821 XEXP (note, 0) = GEN_INT (-1);
2823 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2827 /* First emit all insns that set pseudos. Remove them from the list as
2828 we go. Avoid insns that set pseudos which were referenced in previous
2829 insns. These can be generated by move_by_pieces, for example,
2830 to update an address. Similarly, avoid insns that reference things
2831 set in previous insns. */
2833 for (insn = insns; insn; insn = next)
2835 rtx set = single_set (insn);
2837 next = NEXT_INSN (insn);
2839 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2840 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2842 || ((! INSN_P(insns)
2843 || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
2844 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2845 && ! modified_in_p (SET_SRC (set), insns)
2846 && ! modified_between_p (SET_SRC (set), insns, insn))))
2848 if (PREV_INSN (insn))
2849 NEXT_INSN (PREV_INSN (insn)) = next;
2854 PREV_INSN (next) = PREV_INSN (insn);
2860 prev = get_last_insn ();
2862 /* Write the remaining insns followed by the final copy. */
2864 for (insn = insns; insn; insn = next)
2866 next = NEXT_INSN (insn);
2871 last = emit_move_insn (target, result);
2872 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2873 != CODE_FOR_nothing)
2874 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2877 /* Remove any existing REG_EQUAL note from "last", or else it will
2878 be mistaken for a note referring to the full contents of the
2879 libcall value when found together with the REG_RETVAL note added
2880 below. An existing note can come from an insn expansion at
2882 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2885 if (final_dest != target)
2886 emit_move_insn (final_dest, target);
2889 first = get_insns ();
2891 first = NEXT_INSN (prev);
2893 /* Encapsulate the block so it gets manipulated as a unit. */
2894 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2896 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2899 /* Generate code to store zero in X. */
2905 emit_move_insn (x, const0_rtx);
2908 /* Generate code to store 1 in X
2909 assuming it contains zero beforehand. */
2912 emit_0_to_1_insn (x)
2915 emit_move_insn (x, const1_rtx);
2918 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
2919 PURPOSE describes how this comparison will be used. CODE is the rtx
2920 comparison code we will be using.
2922 ??? Actually, CODE is slightly weaker than that. A target is still
2923 required to implement all of the normal bcc operations, but not
2924 required to implement all (or any) of the unordered bcc operations. */
2927 can_compare_p (code, mode, purpose)
2929 enum machine_mode mode;
2930 enum can_compare_purpose purpose;
2934 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2936 if (purpose == ccp_jump)
2937 return bcc_gen_fctn[(int)code] != NULL;
2938 else if (purpose == ccp_store_flag)
2939 return setcc_gen_code[(int)code] != CODE_FOR_nothing;
2941 /* There's only one cmov entry point, and it's allowed to fail. */
2944 if (purpose == ccp_jump
2945 && cbranch_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2947 if (purpose == ccp_cmov
2948 && cmov_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2950 if (purpose == ccp_store_flag
2951 && cstore_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2954 mode = GET_MODE_WIDER_MODE (mode);
2956 while (mode != VOIDmode);
2961 /* This function is called when we are going to emit a compare instruction that
2962 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
2964 *PMODE is the mode of the inputs (in case they are const_int).
2965 *PUNSIGNEDP nonzero says that the operands are unsigned;
2966 this matters if they need to be widened.
2968 If they have mode BLKmode, then SIZE specifies the size of both operands,
2969 and ALIGN specifies the known shared alignment of the operands.
2971 This function performs all the setup necessary so that the caller only has
2972 to emit a single comparison insn. This setup can involve doing a BLKmode
2973 comparison or emitting a library call to perform the comparison if no insn
2974 is available to handle it.
2975 The values which are passed in through pointers can be modified; the caller
2976 should perform the comparison on the modified values. */
2979 prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
2982 enum rtx_code *pcomparison;
2984 enum machine_mode *pmode;
2986 int align ATTRIBUTE_UNUSED;
2987 enum can_compare_purpose purpose;
2989 enum machine_mode mode = *pmode;
2990 rtx x = *px, y = *py;
2991 int unsignedp = *punsignedp;
2992 enum mode_class class;
2993 rtx opalign ATTRIBUTE_UNUSED = GEN_INT (align / BITS_PER_UNIT);;
2995 class = GET_MODE_CLASS (mode);
2997 /* They could both be VOIDmode if both args are immediate constants,
2998 but we should fold that at an earlier stage.
2999 With no special code here, this will call abort,
3000 reminding the programmer to implement such folding. */
3002 if (mode != BLKmode && flag_force_mem)
3004 x = force_not_mem (x);
3005 y = force_not_mem (y);
3008 /* If we are inside an appropriately-short loop and one operand is an
3009 expensive constant, force it into a register. */
3010 if (CONSTANT_P (x) && preserve_subexpressions_p ()
3011 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3012 x = force_reg (mode, x);
3014 if (CONSTANT_P (y) && preserve_subexpressions_p ()
3015 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3016 y = force_reg (mode, y);
3019 /* Abort if we have a non-canonical comparison. The RTL documentation
3020 states that canonical comparisons are required only for targets which
3022 if (CONSTANT_P (x) && ! CONSTANT_P (y))
3026 /* Don't let both operands fail to indicate the mode. */
3027 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3028 x = force_reg (mode, x);
3030 /* Handle all BLKmode compares. */
3032 if (mode == BLKmode)
3035 enum machine_mode result_mode;
3038 x = protect_from_queue (x, 0);
3039 y = protect_from_queue (y, 0);
3043 #ifdef HAVE_cmpstrqi
3045 && GET_CODE (size) == CONST_INT
3046 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3048 result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
3049 result = gen_reg_rtx (result_mode);
3050 emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
3054 #ifdef HAVE_cmpstrhi
3056 && GET_CODE (size) == CONST_INT
3057 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3059 result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
3060 result = gen_reg_rtx (result_mode);
3061 emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
3065 #ifdef HAVE_cmpstrsi
3068 result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3069 result = gen_reg_rtx (result_mode);
3070 size = protect_from_queue (size, 0);
3071 emit_insn (gen_cmpstrsi (result, x, y,
3072 convert_to_mode (SImode, size, 1),
3078 #ifdef TARGET_MEM_FUNCTIONS
3079 emit_library_call (memcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3080 TYPE_MODE (integer_type_node), 3,
3081 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3082 convert_to_mode (TYPE_MODE (sizetype), size,
3083 TREE_UNSIGNED (sizetype)),
3084 TYPE_MODE (sizetype));
3086 emit_library_call (bcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3087 TYPE_MODE (integer_type_node), 3,
3088 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3089 convert_to_mode (TYPE_MODE (integer_type_node),
3091 TREE_UNSIGNED (integer_type_node)),
3092 TYPE_MODE (integer_type_node));
3095 /* Immediately move the result of the libcall into a pseudo
3096 register so reload doesn't clobber the value if it needs
3097 the return register for a spill reg. */
3098 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3099 result_mode = TYPE_MODE (integer_type_node);
3100 emit_move_insn (result,
3101 hard_libcall_value (result_mode));
3105 *pmode = result_mode;
3111 if (can_compare_p (*pcomparison, mode, purpose))
3114 /* Handle a lib call just for the mode we are using. */
3116 if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3118 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3121 /* If we want unsigned, and this mode has a distinct unsigned
3122 comparison routine, use that. */
3123 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3124 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3126 emit_library_call (libfunc, 1,
3127 word_mode, 2, x, mode, y, mode);
3129 /* Immediately move the result of the libcall into a pseudo
3130 register so reload doesn't clobber the value if it needs
3131 the return register for a spill reg. */
3132 result = gen_reg_rtx (word_mode);
3133 emit_move_insn (result, hard_libcall_value (word_mode));
3135 /* Integer comparison returns a result that must be compared against 1,
3136 so that even if we do an unsigned compare afterward,
3137 there is still a value that can represent the result "less than". */
3144 if (class == MODE_FLOAT)
3145 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3151 /* Before emitting an insn with code ICODE, make sure that X, which is going
3152 to be used for operand OPNUM of the insn, is converted from mode MODE to
3153 WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
3154 that it is accepted by the operand predicate. Return the new value. */
3157 prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
3161 enum machine_mode mode, wider_mode;
3164 x = protect_from_queue (x, 0);
3166 if (mode != wider_mode)
3167 x = convert_modes (wider_mode, mode, x, unsignedp);
3169 if (! (*insn_data[icode].operand[opnum].predicate)
3170 (x, insn_data[icode].operand[opnum].mode))
3171 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3175 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3176 we can do the comparison.
3177 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3178 be NULL_RTX which indicates that only a comparison is to be generated. */
3181 emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
3183 enum machine_mode mode;
3184 enum rtx_code comparison;
3188 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3189 enum mode_class class = GET_MODE_CLASS (mode);
3190 enum machine_mode wider_mode = mode;
3192 /* Try combined insns first. */
3195 enum insn_code icode;
3196 PUT_MODE (test, wider_mode);
3200 icode = cbranch_optab->handlers[(int)wider_mode].insn_code;
3202 if (icode != CODE_FOR_nothing
3203 && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3205 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3206 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3207 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3212 /* Handle some compares against zero. */
3213 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3214 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3216 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3217 emit_insn (GEN_FCN (icode) (x));
3219 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3223 /* Handle compares for which there is a directly suitable insn. */
3225 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3226 if (icode != CODE_FOR_nothing)
3228 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3229 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3230 emit_insn (GEN_FCN (icode) (x, y));
3232 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3236 if (class != MODE_INT && class != MODE_FLOAT
3237 && class != MODE_COMPLEX_FLOAT)
3240 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3241 } while (wider_mode != VOIDmode);
3246 /* Generate code to compare X with Y so that the condition codes are
3247 set and to jump to LABEL if the condition is true. If X is a
3248 constant and Y is not a constant, then the comparison is swapped to
3249 ensure that the comparison RTL has the canonical form.
3251 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3252 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3253 the proper branch condition code.
3255 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3256 and ALIGN specifies the known shared alignment of X and Y.
3258 MODE is the mode of the inputs (in case they are const_int).
3260 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3261 be passed unchanged to emit_cmp_insn, then potentially converted into an
3262 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3265 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
3267 enum rtx_code comparison;
3269 enum machine_mode mode;
3277 if ((CONSTANT_P (x) && ! CONSTANT_P (y))
3278 || (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT))
3280 /* Swap operands and condition to ensure canonical RTL. */
3283 comparison = swap_condition (comparison);
3292 /* If OP0 is still a constant, then both X and Y must be constants. Force
3293 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3295 if (CONSTANT_P (op0))
3296 op0 = force_reg (mode, op0);
3301 comparison = unsigned_condition (comparison);
3302 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp, align,
3304 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3307 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3310 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
3312 enum rtx_code comparison;
3314 enum machine_mode mode;
3318 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, 0);
3321 /* Emit a library call comparison between floating point X and Y.
3322 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3325 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
3327 enum rtx_code *pcomparison;
3328 enum machine_mode *pmode;
3331 enum rtx_code comparison = *pcomparison;
3332 rtx x = *px = protect_from_queue (*px, 0);
3333 rtx y = *py = protect_from_queue (*py, 0);
3334 enum machine_mode mode = GET_MODE (x);
3342 libfunc = eqhf2_libfunc;
3346 libfunc = nehf2_libfunc;
3350 libfunc = gthf2_libfunc;
3354 libfunc = gehf2_libfunc;
3358 libfunc = lthf2_libfunc;
3362 libfunc = lehf2_libfunc;
3366 libfunc = unordhf2_libfunc;
3372 else if (mode == SFmode)
3376 libfunc = eqsf2_libfunc;
3380 libfunc = nesf2_libfunc;
3384 libfunc = gtsf2_libfunc;
3388 libfunc = gesf2_libfunc;
3392 libfunc = ltsf2_libfunc;
3396 libfunc = lesf2_libfunc;
3400 libfunc = unordsf2_libfunc;
3406 else if (mode == DFmode)
3410 libfunc = eqdf2_libfunc;
3414 libfunc = nedf2_libfunc;
3418 libfunc = gtdf2_libfunc;
3422 libfunc = gedf2_libfunc;
3426 libfunc = ltdf2_libfunc;
3430 libfunc = ledf2_libfunc;
3434 libfunc = unorddf2_libfunc;
3440 else if (mode == XFmode)
3444 libfunc = eqxf2_libfunc;
3448 libfunc = nexf2_libfunc;
3452 libfunc = gtxf2_libfunc;
3456 libfunc = gexf2_libfunc;
3460 libfunc = ltxf2_libfunc;
3464 libfunc = lexf2_libfunc;
3468 libfunc = unordxf2_libfunc;
3474 else if (mode == TFmode)
3478 libfunc = eqtf2_libfunc;
3482 libfunc = netf2_libfunc;
3486 libfunc = gttf2_libfunc;
3490 libfunc = getf2_libfunc;
3494 libfunc = lttf2_libfunc;
3498 libfunc = letf2_libfunc;
3502 libfunc = unordtf2_libfunc;
3510 enum machine_mode wider_mode;
3512 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3513 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3515 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3516 != CODE_FOR_nothing)
3517 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3519 x = protect_from_queue (x, 0);
3520 y = protect_from_queue (y, 0);
3521 *px = convert_to_mode (wider_mode, x, 0);
3522 *py = convert_to_mode (wider_mode, y, 0);
3523 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3533 emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode, y,
3536 /* Immediately move the result of the libcall into a pseudo
3537 register so reload doesn't clobber the value if it needs
3538 the return register for a spill reg. */
3539 result = gen_reg_rtx (word_mode);
3540 emit_move_insn (result, hard_libcall_value (word_mode));
3544 if (comparison == UNORDERED)
3546 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
3547 else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3553 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3556 emit_indirect_jump (loc)
3559 if (! ((*insn_data[(int)CODE_FOR_indirect_jump].operand[0].predicate)
3561 loc = copy_to_mode_reg (Pmode, loc);
3563 emit_jump_insn (gen_indirect_jump (loc));
3567 #ifdef HAVE_conditional_move
3569 /* Emit a conditional move instruction if the machine supports one for that
3570 condition and machine mode.
3572 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3573 the mode to use should they be constants. If it is VOIDmode, they cannot
3576 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3577 should be stored there. MODE is the mode to use should they be constants.
3578 If it is VOIDmode, they cannot both be constants.
3580 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3581 is not supported. */
3584 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3589 enum machine_mode cmode;
3591 enum machine_mode mode;
3594 rtx tem, subtarget, comparison, insn;
3595 enum insn_code icode;
3597 /* If one operand is constant, make it the second one. Only do this
3598 if the other operand is not constant as well. */
3600 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3601 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3606 code = swap_condition (code);
3609 /* get_condition will prefer to generate LT and GT even if the old
3610 comparison was against zero, so undo that canonicalization here since
3611 comparisons against zero are cheaper. */
3612 if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
3613 code = LE, op1 = const0_rtx;
3614 else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
3615 code = GE, op1 = const0_rtx;
3617 if (cmode == VOIDmode)
3618 cmode = GET_MODE (op0);
3620 if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3621 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3622 && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3623 || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
3624 || flag_unsafe_math_optimizations))
3629 code = reverse_condition (code);
3632 if (mode == VOIDmode)
3633 mode = GET_MODE (op2);
3635 icode = movcc_gen_code[mode];
3637 if (icode == CODE_FOR_nothing)
3642 op2 = force_not_mem (op2);
3643 op3 = force_not_mem (op3);
3647 target = protect_from_queue (target, 1);
3649 target = gen_reg_rtx (mode);
3655 op2 = protect_from_queue (op2, 0);
3656 op3 = protect_from_queue (op3, 0);
3658 /* If the insn doesn't accept these operands, put them in pseudos. */
3660 if (! (*insn_data[icode].operand[0].predicate)
3661 (subtarget, insn_data[icode].operand[0].mode))
3662 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
3664 if (! (*insn_data[icode].operand[2].predicate)
3665 (op2, insn_data[icode].operand[2].mode))
3666 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
3668 if (! (*insn_data[icode].operand[3].predicate)
3669 (op3, insn_data[icode].operand[3].mode))
3670 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
3672 /* Everything should now be in the suitable form, so emit the compare insn
3673 and then the conditional move. */
3676 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3678 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3679 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3680 return NULL and let the caller figure out how best to deal with this
3682 if (GET_CODE (comparison) != code)
3685 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3687 /* If that failed, then give up. */
3693 if (subtarget != target)
3694 convert_move (target, subtarget, 0);
3699 /* Return non-zero if a conditional move of mode MODE is supported.
3701 This function is for combine so it can tell whether an insn that looks
3702 like a conditional move is actually supported by the hardware. If we
3703 guess wrong we lose a bit on optimization, but that's it. */
3704 /* ??? sparc64 supports conditionally moving integers values based on fp
3705 comparisons, and vice versa. How do we handle them? */
3708 can_conditionally_move_p (mode)
3709 enum machine_mode mode;
3711 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3717 #endif /* HAVE_conditional_move */
3719 /* These three functions generate an insn body and return it
3720 rather than emitting the insn.
3722 They do not protect from queued increments,
3723 because they may be used 1) in protect_from_queue itself
3724 and 2) in other passes where there is no queue. */
3726 /* Generate and return an insn body to add Y to X. */
3729 gen_add2_insn (x, y)
3732 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3734 if (! ((*insn_data[icode].operand[0].predicate)
3735 (x, insn_data[icode].operand[0].mode))
3736 || ! ((*insn_data[icode].operand[1].predicate)
3737 (x, insn_data[icode].operand[1].mode))
3738 || ! ((*insn_data[icode].operand[2].predicate)
3739 (y, insn_data[icode].operand[2].mode)))
3742 return (GEN_FCN (icode) (x, x, y));
3746 have_add2_insn (mode)
3747 enum machine_mode mode;
3749 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3752 /* Generate and return an insn body to subtract Y from X. */
3755 gen_sub2_insn (x, y)
3758 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3760 if (! ((*insn_data[icode].operand[0].predicate)
3761 (x, insn_data[icode].operand[0].mode))
3762 || ! ((*insn_data[icode].operand[1].predicate)
3763 (x, insn_data[icode].operand[1].mode))
3764 || ! ((*insn_data[icode].operand[2].predicate)
3765 (y, insn_data[icode].operand[2].mode)))
3768 return (GEN_FCN (icode) (x, x, y));
3772 have_sub2_insn (mode)
3773 enum machine_mode mode;
3775 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3778 /* Generate the body of an instruction to copy Y into X.
3779 It may be a SEQUENCE, if one insn isn't enough. */
3782 gen_move_insn (x, y)
3785 register enum machine_mode mode = GET_MODE (x);
3786 enum insn_code insn_code;
3789 if (mode == VOIDmode)
3790 mode = GET_MODE (y);
3792 insn_code = mov_optab->handlers[(int) mode].insn_code;
3794 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3795 find a mode to do it in. If we have a movcc, use it. Otherwise,
3796 find the MODE_INT mode of the same width. */
3798 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3800 enum machine_mode tmode = VOIDmode;
3804 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3807 for (tmode = QImode; tmode != VOIDmode;
3808 tmode = GET_MODE_WIDER_MODE (tmode))
3809 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3812 if (tmode == VOIDmode)
3815 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3816 may call change_address which is not appropriate if we were
3817 called when a reload was in progress. We don't have to worry
3818 about changing the address since the size in bytes is supposed to
3819 be the same. Copy the MEM to change the mode and move any
3820 substitutions from the old MEM to the new one. */
3822 if (reload_in_progress)
3824 x = gen_lowpart_common (tmode, x1);
3825 if (x == 0 && GET_CODE (x1) == MEM)
3827 x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3828 MEM_COPY_ATTRIBUTES (x, x1);
3829 copy_replacements (x1, x);
3832 y = gen_lowpart_common (tmode, y1);
3833 if (y == 0 && GET_CODE (y1) == MEM)
3835 y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3836 MEM_COPY_ATTRIBUTES (y, y1);
3837 copy_replacements (y1, y);
3842 x = gen_lowpart (tmode, x);
3843 y = gen_lowpart (tmode, y);
3846 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3847 return (GEN_FCN (insn_code) (x, y));
3851 emit_move_insn_1 (x, y);
3852 seq = gen_sequence ();
3857 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3858 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3859 no such operation exists, CODE_FOR_nothing will be returned. */
3862 can_extend_p (to_mode, from_mode, unsignedp)
3863 enum machine_mode to_mode, from_mode;
3866 return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
3869 /* Generate the body of an insn to extend Y (with mode MFROM)
3870 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3873 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3875 enum machine_mode mto, mfrom;
3878 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
3881 /* can_fix_p and can_float_p say whether the target machine
3882 can directly convert a given fixed point type to
3883 a given floating point type, or vice versa.
3884 The returned value is the CODE_FOR_... value to use,
3885 or CODE_FOR_nothing if these modes cannot be directly converted.
3887 *TRUNCP_PTR is set to 1 if it is necessary to output
3888 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3890 static enum insn_code
3891 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3892 enum machine_mode fltmode, fixmode;
3897 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
3898 != CODE_FOR_nothing)
3899 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
3901 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3904 return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
3906 return CODE_FOR_nothing;
3909 static enum insn_code
3910 can_float_p (fltmode, fixmode, unsignedp)
3911 enum machine_mode fixmode, fltmode;
3914 return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
3917 /* Generate code to convert FROM to floating point
3918 and store in TO. FROM must be fixed point and not VOIDmode.
3919 UNSIGNEDP nonzero means regard FROM as unsigned.
3920 Normally this is done by correcting the final value
3921 if it is negative. */
3924 expand_float (to, from, unsignedp)
3928 enum insn_code icode;
3929 register rtx target = to;
3930 enum machine_mode fmode, imode;
3932 /* Crash now, because we won't be able to decide which mode to use. */
3933 if (GET_MODE (from) == VOIDmode)
3936 /* Look for an insn to do the conversion. Do it in the specified
3937 modes if possible; otherwise convert either input, output or both to
3938 wider mode. If the integer mode is wider than the mode of FROM,
3939 we can do the conversion signed even if the input is unsigned. */
3941 for (imode = GET_MODE (from); imode != VOIDmode;
3942 imode = GET_MODE_WIDER_MODE (imode))
3943 for (fmode = GET_MODE (to); fmode != VOIDmode;
3944 fmode = GET_MODE_WIDER_MODE (fmode))
3946 int doing_unsigned = unsignedp;
3948 if (fmode != GET_MODE (to)
3949 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
3952 icode = can_float_p (fmode, imode, unsignedp);
3953 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3954 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3956 if (icode != CODE_FOR_nothing)
3958 to = protect_from_queue (to, 1);
3959 from = protect_from_queue (from, 0);
3961 if (imode != GET_MODE (from))
3962 from = convert_to_mode (imode, from, unsignedp);
3964 if (fmode != GET_MODE (to))
3965 target = gen_reg_rtx (fmode);
3967 emit_unop_insn (icode, target, from,
3968 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3971 convert_move (to, target, 0);
3976 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3978 /* Unsigned integer, and no way to convert directly.
3979 Convert as signed, then conditionally adjust the result. */
3982 rtx label = gen_label_rtx ();
3984 REAL_VALUE_TYPE offset;
3988 to = protect_from_queue (to, 1);
3989 from = protect_from_queue (from, 0);
3992 from = force_not_mem (from);
3994 /* Look for a usable floating mode FMODE wider than the source and at
3995 least as wide as the target. Using FMODE will avoid rounding woes
3996 with unsigned values greater than the signed maximum value. */
3998 for (fmode = GET_MODE (to); fmode != VOIDmode;
3999 fmode = GET_MODE_WIDER_MODE (fmode))
4000 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4001 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4004 if (fmode == VOIDmode)
4006 /* There is no such mode. Pretend the target is wide enough. */
4007 fmode = GET_MODE (to);
4009 /* Avoid double-rounding when TO is narrower than FROM. */
4010 if ((significand_size (fmode) + 1)
4011 < GET_MODE_BITSIZE (GET_MODE (from)))
4014 rtx neglabel = gen_label_rtx ();
4016 /* Don't use TARGET if it isn't a register, is a hard register,
4017 or is the wrong mode. */
4018 if (GET_CODE (target) != REG
4019 || REGNO (target) < FIRST_PSEUDO_REGISTER
4020 || GET_MODE (target) != fmode)
4021 target = gen_reg_rtx (fmode);
4023 imode = GET_MODE (from);
4024 do_pending_stack_adjust ();
4026 /* Test whether the sign bit is set. */
4027 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4030 /* The sign bit is not set. Convert as signed. */
4031 expand_float (target, from, 0);
4032 emit_jump_insn (gen_jump (label));
4035 /* The sign bit is set.
4036 Convert to a usable (positive signed) value by shifting right
4037 one bit, while remembering if a nonzero bit was shifted
4038 out; i.e., compute (from & 1) | (from >> 1). */
4040 emit_label (neglabel);
4041 temp = expand_binop (imode, and_optab, from, const1_rtx,
4042 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4043 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4045 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4047 expand_float (target, temp, 0);
4049 /* Multiply by 2 to undo the shift above. */
4050 temp = expand_binop (fmode, add_optab, target, target,
4051 target, 0, OPTAB_LIB_WIDEN);
4053 emit_move_insn (target, temp);
4055 do_pending_stack_adjust ();
4061 /* If we are about to do some arithmetic to correct for an
4062 unsigned operand, do it in a pseudo-register. */
4064 if (GET_MODE (to) != fmode
4065 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4066 target = gen_reg_rtx (fmode);
4068 /* Convert as signed integer to floating. */
4069 expand_float (target, from, 0);
4071 /* If FROM is negative (and therefore TO is negative),
4072 correct its value by 2**bitwidth. */
4074 do_pending_stack_adjust ();
4075 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4078 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4079 Rather than setting up a dconst_dot_5, let's hope SCO
4081 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4082 temp = expand_binop (fmode, add_optab, target,
4083 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4084 target, 0, OPTAB_LIB_WIDEN);
4086 emit_move_insn (target, temp);
4088 do_pending_stack_adjust ();
4094 /* No hardware instruction available; call a library routine to convert from
4095 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4101 to = protect_from_queue (to, 1);
4102 from = protect_from_queue (from, 0);
4104 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4105 from = convert_to_mode (SImode, from, unsignedp);
4108 from = force_not_mem (from);
4110 if (GET_MODE (to) == SFmode)
4112 if (GET_MODE (from) == SImode)
4113 libfcn = floatsisf_libfunc;
4114 else if (GET_MODE (from) == DImode)
4115 libfcn = floatdisf_libfunc;
4116 else if (GET_MODE (from) == TImode)
4117 libfcn = floattisf_libfunc;
4121 else if (GET_MODE (to) == DFmode)
4123 if (GET_MODE (from) == SImode)
4124 libfcn = floatsidf_libfunc;
4125 else if (GET_MODE (from) == DImode)
4126 libfcn = floatdidf_libfunc;
4127 else if (GET_MODE (from) == TImode)
4128 libfcn = floattidf_libfunc;
4132 else if (GET_MODE (to) == XFmode)
4134 if (GET_MODE (from) == SImode)
4135 libfcn = floatsixf_libfunc;
4136 else if (GET_MODE (from) == DImode)
4137 libfcn = floatdixf_libfunc;
4138 else if (GET_MODE (from) == TImode)
4139 libfcn = floattixf_libfunc;
4143 else if (GET_MODE (to) == TFmode)
4145 if (GET_MODE (from) == SImode)
4146 libfcn = floatsitf_libfunc;
4147 else if (GET_MODE (from) == DImode)
4148 libfcn = floatditf_libfunc;
4149 else if (GET_MODE (from) == TImode)
4150 libfcn = floattitf_libfunc;
4159 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4160 GET_MODE (to), 1, from,
4162 insns = get_insns ();
4165 emit_libcall_block (insns, target, value,
4166 gen_rtx_FLOAT (GET_MODE (to), from));
4171 /* Copy result to requested destination
4172 if we have been computing in a temp location. */
4176 if (GET_MODE (target) == GET_MODE (to))
4177 emit_move_insn (to, target);
4179 convert_move (to, target, 0);
4183 /* expand_fix: generate code to convert FROM to fixed point
4184 and store in TO. FROM must be floating point. */
4190 rtx temp = gen_reg_rtx (GET_MODE (x));
4191 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4195 expand_fix (to, from, unsignedp)
4196 register rtx to, from;
4199 enum insn_code icode;
4200 register rtx target = to;
4201 enum machine_mode fmode, imode;
4205 /* We first try to find a pair of modes, one real and one integer, at
4206 least as wide as FROM and TO, respectively, in which we can open-code
4207 this conversion. If the integer mode is wider than the mode of TO,
4208 we can do the conversion either signed or unsigned. */
4210 for (imode = GET_MODE (to); imode != VOIDmode;
4211 imode = GET_MODE_WIDER_MODE (imode))
4212 for (fmode = GET_MODE (from); fmode != VOIDmode;
4213 fmode = GET_MODE_WIDER_MODE (fmode))
4215 int doing_unsigned = unsignedp;
4217 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4218 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4219 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4221 if (icode != CODE_FOR_nothing)
4223 to = protect_from_queue (to, 1);
4224 from = protect_from_queue (from, 0);
4226 if (fmode != GET_MODE (from))
4227 from = convert_to_mode (fmode, from, 0);
4230 from = ftruncify (from);
4232 if (imode != GET_MODE (to))
4233 target = gen_reg_rtx (imode);
4235 emit_unop_insn (icode, target, from,
4236 doing_unsigned ? UNSIGNED_FIX : FIX);
4238 convert_move (to, target, unsignedp);
4243 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4244 /* For an unsigned conversion, there is one more way to do it.
4245 If we have a signed conversion, we generate code that compares
4246 the real value to the largest representable positive number. If if
4247 is smaller, the conversion is done normally. Otherwise, subtract
4248 one plus the highest signed number, convert, and add it back.
4250 We only need to check all real modes, since we know we didn't find
4251 anything with a wider integer mode. */
4253 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4254 for (fmode = GET_MODE (from); fmode != VOIDmode;
4255 fmode = GET_MODE_WIDER_MODE (fmode))
4256 /* Make sure we won't lose significant bits doing this. */
4257 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4258 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4262 REAL_VALUE_TYPE offset;
4263 rtx limit, lab1, lab2, insn;
4265 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4266 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4267 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4268 lab1 = gen_label_rtx ();
4269 lab2 = gen_label_rtx ();
4272 to = protect_from_queue (to, 1);
4273 from = protect_from_queue (from, 0);
4276 from = force_not_mem (from);
4278 if (fmode != GET_MODE (from))
4279 from = convert_to_mode (fmode, from, 0);
4281 /* See if we need to do the subtraction. */
4282 do_pending_stack_adjust ();
4283 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4286 /* If not, do the signed "fix" and branch around fixup code. */
4287 expand_fix (to, from, 0);
4288 emit_jump_insn (gen_jump (lab2));
4291 /* Otherwise, subtract 2**(N-1), convert to signed number,
4292 then add 2**(N-1). Do the addition using XOR since this
4293 will often generate better code. */
4295 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4296 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4297 expand_fix (to, target, 0);
4298 target = expand_binop (GET_MODE (to), xor_optab, to,
4299 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
4300 to, 1, OPTAB_LIB_WIDEN);
4303 emit_move_insn (to, target);
4307 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4308 != CODE_FOR_nothing)
4310 /* Make a place for a REG_NOTE and add it. */
4311 insn = emit_move_insn (to, to);
4312 set_unique_reg_note (insn,
4314 gen_rtx_fmt_e (UNSIGNED_FIX,
4323 /* We can't do it with an insn, so use a library call. But first ensure
4324 that the mode of TO is at least as wide as SImode, since those are the
4325 only library calls we know about. */
4327 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4329 target = gen_reg_rtx (SImode);
4331 expand_fix (target, from, unsignedp);
4333 else if (GET_MODE (from) == SFmode)
4335 if (GET_MODE (to) == SImode)
4336 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4337 else if (GET_MODE (to) == DImode)
4338 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4339 else if (GET_MODE (to) == TImode)
4340 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4344 else if (GET_MODE (from) == DFmode)
4346 if (GET_MODE (to) == SImode)
4347 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4348 else if (GET_MODE (to) == DImode)
4349 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4350 else if (GET_MODE (to) == TImode)
4351 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4355 else if (GET_MODE (from) == XFmode)
4357 if (GET_MODE (to) == SImode)
4358 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4359 else if (GET_MODE (to) == DImode)
4360 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4361 else if (GET_MODE (to) == TImode)
4362 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4366 else if (GET_MODE (from) == TFmode)
4368 if (GET_MODE (to) == SImode)
4369 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4370 else if (GET_MODE (to) == DImode)
4371 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4372 else if (GET_MODE (to) == TImode)
4373 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4385 to = protect_from_queue (to, 1);
4386 from = protect_from_queue (from, 0);
4389 from = force_not_mem (from);
4393 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4394 GET_MODE (to), 1, from,
4396 insns = get_insns ();
4399 emit_libcall_block (insns, target, value,
4400 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4401 GET_MODE (to), from));
4406 if (GET_MODE (to) == GET_MODE (target))
4407 emit_move_insn (to, target);
4409 convert_move (to, target, 0);
4418 optab op = (optab) xmalloc (sizeof (struct optab));
4420 for (i = 0; i < NUM_MACHINE_MODES; i++)
4422 op->handlers[i].insn_code = CODE_FOR_nothing;
4423 op->handlers[i].libfunc = 0;
4426 if (code != UNKNOWN)
4427 code_to_optab[(int) code] = op;
4432 /* Initialize the libfunc fields of an entire group of entries in some
4433 optab. Each entry is set equal to a string consisting of a leading
4434 pair of underscores followed by a generic operation name followed by
4435 a mode name (downshifted to lower case) followed by a single character
4436 representing the number of operands for the given operation (which is
4437 usually one of the characters '2', '3', or '4').
4439 OPTABLE is the table in which libfunc fields are to be initialized.
4440 FIRST_MODE is the first machine mode index in the given optab to
4442 LAST_MODE is the last machine mode index in the given optab to
4444 OPNAME is the generic (string) name of the operation.
4445 SUFFIX is the character which specifies the number of operands for
4446 the given generic operation.
4450 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4451 register optab optable;
4452 register int first_mode;
4453 register int last_mode;
4454 register const char *opname;
4455 register int suffix;
4458 register unsigned opname_len = strlen (opname);
4460 for (mode = first_mode; (int) mode <= (int) last_mode;
4461 mode = (enum machine_mode) ((int) mode + 1))
4463 register const char *mname = GET_MODE_NAME(mode);
4464 register unsigned mname_len = strlen (mname);
4465 register char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
4467 register const char *q;
4472 for (q = opname; *q; )
4474 for (q = mname; *q; q++)
4475 *p++ = TOLOWER (*q);
4479 optable->handlers[(int) mode].libfunc
4480 = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
4485 /* Initialize the libfunc fields of an entire group of entries in some
4486 optab which correspond to all integer mode operations. The parameters
4487 have the same meaning as similarly named ones for the `init_libfuncs'
4488 routine. (See above). */
4491 init_integral_libfuncs (optable, opname, suffix)
4492 register optab optable;
4493 register const char *opname;
4494 register int suffix;
4496 init_libfuncs (optable, SImode, TImode, opname, suffix);
4499 /* Initialize the libfunc fields of an entire group of entries in some
4500 optab which correspond to all real mode operations. The parameters
4501 have the same meaning as similarly named ones for the `init_libfuncs'
4502 routine. (See above). */
4505 init_floating_libfuncs (optable, opname, suffix)
4506 register optab optable;
4507 register const char *opname;
4508 register int suffix;
4510 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4514 init_one_libfunc (name)
4515 register const char *name;
4517 name = ggc_strdup (name);
4519 return gen_rtx_SYMBOL_REF (Pmode, name);
4522 /* Mark ARG (which is really an OPTAB *) for GC. */
4528 optab o = *(optab *) arg;
4531 for (i = 0; i < NUM_MACHINE_MODES; ++i)
4532 ggc_mark_rtx (o->handlers[i].libfunc);
4535 /* Call this once to initialize the contents of the optabs
4536 appropriately for the current target machine. */
4541 unsigned int i, j, k;
4543 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4545 for (i = 0; i < ARRAY_SIZE (fixtab); i++)
4546 for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
4547 for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
4548 fixtab[i][j][k] = CODE_FOR_nothing;
4550 for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
4551 for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
4552 for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
4553 fixtrunctab[i][j][k] = CODE_FOR_nothing;
4555 for (i = 0; i < ARRAY_SIZE (floattab); i++)
4556 for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
4557 for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
4558 floattab[i][j][k] = CODE_FOR_nothing;
4560 for (i = 0; i < ARRAY_SIZE (extendtab); i++)
4561 for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
4562 for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
4563 extendtab[i][j][k] = CODE_FOR_nothing;
4565 for (i = 0; i < NUM_RTX_CODE; i++)
4566 setcc_gen_code[i] = CODE_FOR_nothing;
4568 #ifdef HAVE_conditional_move
4569 for (i = 0; i < NUM_MACHINE_MODES; i++)
4570 movcc_gen_code[i] = CODE_FOR_nothing;
4573 add_optab = init_optab (PLUS);
4574 addv_optab = init_optab (PLUS);
4575 sub_optab = init_optab (MINUS);
4576 subv_optab = init_optab (MINUS);
4577 smul_optab = init_optab (MULT);
4578 smulv_optab = init_optab (MULT);
4579 smul_highpart_optab = init_optab (UNKNOWN);
4580 umul_highpart_optab = init_optab (UNKNOWN);
4581 smul_widen_optab = init_optab (UNKNOWN);
4582 umul_widen_optab = init_optab (UNKNOWN);
4583 sdiv_optab = init_optab (DIV);
4584 sdivv_optab = init_optab (DIV);
4585 sdivmod_optab = init_optab (UNKNOWN);
4586 udiv_optab = init_optab (UDIV);
4587 udivmod_optab = init_optab (UNKNOWN);
4588 smod_optab = init_optab (MOD);
4589 umod_optab = init_optab (UMOD);
4590 flodiv_optab = init_optab (DIV);
4591 ftrunc_optab = init_optab (UNKNOWN);
4592 and_optab = init_optab (AND);
4593 ior_optab = init_optab (IOR);
4594 xor_optab = init_optab (XOR);
4595 ashl_optab = init_optab (ASHIFT);
4596 ashr_optab = init_optab (ASHIFTRT);
4597 lshr_optab = init_optab (LSHIFTRT);
4598 rotl_optab = init_optab (ROTATE);
4599 rotr_optab = init_optab (ROTATERT);
4600 smin_optab = init_optab (SMIN);
4601 smax_optab = init_optab (SMAX);
4602 umin_optab = init_optab (UMIN);
4603 umax_optab = init_optab (UMAX);
4604 mov_optab = init_optab (UNKNOWN);
4605 movstrict_optab = init_optab (UNKNOWN);
4606 cmp_optab = init_optab (UNKNOWN);
4607 ucmp_optab = init_optab (UNKNOWN);
4608 tst_optab = init_optab (UNKNOWN);
4609 neg_optab = init_optab (NEG);
4610 negv_optab = init_optab (NEG);
4611 abs_optab = init_optab (ABS);
4612 absv_optab = init_optab (ABS);
4613 one_cmpl_optab = init_optab (NOT);
4614 ffs_optab = init_optab (FFS);
4615 sqrt_optab = init_optab (SQRT);
4616 sin_optab = init_optab (UNKNOWN);
4617 cos_optab = init_optab (UNKNOWN);
4618 strlen_optab = init_optab (UNKNOWN);
4619 cbranch_optab = init_optab (UNKNOWN);
4620 cmov_optab = init_optab (UNKNOWN);
4621 cstore_optab = init_optab (UNKNOWN);
4623 for (i = 0; i < NUM_MACHINE_MODES; i++)
4625 movstr_optab[i] = CODE_FOR_nothing;
4626 clrstr_optab[i] = CODE_FOR_nothing;
4628 #ifdef HAVE_SECONDARY_RELOADS
4629 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4633 /* Fill in the optabs with the insns we support. */
4636 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4637 /* This flag says the same insns that convert to a signed fixnum
4638 also convert validly to an unsigned one. */
4639 for (i = 0; i < NUM_MACHINE_MODES; i++)
4640 for (j = 0; j < NUM_MACHINE_MODES; j++)
4641 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4644 /* Initialize the optabs with the names of the library functions. */
4645 init_integral_libfuncs (add_optab, "add", '3');
4646 init_floating_libfuncs (add_optab, "add", '3');
4647 init_integral_libfuncs (addv_optab, "addv", '3');
4648 init_floating_libfuncs (addv_optab, "add", '3');
4649 init_integral_libfuncs (sub_optab, "sub", '3');
4650 init_floating_libfuncs (sub_optab, "sub", '3');
4651 init_integral_libfuncs (subv_optab, "subv", '3');
4652 init_floating_libfuncs (subv_optab, "sub", '3');
4653 init_integral_libfuncs (smul_optab, "mul", '3');
4654 init_floating_libfuncs (smul_optab, "mul", '3');
4655 init_integral_libfuncs (smulv_optab, "mulv", '3');
4656 init_floating_libfuncs (smulv_optab, "mul", '3');
4657 init_integral_libfuncs (sdiv_optab, "div", '3');
4658 init_integral_libfuncs (sdivv_optab, "divv", '3');
4659 init_integral_libfuncs (udiv_optab, "udiv", '3');
4660 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4661 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4662 init_integral_libfuncs (smod_optab, "mod", '3');
4663 init_integral_libfuncs (umod_optab, "umod", '3');
4664 init_floating_libfuncs (flodiv_optab, "div", '3');
4665 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4666 init_integral_libfuncs (and_optab, "and", '3');
4667 init_integral_libfuncs (ior_optab, "ior", '3');
4668 init_integral_libfuncs (xor_optab, "xor", '3');
4669 init_integral_libfuncs (ashl_optab, "ashl", '3');
4670 init_integral_libfuncs (ashr_optab, "ashr", '3');
4671 init_integral_libfuncs (lshr_optab, "lshr", '3');
4672 init_integral_libfuncs (smin_optab, "min", '3');
4673 init_floating_libfuncs (smin_optab, "min", '3');
4674 init_integral_libfuncs (smax_optab, "max", '3');
4675 init_floating_libfuncs (smax_optab, "max", '3');
4676 init_integral_libfuncs (umin_optab, "umin", '3');
4677 init_integral_libfuncs (umax_optab, "umax", '3');
4678 init_integral_libfuncs (neg_optab, "neg", '2');
4679 init_floating_libfuncs (neg_optab, "neg", '2');
4680 init_integral_libfuncs (negv_optab, "negv", '2');
4681 init_floating_libfuncs (negv_optab, "neg", '2');
4682 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4683 init_integral_libfuncs (ffs_optab, "ffs", '2');
4685 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4686 init_integral_libfuncs (cmp_optab, "cmp", '2');
4687 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4688 init_floating_libfuncs (cmp_optab, "cmp", '2');
4690 #ifdef MULSI3_LIBCALL
4691 smul_optab->handlers[(int) SImode].libfunc
4692 = init_one_libfunc (MULSI3_LIBCALL);
4694 #ifdef MULDI3_LIBCALL
4695 smul_optab->handlers[(int) DImode].libfunc
4696 = init_one_libfunc (MULDI3_LIBCALL);
4699 #ifdef DIVSI3_LIBCALL
4700 sdiv_optab->handlers[(int) SImode].libfunc
4701 = init_one_libfunc (DIVSI3_LIBCALL);
4703 #ifdef DIVDI3_LIBCALL
4704 sdiv_optab->handlers[(int) DImode].libfunc
4705 = init_one_libfunc (DIVDI3_LIBCALL);
4708 #ifdef UDIVSI3_LIBCALL
4709 udiv_optab->handlers[(int) SImode].libfunc
4710 = init_one_libfunc (UDIVSI3_LIBCALL);
4712 #ifdef UDIVDI3_LIBCALL
4713 udiv_optab->handlers[(int) DImode].libfunc
4714 = init_one_libfunc (UDIVDI3_LIBCALL);
4717 #ifdef MODSI3_LIBCALL
4718 smod_optab->handlers[(int) SImode].libfunc
4719 = init_one_libfunc (MODSI3_LIBCALL);
4721 #ifdef MODDI3_LIBCALL
4722 smod_optab->handlers[(int) DImode].libfunc
4723 = init_one_libfunc (MODDI3_LIBCALL);
4726 #ifdef UMODSI3_LIBCALL
4727 umod_optab->handlers[(int) SImode].libfunc
4728 = init_one_libfunc (UMODSI3_LIBCALL);
4730 #ifdef UMODDI3_LIBCALL
4731 umod_optab->handlers[(int) DImode].libfunc
4732 = init_one_libfunc (UMODDI3_LIBCALL);
4735 /* Use cabs for DC complex abs, since systems generally have cabs.
4736 Don't define any libcall for SCmode, so that cabs will be used. */
4737 abs_optab->handlers[(int) DCmode].libfunc
4738 = init_one_libfunc ("cabs");
4740 /* The ffs function operates on `int'. */
4741 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
4742 = init_one_libfunc ("ffs");
4744 extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
4745 extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
4746 extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
4747 extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
4748 extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
4750 truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
4751 truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
4752 trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
4753 truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
4754 trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
4756 memcpy_libfunc = init_one_libfunc ("memcpy");
4757 bcopy_libfunc = init_one_libfunc ("bcopy");
4758 memcmp_libfunc = init_one_libfunc ("memcmp");
4759 bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
4760 memset_libfunc = init_one_libfunc ("memset");
4761 bzero_libfunc = init_one_libfunc ("bzero");
4763 throw_libfunc = init_one_libfunc ("__throw");
4764 rethrow_libfunc = init_one_libfunc ("__rethrow");
4765 sjthrow_libfunc = init_one_libfunc ("__sjthrow");
4766 sjpopnthrow_libfunc = init_one_libfunc ("__sjpopnthrow");
4767 terminate_libfunc = init_one_libfunc ("__terminate");
4768 eh_rtime_match_libfunc = init_one_libfunc ("__eh_rtime_match");
4769 #ifndef DONT_USE_BUILTIN_SETJMP
4770 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
4771 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
4773 setjmp_libfunc = init_one_libfunc ("setjmp");
4774 longjmp_libfunc = init_one_libfunc ("longjmp");
4777 eqhf2_libfunc = init_one_libfunc ("__eqhf2");
4778 nehf2_libfunc = init_one_libfunc ("__nehf2");
4779 gthf2_libfunc = init_one_libfunc ("__gthf2");
4780 gehf2_libfunc = init_one_libfunc ("__gehf2");
4781 lthf2_libfunc = init_one_libfunc ("__lthf2");
4782 lehf2_libfunc = init_one_libfunc ("__lehf2");
4783 unordhf2_libfunc = init_one_libfunc ("__unordhf2");
4785 eqsf2_libfunc = init_one_libfunc ("__eqsf2");
4786 nesf2_libfunc = init_one_libfunc ("__nesf2");
4787 gtsf2_libfunc = init_one_libfunc ("__gtsf2");
4788 gesf2_libfunc = init_one_libfunc ("__gesf2");
4789 ltsf2_libfunc = init_one_libfunc ("__ltsf2");
4790 lesf2_libfunc = init_one_libfunc ("__lesf2");
4791 unordsf2_libfunc = init_one_libfunc ("__unordsf2");
4793 eqdf2_libfunc = init_one_libfunc ("__eqdf2");
4794 nedf2_libfunc = init_one_libfunc ("__nedf2");
4795 gtdf2_libfunc = init_one_libfunc ("__gtdf2");
4796 gedf2_libfunc = init_one_libfunc ("__gedf2");
4797 ltdf2_libfunc = init_one_libfunc ("__ltdf2");
4798 ledf2_libfunc = init_one_libfunc ("__ledf2");
4799 unorddf2_libfunc = init_one_libfunc ("__unorddf2");
4801 eqxf2_libfunc = init_one_libfunc ("__eqxf2");
4802 nexf2_libfunc = init_one_libfunc ("__nexf2");
4803 gtxf2_libfunc = init_one_libfunc ("__gtxf2");
4804 gexf2_libfunc = init_one_libfunc ("__gexf2");
4805 ltxf2_libfunc = init_one_libfunc ("__ltxf2");
4806 lexf2_libfunc = init_one_libfunc ("__lexf2");
4807 unordxf2_libfunc = init_one_libfunc ("__unordxf2");
4809 eqtf2_libfunc = init_one_libfunc ("__eqtf2");
4810 netf2_libfunc = init_one_libfunc ("__netf2");
4811 gttf2_libfunc = init_one_libfunc ("__gttf2");
4812 getf2_libfunc = init_one_libfunc ("__getf2");
4813 lttf2_libfunc = init_one_libfunc ("__lttf2");
4814 letf2_libfunc = init_one_libfunc ("__letf2");
4815 unordtf2_libfunc = init_one_libfunc ("__unordtf2");
4817 floatsisf_libfunc = init_one_libfunc ("__floatsisf");
4818 floatdisf_libfunc = init_one_libfunc ("__floatdisf");
4819 floattisf_libfunc = init_one_libfunc ("__floattisf");
4821 floatsidf_libfunc = init_one_libfunc ("__floatsidf");
4822 floatdidf_libfunc = init_one_libfunc ("__floatdidf");
4823 floattidf_libfunc = init_one_libfunc ("__floattidf");
4825 floatsixf_libfunc = init_one_libfunc ("__floatsixf");
4826 floatdixf_libfunc = init_one_libfunc ("__floatdixf");
4827 floattixf_libfunc = init_one_libfunc ("__floattixf");
4829 floatsitf_libfunc = init_one_libfunc ("__floatsitf");
4830 floatditf_libfunc = init_one_libfunc ("__floatditf");
4831 floattitf_libfunc = init_one_libfunc ("__floattitf");
4833 fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
4834 fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
4835 fixsfti_libfunc = init_one_libfunc ("__fixsfti");
4837 fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
4838 fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
4839 fixdfti_libfunc = init_one_libfunc ("__fixdfti");
4841 fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
4842 fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
4843 fixxfti_libfunc = init_one_libfunc ("__fixxfti");
4845 fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
4846 fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
4847 fixtfti_libfunc = init_one_libfunc ("__fixtfti");
4849 fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
4850 fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
4851 fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
4853 fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
4854 fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
4855 fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
4857 fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
4858 fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
4859 fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
4861 fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
4862 fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
4863 fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
4865 /* For check-memory-usage. */
4866 chkr_check_addr_libfunc = init_one_libfunc ("chkr_check_addr");
4867 chkr_set_right_libfunc = init_one_libfunc ("chkr_set_right");
4868 chkr_copy_bitmap_libfunc = init_one_libfunc ("chkr_copy_bitmap");
4869 chkr_check_exec_libfunc = init_one_libfunc ("chkr_check_exec");
4870 chkr_check_str_libfunc = init_one_libfunc ("chkr_check_str");
4872 /* For function entry/exit instrumentation. */
4873 profile_function_entry_libfunc
4874 = init_one_libfunc ("__cyg_profile_func_enter");
4875 profile_function_exit_libfunc
4876 = init_one_libfunc ("__cyg_profile_func_exit");
4878 #ifdef HAVE_conditional_trap
4882 #ifdef INIT_TARGET_OPTABS
4883 /* Allow the target to add more libcalls or rename some, etc. */
4887 /* Add these GC roots. */
4888 ggc_add_root (optab_table, OTI_MAX, sizeof(optab), mark_optab);
4889 ggc_add_rtx_root (libfunc_table, LTI_MAX);
4894 /* SCO 3.2 apparently has a broken ldexp. */
4907 #endif /* BROKEN_LDEXP */
4909 #ifdef HAVE_conditional_trap
4910 /* The insn generating function can not take an rtx_code argument.
4911 TRAP_RTX is used as an rtx argument. Its code is replaced with
4912 the code to be used in the trap insn and all other fields are
4914 static rtx trap_rtx;
4919 if (HAVE_conditional_trap)
4921 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4922 ggc_add_rtx_root (&trap_rtx, 1);
4927 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4928 CODE. Return 0 on failure. */
4931 gen_cond_trap (code, op1, op2, tcode)
4932 enum rtx_code code ATTRIBUTE_UNUSED;
4933 rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
4935 enum machine_mode mode = GET_MODE (op1);
4937 if (mode == VOIDmode)
4940 #ifdef HAVE_conditional_trap
4941 if (HAVE_conditional_trap
4942 && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4946 emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4947 PUT_CODE (trap_rtx, code);
4948 insn = gen_conditional_trap (trap_rtx, tcode);
4952 insn = gen_sequence ();