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 GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 /* Include insn-config.h before expr.h so that HAVE_conditional_move
28 is properly defined. */
29 #include "insn-config.h"
44 /* Each optab contains info on how this target machine
45 can perform a particular operation
46 for all sizes and kinds of operands.
48 The operation to be performed is often specified
49 by passing one of these optabs as an argument.
51 See expr.h for documentation of these optabs. */
53 optab optab_table[OTI_MAX];
55 rtx libfunc_table[LTI_MAX];
57 /* Tables of patterns for extending one integer mode to another. */
58 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
60 /* Tables of patterns for converting between fixed and floating point. */
61 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
62 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
63 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
65 /* Contains the optab used for each rtx code. */
66 optab code_to_optab[NUM_RTX_CODE + 1];
68 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
69 gives the gen_function to make a branch to test that condition. */
71 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
73 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
74 gives the insn code to make a store-condition insn
75 to test that condition. */
77 enum insn_code setcc_gen_code[NUM_RTX_CODE];
79 #ifdef HAVE_conditional_move
80 /* Indexed by the machine mode, gives the insn code to make a conditional
81 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
82 setcc_gen_code to cut down on the number of named patterns. Consider a day
83 when a lot more rtx codes are conditional (eg: for the ARM). */
85 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
88 static int add_equal_note PARAMS ((rtx, rtx, enum rtx_code, rtx, rtx));
89 static rtx widen_operand PARAMS ((rtx, enum machine_mode,
90 enum machine_mode, int, int));
91 static int expand_cmplxdiv_straight PARAMS ((rtx, rtx, rtx, rtx,
92 rtx, rtx, enum machine_mode,
93 int, enum optab_methods,
94 enum mode_class, optab));
95 static int expand_cmplxdiv_wide PARAMS ((rtx, rtx, rtx, rtx,
96 rtx, rtx, enum machine_mode,
97 int, enum optab_methods,
98 enum mode_class, optab));
99 static void prepare_cmp_insn PARAMS ((rtx *, rtx *, enum rtx_code *, rtx,
100 enum machine_mode *, int *,
101 enum can_compare_purpose));
102 static enum insn_code can_fix_p PARAMS ((enum machine_mode, enum machine_mode,
104 static enum insn_code can_float_p PARAMS ((enum machine_mode,
107 static rtx ftruncify PARAMS ((rtx));
108 static optab new_optab PARAMS ((void));
109 static inline optab init_optab PARAMS ((enum rtx_code));
110 static inline optab init_optabv PARAMS ((enum rtx_code));
111 static void init_libfuncs PARAMS ((optab, int, int, const char *, int));
112 static void init_integral_libfuncs PARAMS ((optab, const char *, int));
113 static void init_floating_libfuncs PARAMS ((optab, const char *, int));
114 #ifdef HAVE_conditional_trap
115 static void init_traps PARAMS ((void));
117 static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode,
118 enum rtx_code, int, rtx));
119 static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
120 enum machine_mode *, int *));
121 static rtx expand_vector_binop PARAMS ((enum machine_mode, optab,
123 enum optab_methods));
124 static rtx expand_vector_unop PARAMS ((enum machine_mode, optab, rtx, rtx,
127 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
128 the result of operation CODE applied to OP0 (and OP1 if it is a binary
131 If the last insn does not set TARGET, don't do anything, but return 1.
133 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
134 don't add the REG_EQUAL note but return 0. Our caller can then try
135 again, ensuring that TARGET is not one of the operands. */
138 add_equal_note (insns, target, code, op0, op1)
144 rtx last_insn, insn, set;
149 || NEXT_INSN (insns) == NULL_RTX)
152 if (GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
153 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
156 if (GET_CODE (target) == ZERO_EXTRACT)
159 for (last_insn = insns;
160 NEXT_INSN (last_insn) != NULL_RTX;
161 last_insn = NEXT_INSN (last_insn))
164 set = single_set (last_insn);
168 if (! rtx_equal_p (SET_DEST (set), target)
169 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
171 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
172 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
176 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
177 besides the last insn. */
178 if (reg_overlap_mentioned_p (target, op0)
179 || (op1 && reg_overlap_mentioned_p (target, op1)))
181 insn = PREV_INSN (last_insn);
182 while (insn != NULL_RTX)
184 if (reg_set_p (target, insn))
187 insn = PREV_INSN (insn);
191 if (GET_RTX_CLASS (code) == '1')
192 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
194 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
196 set_unique_reg_note (last_insn, REG_EQUAL, note);
201 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
202 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
203 not actually do a sign-extend or zero-extend, but can leave the
204 higher-order bits of the result rtx undefined, for example, in the case
205 of logical operations, but not right shifts. */
208 widen_operand (op, mode, oldmode, unsignedp, no_extend)
210 enum machine_mode mode, oldmode;
216 /* If we don't have to extend and this is a constant, return it. */
217 if (no_extend && GET_MODE (op) == VOIDmode)
220 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
221 extend since it will be more efficient to do so unless the signedness of
222 a promoted object differs from our extension. */
224 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
225 && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
226 return convert_modes (mode, oldmode, op, unsignedp);
228 /* If MODE is no wider than a single word, we return a paradoxical
230 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
231 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
233 /* Otherwise, get an object of MODE, clobber it, and set the low-order
236 result = gen_reg_rtx (mode);
237 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
238 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
242 /* Generate code to perform a straightforward complex divide. */
245 expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
246 unsignedp, methods, class, binoptab)
247 rtx real0, real1, imag0, imag1, realr, imagr;
248 enum machine_mode submode;
250 enum optab_methods methods;
251 enum mode_class class;
258 optab this_add_optab = add_optab;
259 optab this_sub_optab = sub_optab;
260 optab this_neg_optab = neg_optab;
261 optab this_mul_optab = smul_optab;
263 if (binoptab == sdivv_optab)
265 this_add_optab = addv_optab;
266 this_sub_optab = subv_optab;
267 this_neg_optab = negv_optab;
268 this_mul_optab = smulv_optab;
271 /* Don't fetch these from memory more than once. */
272 real0 = force_reg (submode, real0);
273 real1 = force_reg (submode, real1);
276 imag0 = force_reg (submode, imag0);
278 imag1 = force_reg (submode, imag1);
280 /* Divisor: c*c + d*d. */
281 temp1 = expand_binop (submode, this_mul_optab, real1, real1,
282 NULL_RTX, unsignedp, methods);
284 temp2 = expand_binop (submode, this_mul_optab, imag1, imag1,
285 NULL_RTX, unsignedp, methods);
287 if (temp1 == 0 || temp2 == 0)
290 divisor = expand_binop (submode, this_add_optab, temp1, temp2,
291 NULL_RTX, unsignedp, methods);
297 /* Mathematically, ((a)(c-id))/divisor. */
298 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */
300 /* Calculate the dividend. */
301 real_t = expand_binop (submode, this_mul_optab, real0, real1,
302 NULL_RTX, unsignedp, methods);
304 imag_t = expand_binop (submode, this_mul_optab, real0, imag1,
305 NULL_RTX, unsignedp, methods);
307 if (real_t == 0 || imag_t == 0)
310 imag_t = expand_unop (submode, this_neg_optab, imag_t,
311 NULL_RTX, unsignedp);
315 /* Mathematically, ((a+ib)(c-id))/divider. */
316 /* Calculate the dividend. */
317 temp1 = expand_binop (submode, this_mul_optab, real0, real1,
318 NULL_RTX, unsignedp, methods);
320 temp2 = expand_binop (submode, this_mul_optab, imag0, imag1,
321 NULL_RTX, unsignedp, methods);
323 if (temp1 == 0 || temp2 == 0)
326 real_t = expand_binop (submode, this_add_optab, temp1, temp2,
327 NULL_RTX, unsignedp, methods);
329 temp1 = expand_binop (submode, this_mul_optab, imag0, real1,
330 NULL_RTX, unsignedp, methods);
332 temp2 = expand_binop (submode, this_mul_optab, real0, imag1,
333 NULL_RTX, unsignedp, methods);
335 if (temp1 == 0 || temp2 == 0)
338 imag_t = expand_binop (submode, this_sub_optab, temp1, temp2,
339 NULL_RTX, unsignedp, methods);
341 if (real_t == 0 || imag_t == 0)
345 if (class == MODE_COMPLEX_FLOAT)
346 res = expand_binop (submode, binoptab, real_t, divisor,
347 realr, unsignedp, methods);
349 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
350 real_t, divisor, realr, unsignedp);
356 emit_move_insn (realr, res);
358 if (class == MODE_COMPLEX_FLOAT)
359 res = expand_binop (submode, binoptab, imag_t, divisor,
360 imagr, unsignedp, methods);
362 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
363 imag_t, divisor, imagr, unsignedp);
369 emit_move_insn (imagr, res);
374 /* Generate code to perform a wide-input-range-acceptable complex divide. */
377 expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
378 unsignedp, methods, class, binoptab)
379 rtx real0, real1, imag0, imag1, realr, imagr;
380 enum machine_mode submode;
382 enum optab_methods methods;
383 enum mode_class class;
388 rtx temp1, temp2, lab1, lab2;
389 enum machine_mode mode;
391 optab this_add_optab = add_optab;
392 optab this_sub_optab = sub_optab;
393 optab this_neg_optab = neg_optab;
394 optab this_mul_optab = smul_optab;
396 if (binoptab == sdivv_optab)
398 this_add_optab = addv_optab;
399 this_sub_optab = subv_optab;
400 this_neg_optab = negv_optab;
401 this_mul_optab = smulv_optab;
404 /* Don't fetch these from memory more than once. */
405 real0 = force_reg (submode, real0);
406 real1 = force_reg (submode, real1);
409 imag0 = force_reg (submode, imag0);
411 imag1 = force_reg (submode, imag1);
413 /* XXX What's an "unsigned" complex number? */
421 temp1 = expand_abs (submode, real1, NULL_RTX, unsignedp, 1);
422 temp2 = expand_abs (submode, imag1, NULL_RTX, unsignedp, 1);
425 if (temp1 == 0 || temp2 == 0)
428 mode = GET_MODE (temp1);
429 lab1 = gen_label_rtx ();
430 emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX,
431 mode, unsignedp, lab1);
433 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */
435 if (class == MODE_COMPLEX_FLOAT)
436 ratio = expand_binop (submode, binoptab, imag1, real1,
437 NULL_RTX, unsignedp, methods);
439 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
440 imag1, real1, NULL_RTX, unsignedp);
445 /* Calculate divisor. */
447 temp1 = expand_binop (submode, this_mul_optab, imag1, ratio,
448 NULL_RTX, unsignedp, methods);
453 divisor = expand_binop (submode, this_add_optab, temp1, real1,
454 NULL_RTX, unsignedp, methods);
459 /* Calculate dividend. */
465 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */
467 imag_t = expand_binop (submode, this_mul_optab, real0, ratio,
468 NULL_RTX, unsignedp, methods);
473 imag_t = expand_unop (submode, this_neg_optab, imag_t,
474 NULL_RTX, unsignedp);
476 if (real_t == 0 || imag_t == 0)
481 /* Compute (a+ib)/(c+id) as
482 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */
484 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
485 NULL_RTX, unsignedp, methods);
490 real_t = expand_binop (submode, this_add_optab, temp1, real0,
491 NULL_RTX, unsignedp, methods);
493 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
494 NULL_RTX, unsignedp, methods);
499 imag_t = expand_binop (submode, this_sub_optab, imag0, temp1,
500 NULL_RTX, unsignedp, methods);
502 if (real_t == 0 || imag_t == 0)
506 if (class == MODE_COMPLEX_FLOAT)
507 res = expand_binop (submode, binoptab, real_t, divisor,
508 realr, unsignedp, methods);
510 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
511 real_t, divisor, realr, unsignedp);
517 emit_move_insn (realr, res);
519 if (class == MODE_COMPLEX_FLOAT)
520 res = expand_binop (submode, binoptab, imag_t, divisor,
521 imagr, unsignedp, methods);
523 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
524 imag_t, divisor, imagr, unsignedp);
530 emit_move_insn (imagr, res);
532 lab2 = gen_label_rtx ();
533 emit_jump_insn (gen_jump (lab2));
538 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */
540 if (class == MODE_COMPLEX_FLOAT)
541 ratio = expand_binop (submode, binoptab, real1, imag1,
542 NULL_RTX, unsignedp, methods);
544 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
545 real1, imag1, NULL_RTX, unsignedp);
550 /* Calculate divisor. */
552 temp1 = expand_binop (submode, this_mul_optab, real1, ratio,
553 NULL_RTX, unsignedp, methods);
558 divisor = expand_binop (submode, this_add_optab, temp1, imag1,
559 NULL_RTX, unsignedp, methods);
564 /* Calculate dividend. */
568 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */
570 real_t = expand_binop (submode, this_mul_optab, real0, ratio,
571 NULL_RTX, unsignedp, methods);
573 imag_t = expand_unop (submode, this_neg_optab, real0,
574 NULL_RTX, unsignedp);
576 if (real_t == 0 || imag_t == 0)
581 /* Compute (a+ib)/(c+id) as
582 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */
584 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
585 NULL_RTX, unsignedp, methods);
590 real_t = expand_binop (submode, this_add_optab, temp1, imag0,
591 NULL_RTX, unsignedp, methods);
593 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
594 NULL_RTX, unsignedp, methods);
599 imag_t = expand_binop (submode, this_sub_optab, temp1, real0,
600 NULL_RTX, unsignedp, methods);
602 if (real_t == 0 || imag_t == 0)
606 if (class == MODE_COMPLEX_FLOAT)
607 res = expand_binop (submode, binoptab, real_t, divisor,
608 realr, unsignedp, methods);
610 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
611 real_t, divisor, realr, unsignedp);
617 emit_move_insn (realr, res);
619 if (class == MODE_COMPLEX_FLOAT)
620 res = expand_binop (submode, binoptab, imag_t, divisor,
621 imagr, unsignedp, methods);
623 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
624 imag_t, divisor, imagr, unsignedp);
630 emit_move_insn (imagr, res);
637 /* Wrapper around expand_binop which takes an rtx code to specify
638 the operation to perform, not an optab pointer. All other
639 arguments are the same. */
641 expand_simple_binop (mode, code, op0, op1, target, unsignedp, methods)
642 enum machine_mode mode;
647 enum optab_methods methods;
649 optab binop = code_to_optab [(int) code];
653 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
656 /* Generate code to perform an operation specified by BINOPTAB
657 on operands OP0 and OP1, with result having machine-mode MODE.
659 UNSIGNEDP is for the case where we have to widen the operands
660 to perform the operation. It says to use zero-extension.
662 If TARGET is nonzero, the value
663 is generated there, if it is convenient to do so.
664 In all cases an rtx is returned for the locus of the value;
665 this may or may not be TARGET. */
668 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
669 enum machine_mode mode;
674 enum optab_methods methods;
676 enum optab_methods next_methods
677 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
678 ? OPTAB_WIDEN : methods);
679 enum mode_class class;
680 enum machine_mode wider_mode;
682 int commutative_op = 0;
683 int shift_op = (binoptab->code == ASHIFT
684 || binoptab->code == ASHIFTRT
685 || binoptab->code == LSHIFTRT
686 || binoptab->code == ROTATE
687 || binoptab->code == ROTATERT);
688 rtx entry_last = get_last_insn ();
691 class = GET_MODE_CLASS (mode);
693 op0 = protect_from_queue (op0, 0);
694 op1 = protect_from_queue (op1, 0);
696 target = protect_from_queue (target, 1);
700 op0 = force_not_mem (op0);
701 op1 = force_not_mem (op1);
704 /* If subtracting an integer constant, convert this into an addition of
705 the negated constant. */
707 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
709 op1 = negate_rtx (mode, op1);
710 binoptab = add_optab;
713 /* If we are inside an appropriately-short loop and one operand is an
714 expensive constant, force it into a register. */
715 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
716 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
717 op0 = force_reg (mode, op0);
719 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
720 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
721 op1 = force_reg (mode, op1);
723 /* Record where to delete back to if we backtrack. */
724 last = get_last_insn ();
726 /* If operation is commutative,
727 try to make the first operand a register.
728 Even better, try to make it the same as the target.
729 Also try to make the last operand a constant. */
730 if (GET_RTX_CLASS (binoptab->code) == 'c'
731 || binoptab == smul_widen_optab
732 || binoptab == umul_widen_optab
733 || binoptab == smul_highpart_optab
734 || binoptab == umul_highpart_optab)
738 if (((target == 0 || GET_CODE (target) == REG)
739 ? ((GET_CODE (op1) == REG
740 && GET_CODE (op0) != REG)
742 : rtx_equal_p (op1, target))
743 || GET_CODE (op0) == CONST_INT)
751 /* If we can do it with a three-operand insn, do so. */
753 if (methods != OPTAB_MUST_WIDEN
754 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
756 int icode = (int) binoptab->handlers[(int) mode].insn_code;
757 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
758 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
760 rtx xop0 = op0, xop1 = op1;
765 temp = gen_reg_rtx (mode);
767 /* If it is a commutative operator and the modes would match
768 if we would swap the operands, we can save the conversions. */
771 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
772 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
776 tmp = op0; op0 = op1; op1 = tmp;
777 tmp = xop0; xop0 = xop1; xop1 = tmp;
781 /* In case the insn wants input operands in modes different from
782 those of the actual operands, convert the operands. It would
783 seem that we don't need to convert CONST_INTs, but we do, so
784 that they're properly zero-extended or sign-extended for their
785 modes; shift operations are an exception, because the second
786 operand needs not be extended to the mode of the result. */
788 if (GET_MODE (op0) != mode0
789 && mode0 != VOIDmode)
790 xop0 = convert_modes (mode0,
791 GET_MODE (op0) != VOIDmode
796 if (GET_MODE (xop1) != mode1
797 && mode1 != VOIDmode)
798 xop1 = convert_modes (mode1,
799 GET_MODE (op1) != VOIDmode
806 /* Now, if insn's predicates don't allow our operands, put them into
809 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)
810 && mode0 != VOIDmode)
811 xop0 = copy_to_mode_reg (mode0, xop0);
813 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
814 && mode1 != VOIDmode)
815 xop1 = copy_to_mode_reg (mode1, xop1);
817 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
818 temp = gen_reg_rtx (mode);
820 pat = GEN_FCN (icode) (temp, xop0, xop1);
823 /* If PAT is composed of more than one insn, try to add an appropriate
824 REG_EQUAL note to it. If we can't because TEMP conflicts with an
825 operand, call ourselves again, this time without a target. */
826 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
827 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
829 delete_insns_since (last);
830 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
838 delete_insns_since (last);
841 /* If this is a multiply, see if we can do a widening operation that
842 takes operands of this mode and makes a wider mode. */
844 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
845 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
846 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
847 != CODE_FOR_nothing))
849 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
850 unsignedp ? umul_widen_optab : smul_widen_optab,
851 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
855 if (GET_MODE_CLASS (mode) == MODE_INT)
856 return gen_lowpart (mode, temp);
858 return convert_to_mode (mode, temp, unsignedp);
862 /* Look for a wider mode of the same class for which we think we
863 can open-code the operation. Check for a widening multiply at the
864 wider mode as well. */
866 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
867 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
868 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
869 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
871 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
872 || (binoptab == smul_optab
873 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
874 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
875 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
876 != CODE_FOR_nothing)))
878 rtx xop0 = op0, xop1 = op1;
881 /* For certain integer operations, we need not actually extend
882 the narrow operands, as long as we will truncate
883 the results to the same narrowness. */
885 if ((binoptab == ior_optab || binoptab == and_optab
886 || binoptab == xor_optab
887 || binoptab == add_optab || binoptab == sub_optab
888 || binoptab == smul_optab || binoptab == ashl_optab)
889 && class == MODE_INT)
892 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
894 /* The second operand of a shift must always be extended. */
895 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
896 no_extend && binoptab != ashl_optab);
898 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
899 unsignedp, OPTAB_DIRECT);
902 if (class != MODE_INT)
905 target = gen_reg_rtx (mode);
906 convert_move (target, temp, 0);
910 return gen_lowpart (mode, temp);
913 delete_insns_since (last);
917 /* These can be done a word at a time. */
918 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
920 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
921 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
927 /* If TARGET is the same as one of the operands, the REG_EQUAL note
928 won't be accurate, so use a new target. */
929 if (target == 0 || target == op0 || target == op1)
930 target = gen_reg_rtx (mode);
934 /* Do the actual arithmetic. */
935 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
937 rtx target_piece = operand_subword (target, i, 1, mode);
938 rtx x = expand_binop (word_mode, binoptab,
939 operand_subword_force (op0, i, mode),
940 operand_subword_force (op1, i, mode),
941 target_piece, unsignedp, next_methods);
946 if (target_piece != x)
947 emit_move_insn (target_piece, x);
950 insns = get_insns ();
953 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
955 if (binoptab->code != UNKNOWN)
957 = gen_rtx_fmt_ee (binoptab->code, mode,
958 copy_rtx (op0), copy_rtx (op1));
962 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
967 /* Synthesize double word shifts from single word shifts. */
968 if ((binoptab == lshr_optab || binoptab == ashl_optab
969 || binoptab == ashr_optab)
971 && GET_CODE (op1) == CONST_INT
972 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
973 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
974 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
975 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
977 rtx insns, inter, equiv_value;
978 rtx into_target, outof_target;
979 rtx into_input, outof_input;
980 int shift_count, left_shift, outof_word;
982 /* If TARGET is the same as one of the operands, the REG_EQUAL note
983 won't be accurate, so use a new target. */
984 if (target == 0 || target == op0 || target == op1)
985 target = gen_reg_rtx (mode);
989 shift_count = INTVAL (op1);
991 /* OUTOF_* is the word we are shifting bits away from, and
992 INTO_* is the word that we are shifting bits towards, thus
993 they differ depending on the direction of the shift and
996 left_shift = binoptab == ashl_optab;
997 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
999 outof_target = operand_subword (target, outof_word, 1, mode);
1000 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1002 outof_input = operand_subword_force (op0, outof_word, mode);
1003 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1005 if (shift_count >= BITS_PER_WORD)
1007 inter = expand_binop (word_mode, binoptab,
1009 GEN_INT (shift_count - BITS_PER_WORD),
1010 into_target, unsignedp, next_methods);
1012 if (inter != 0 && inter != into_target)
1013 emit_move_insn (into_target, inter);
1015 /* For a signed right shift, we must fill the word we are shifting
1016 out of with copies of the sign bit. Otherwise it is zeroed. */
1017 if (inter != 0 && binoptab != ashr_optab)
1018 inter = CONST0_RTX (word_mode);
1019 else if (inter != 0)
1020 inter = expand_binop (word_mode, binoptab,
1022 GEN_INT (BITS_PER_WORD - 1),
1023 outof_target, unsignedp, next_methods);
1025 if (inter != 0 && inter != outof_target)
1026 emit_move_insn (outof_target, inter);
1031 optab reverse_unsigned_shift, unsigned_shift;
1033 /* For a shift of less then BITS_PER_WORD, to compute the carry,
1034 we must do a logical shift in the opposite direction of the
1037 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
1039 /* For a shift of less than BITS_PER_WORD, to compute the word
1040 shifted towards, we need to unsigned shift the orig value of
1043 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
1045 carries = expand_binop (word_mode, reverse_unsigned_shift,
1047 GEN_INT (BITS_PER_WORD - shift_count),
1048 0, unsignedp, next_methods);
1053 inter = expand_binop (word_mode, unsigned_shift, into_input,
1054 op1, 0, unsignedp, next_methods);
1057 inter = expand_binop (word_mode, ior_optab, carries, inter,
1058 into_target, unsignedp, next_methods);
1060 if (inter != 0 && inter != into_target)
1061 emit_move_insn (into_target, inter);
1064 inter = expand_binop (word_mode, binoptab, outof_input,
1065 op1, outof_target, unsignedp, next_methods);
1067 if (inter != 0 && inter != outof_target)
1068 emit_move_insn (outof_target, inter);
1071 insns = get_insns ();
1076 if (binoptab->code != UNKNOWN)
1077 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1081 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1086 /* Synthesize double word rotates from single word shifts. */
1087 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1088 && class == MODE_INT
1089 && GET_CODE (op1) == CONST_INT
1090 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1091 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1092 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1094 rtx insns, equiv_value;
1095 rtx into_target, outof_target;
1096 rtx into_input, outof_input;
1098 int shift_count, left_shift, outof_word;
1100 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1101 won't be accurate, so use a new target. */
1102 if (target == 0 || target == op0 || target == op1)
1103 target = gen_reg_rtx (mode);
1107 shift_count = INTVAL (op1);
1109 /* OUTOF_* is the word we are shifting bits away from, and
1110 INTO_* is the word that we are shifting bits towards, thus
1111 they differ depending on the direction of the shift and
1112 WORDS_BIG_ENDIAN. */
1114 left_shift = (binoptab == rotl_optab);
1115 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1117 outof_target = operand_subword (target, outof_word, 1, mode);
1118 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1120 outof_input = operand_subword_force (op0, outof_word, mode);
1121 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1123 if (shift_count == BITS_PER_WORD)
1125 /* This is just a word swap. */
1126 emit_move_insn (outof_target, into_input);
1127 emit_move_insn (into_target, outof_input);
1132 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1133 rtx first_shift_count, second_shift_count;
1134 optab reverse_unsigned_shift, unsigned_shift;
1136 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1137 ? lshr_optab : ashl_optab);
1139 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1140 ? ashl_optab : lshr_optab);
1142 if (shift_count > BITS_PER_WORD)
1144 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1145 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
1149 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1150 second_shift_count = GEN_INT (shift_count);
1153 into_temp1 = expand_binop (word_mode, unsigned_shift,
1154 outof_input, first_shift_count,
1155 NULL_RTX, unsignedp, next_methods);
1156 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1157 into_input, second_shift_count,
1158 into_target, unsignedp, next_methods);
1160 if (into_temp1 != 0 && into_temp2 != 0)
1161 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1162 into_target, unsignedp, next_methods);
1166 if (inter != 0 && inter != into_target)
1167 emit_move_insn (into_target, inter);
1169 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1170 into_input, first_shift_count,
1171 NULL_RTX, unsignedp, next_methods);
1172 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1173 outof_input, second_shift_count,
1174 outof_target, unsignedp, next_methods);
1176 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1177 inter = expand_binop (word_mode, ior_optab,
1178 outof_temp1, outof_temp2,
1179 outof_target, unsignedp, next_methods);
1181 if (inter != 0 && inter != outof_target)
1182 emit_move_insn (outof_target, inter);
1185 insns = get_insns ();
1190 if (binoptab->code != UNKNOWN)
1191 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1195 /* We can't make this a no conflict block if this is a word swap,
1196 because the word swap case fails if the input and output values
1197 are in the same register. */
1198 if (shift_count != BITS_PER_WORD)
1199 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1208 /* These can be done a word at a time by propagating carries. */
1209 if ((binoptab == add_optab || binoptab == sub_optab)
1210 && class == MODE_INT
1211 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1212 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1215 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1216 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1217 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1218 rtx xop0, xop1, xtarget;
1220 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1221 value is one of those, use it. Otherwise, use 1 since it is the
1222 one easiest to get. */
1223 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1224 int normalizep = STORE_FLAG_VALUE;
1229 /* Prepare the operands. */
1230 xop0 = force_reg (mode, op0);
1231 xop1 = force_reg (mode, op1);
1233 xtarget = gen_reg_rtx (mode);
1235 if (target == 0 || GET_CODE (target) != REG)
1238 /* Indicate for flow that the entire target reg is being set. */
1239 if (GET_CODE (target) == REG)
1240 emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
1242 /* Do the actual arithmetic. */
1243 for (i = 0; i < nwords; i++)
1245 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1246 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1247 rtx op0_piece = operand_subword_force (xop0, index, mode);
1248 rtx op1_piece = operand_subword_force (xop1, index, mode);
1251 /* Main add/subtract of the input operands. */
1252 x = expand_binop (word_mode, binoptab,
1253 op0_piece, op1_piece,
1254 target_piece, unsignedp, next_methods);
1260 /* Store carry from main add/subtract. */
1261 carry_out = gen_reg_rtx (word_mode);
1262 carry_out = emit_store_flag_force (carry_out,
1263 (binoptab == add_optab
1266 word_mode, 1, normalizep);
1273 /* Add/subtract previous carry to main result. */
1274 newx = expand_binop (word_mode,
1275 normalizep == 1 ? binoptab : otheroptab,
1277 NULL_RTX, 1, next_methods);
1281 /* Get out carry from adding/subtracting carry in. */
1282 rtx carry_tmp = gen_reg_rtx (word_mode);
1283 carry_tmp = emit_store_flag_force (carry_tmp,
1284 (binoptab == add_optab
1287 word_mode, 1, normalizep);
1289 /* Logical-ior the two poss. carry together. */
1290 carry_out = expand_binop (word_mode, ior_optab,
1291 carry_out, carry_tmp,
1292 carry_out, 0, next_methods);
1296 emit_move_insn (target_piece, newx);
1299 carry_in = carry_out;
1302 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1304 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1306 rtx temp = emit_move_insn (target, xtarget);
1308 set_unique_reg_note (temp,
1310 gen_rtx_fmt_ee (binoptab->code, mode,
1319 delete_insns_since (last);
1322 /* If we want to multiply two two-word values and have normal and widening
1323 multiplies of single-word values, we can do this with three smaller
1324 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1325 because we are not operating on one word at a time.
1327 The multiplication proceeds as follows:
1328 _______________________
1329 [__op0_high_|__op0_low__]
1330 _______________________
1331 * [__op1_high_|__op1_low__]
1332 _______________________________________________
1333 _______________________
1334 (1) [__op0_low__*__op1_low__]
1335 _______________________
1336 (2a) [__op0_low__*__op1_high_]
1337 _______________________
1338 (2b) [__op0_high_*__op1_low__]
1339 _______________________
1340 (3) [__op0_high_*__op1_high_]
1343 This gives a 4-word result. Since we are only interested in the
1344 lower 2 words, partial result (3) and the upper words of (2a) and
1345 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1346 calculated using non-widening multiplication.
1348 (1), however, needs to be calculated with an unsigned widening
1349 multiplication. If this operation is not directly supported we
1350 try using a signed widening multiplication and adjust the result.
1351 This adjustment works as follows:
1353 If both operands are positive then no adjustment is needed.
1355 If the operands have different signs, for example op0_low < 0 and
1356 op1_low >= 0, the instruction treats the most significant bit of
1357 op0_low as a sign bit instead of a bit with significance
1358 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1359 with 2**BITS_PER_WORD - op0_low, and two's complements the
1360 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1363 Similarly, if both operands are negative, we need to add
1364 (op0_low + op1_low) * 2**BITS_PER_WORD.
1366 We use a trick to adjust quickly. We logically shift op0_low right
1367 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1368 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1369 logical shift exists, we do an arithmetic right shift and subtract
1372 if (binoptab == smul_optab
1373 && class == MODE_INT
1374 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1375 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1376 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1377 && ((umul_widen_optab->handlers[(int) mode].insn_code
1378 != CODE_FOR_nothing)
1379 || (smul_widen_optab->handlers[(int) mode].insn_code
1380 != CODE_FOR_nothing)))
1382 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1383 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1384 rtx op0_high = operand_subword_force (op0, high, mode);
1385 rtx op0_low = operand_subword_force (op0, low, mode);
1386 rtx op1_high = operand_subword_force (op1, high, mode);
1387 rtx op1_low = operand_subword_force (op1, low, mode);
1389 rtx op0_xhigh = NULL_RTX;
1390 rtx op1_xhigh = NULL_RTX;
1392 /* If the target is the same as one of the inputs, don't use it. This
1393 prevents problems with the REG_EQUAL note. */
1394 if (target == op0 || target == op1
1395 || (target != 0 && GET_CODE (target) != REG))
1398 /* Multiply the two lower words to get a double-word product.
1399 If unsigned widening multiplication is available, use that;
1400 otherwise use the signed form and compensate. */
1402 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1404 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1405 target, 1, OPTAB_DIRECT);
1407 /* If we didn't succeed, delete everything we did so far. */
1409 delete_insns_since (last);
1411 op0_xhigh = op0_high, op1_xhigh = op1_high;
1415 && smul_widen_optab->handlers[(int) mode].insn_code
1416 != CODE_FOR_nothing)
1418 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1419 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1420 target, 1, OPTAB_DIRECT);
1421 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1422 NULL_RTX, 1, next_methods);
1424 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1425 op0_xhigh, op0_xhigh, 0, next_methods);
1428 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1429 NULL_RTX, 0, next_methods);
1431 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1432 op0_xhigh, op0_xhigh, 0,
1436 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1437 NULL_RTX, 1, next_methods);
1439 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1440 op1_xhigh, op1_xhigh, 0, next_methods);
1443 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1444 NULL_RTX, 0, next_methods);
1446 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1447 op1_xhigh, op1_xhigh, 0,
1452 /* If we have been able to directly compute the product of the
1453 low-order words of the operands and perform any required adjustments
1454 of the operands, we proceed by trying two more multiplications
1455 and then computing the appropriate sum.
1457 We have checked above that the required addition is provided.
1458 Full-word addition will normally always succeed, especially if
1459 it is provided at all, so we don't worry about its failure. The
1460 multiplication may well fail, however, so we do handle that. */
1462 if (product && op0_xhigh && op1_xhigh)
1464 rtx product_high = operand_subword (product, high, 1, mode);
1465 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1466 NULL_RTX, 0, OPTAB_DIRECT);
1468 if (!REG_P (product_high))
1469 product_high = force_reg (word_mode, product_high);
1472 temp = expand_binop (word_mode, add_optab, temp, product_high,
1473 product_high, 0, next_methods);
1475 if (temp != 0 && temp != product_high)
1476 emit_move_insn (product_high, temp);
1479 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1480 NULL_RTX, 0, OPTAB_DIRECT);
1483 temp = expand_binop (word_mode, add_optab, temp,
1484 product_high, product_high,
1487 if (temp != 0 && temp != product_high)
1488 emit_move_insn (product_high, temp);
1490 emit_move_insn (operand_subword (product, high, 1, mode), product_high);
1494 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1496 temp = emit_move_insn (product, product);
1497 set_unique_reg_note (temp,
1499 gen_rtx_fmt_ee (MULT, mode,
1508 /* If we get here, we couldn't do it for some reason even though we
1509 originally thought we could. Delete anything we've emitted in
1512 delete_insns_since (last);
1515 /* Open-code the vector operations if we have no hardware support
1517 if (class == MODE_VECTOR_INT || class == MODE_VECTOR_FLOAT)
1518 return expand_vector_binop (mode, binoptab, op0, op1, target,
1519 unsignedp, methods);
1521 /* We need to open-code the complex type operations: '+, -, * and /' */
1523 /* At this point we allow operations between two similar complex
1524 numbers, and also if one of the operands is not a complex number
1525 but rather of MODE_FLOAT or MODE_INT. However, the caller
1526 must make sure that the MODE of the non-complex operand matches
1527 the SUBMODE of the complex operand. */
1529 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1531 rtx real0 = 0, imag0 = 0;
1532 rtx real1 = 0, imag1 = 0;
1533 rtx realr, imagr, res;
1538 /* Find the correct mode for the real and imaginary parts */
1539 enum machine_mode submode
1540 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1541 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1544 if (submode == BLKmode)
1548 target = gen_reg_rtx (mode);
1552 realr = gen_realpart (submode, target);
1553 imagr = gen_imagpart (submode, target);
1555 if (GET_MODE (op0) == mode)
1557 real0 = gen_realpart (submode, op0);
1558 imag0 = gen_imagpart (submode, op0);
1563 if (GET_MODE (op1) == mode)
1565 real1 = gen_realpart (submode, op1);
1566 imag1 = gen_imagpart (submode, op1);
1571 if (real0 == 0 || real1 == 0 || ! (imag0 != 0 || imag1 != 0))
1574 switch (binoptab->code)
1577 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1579 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1580 res = expand_binop (submode, binoptab, real0, real1,
1581 realr, unsignedp, methods);
1585 else if (res != realr)
1586 emit_move_insn (realr, res);
1588 if (imag0 != 0 && imag1 != 0)
1589 res = expand_binop (submode, binoptab, imag0, imag1,
1590 imagr, unsignedp, methods);
1591 else if (imag0 != 0)
1593 else if (binoptab->code == MINUS)
1594 res = expand_unop (submode,
1595 binoptab == subv_optab ? negv_optab : neg_optab,
1596 imag1, imagr, unsignedp);
1602 else if (res != imagr)
1603 emit_move_insn (imagr, res);
1609 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1611 if (imag0 != 0 && imag1 != 0)
1615 /* Don't fetch these from memory more than once. */
1616 real0 = force_reg (submode, real0);
1617 real1 = force_reg (submode, real1);
1618 imag0 = force_reg (submode, imag0);
1619 imag1 = force_reg (submode, imag1);
1621 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1622 unsignedp, methods);
1624 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1625 unsignedp, methods);
1627 if (temp1 == 0 || temp2 == 0)
1632 binoptab == smulv_optab ? subv_optab : sub_optab,
1633 temp1, temp2, realr, unsignedp, methods));
1637 else if (res != realr)
1638 emit_move_insn (realr, res);
1640 temp1 = expand_binop (submode, binoptab, real0, imag1,
1641 NULL_RTX, unsignedp, methods);
1643 temp2 = expand_binop (submode, binoptab, real1, imag0,
1644 NULL_RTX, unsignedp, methods);
1646 if (temp1 == 0 || temp2 == 0)
1651 binoptab == smulv_optab ? addv_optab : add_optab,
1652 temp1, temp2, imagr, unsignedp, methods));
1656 else if (res != imagr)
1657 emit_move_insn (imagr, res);
1663 /* Don't fetch these from memory more than once. */
1664 real0 = force_reg (submode, real0);
1665 real1 = force_reg (submode, real1);
1667 res = expand_binop (submode, binoptab, real0, real1,
1668 realr, unsignedp, methods);
1671 else if (res != realr)
1672 emit_move_insn (realr, res);
1675 res = expand_binop (submode, binoptab,
1676 real1, imag0, imagr, unsignedp, methods);
1678 res = expand_binop (submode, binoptab,
1679 real0, imag1, imagr, unsignedp, methods);
1683 else if (res != imagr)
1684 emit_move_insn (imagr, res);
1691 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1695 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1697 /* Don't fetch these from memory more than once. */
1698 real1 = force_reg (submode, real1);
1700 /* Simply divide the real and imaginary parts by `c' */
1701 if (class == MODE_COMPLEX_FLOAT)
1702 res = expand_binop (submode, binoptab, real0, real1,
1703 realr, unsignedp, methods);
1705 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1706 real0, real1, realr, unsignedp);
1710 else if (res != realr)
1711 emit_move_insn (realr, res);
1713 if (class == MODE_COMPLEX_FLOAT)
1714 res = expand_binop (submode, binoptab, imag0, real1,
1715 imagr, unsignedp, methods);
1717 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1718 imag0, real1, imagr, unsignedp);
1722 else if (res != imagr)
1723 emit_move_insn (imagr, res);
1729 switch (flag_complex_divide_method)
1732 ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
1733 realr, imagr, submode,
1739 ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
1740 realr, imagr, submode,
1760 if (binoptab->code != UNKNOWN)
1762 = gen_rtx_fmt_ee (binoptab->code, mode,
1763 copy_rtx (op0), copy_rtx (op1));
1767 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1773 /* It can't be open-coded in this mode.
1774 Use a library call if one is available and caller says that's ok. */
1776 if (binoptab->handlers[(int) mode].libfunc
1777 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1781 enum machine_mode op1_mode = mode;
1788 op1_mode = word_mode;
1789 /* Specify unsigned here,
1790 since negative shift counts are meaningless. */
1791 op1x = convert_to_mode (word_mode, op1, 1);
1794 if (GET_MODE (op0) != VOIDmode
1795 && GET_MODE (op0) != mode)
1796 op0 = convert_to_mode (mode, op0, unsignedp);
1798 /* Pass 1 for NO_QUEUE so we don't lose any increments
1799 if the libcall is cse'd or moved. */
1800 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1801 NULL_RTX, LCT_CONST, mode, 2,
1802 op0, mode, op1x, op1_mode);
1804 insns = get_insns ();
1807 target = gen_reg_rtx (mode);
1808 emit_libcall_block (insns, target, value,
1809 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1814 delete_insns_since (last);
1816 /* It can't be done in this mode. Can we do it in a wider mode? */
1818 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1819 || methods == OPTAB_MUST_WIDEN))
1821 /* Caller says, don't even try. */
1822 delete_insns_since (entry_last);
1826 /* Compute the value of METHODS to pass to recursive calls.
1827 Don't allow widening to be tried recursively. */
1829 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1831 /* Look for a wider mode of the same class for which it appears we can do
1834 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1836 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1837 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1839 if ((binoptab->handlers[(int) wider_mode].insn_code
1840 != CODE_FOR_nothing)
1841 || (methods == OPTAB_LIB
1842 && binoptab->handlers[(int) wider_mode].libfunc))
1844 rtx xop0 = op0, xop1 = op1;
1847 /* For certain integer operations, we need not actually extend
1848 the narrow operands, as long as we will truncate
1849 the results to the same narrowness. */
1851 if ((binoptab == ior_optab || binoptab == and_optab
1852 || binoptab == xor_optab
1853 || binoptab == add_optab || binoptab == sub_optab
1854 || binoptab == smul_optab || binoptab == ashl_optab)
1855 && class == MODE_INT)
1858 xop0 = widen_operand (xop0, wider_mode, mode,
1859 unsignedp, no_extend);
1861 /* The second operand of a shift must always be extended. */
1862 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1863 no_extend && binoptab != ashl_optab);
1865 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1866 unsignedp, methods);
1869 if (class != MODE_INT)
1872 target = gen_reg_rtx (mode);
1873 convert_move (target, temp, 0);
1877 return gen_lowpart (mode, temp);
1880 delete_insns_since (last);
1885 delete_insns_since (entry_last);
1889 /* Like expand_binop, but for open-coding vectors binops. */
1892 expand_vector_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
1893 enum machine_mode mode;
1898 enum optab_methods methods;
1900 enum machine_mode submode, tmode;
1901 int size, elts, subsize, subbitsize, i;
1902 rtx t, a, b, res, seq;
1903 enum mode_class class;
1905 class = GET_MODE_CLASS (mode);
1907 size = GET_MODE_SIZE (mode);
1908 submode = GET_MODE_INNER (mode);
1910 /* Search for the widest vector mode with the same inner mode that is
1911 still narrower than MODE and that allows to open-code this operator.
1912 Note, if we find such a mode and the handler later decides it can't
1913 do the expansion, we'll be called recursively with the narrower mode. */
1914 for (tmode = GET_CLASS_NARROWEST_MODE (class);
1915 GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode);
1916 tmode = GET_MODE_WIDER_MODE (tmode))
1918 if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode)
1919 && binoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing)
1923 switch (binoptab->code)
1928 tmode = int_mode_for_mode (mode);
1929 if (tmode != BLKmode)
1935 subsize = GET_MODE_SIZE (submode);
1936 subbitsize = GET_MODE_BITSIZE (submode);
1937 elts = size / subsize;
1939 /* If METHODS is OPTAB_DIRECT, we don't insist on the exact mode,
1940 but that we operate on more than one element at a time. */
1941 if (subsize == GET_MODE_UNIT_SIZE (mode) && methods == OPTAB_DIRECT)
1946 /* Errors can leave us with a const0_rtx as operand. */
1947 if (GET_MODE (op0) != mode)
1948 op0 = copy_to_mode_reg (mode, op0);
1949 if (GET_MODE (op1) != mode)
1950 op1 = copy_to_mode_reg (mode, op1);
1953 target = gen_reg_rtx (mode);
1955 for (i = 0; i < elts; ++i)
1957 /* If this is part of a register, and not the first item in the
1958 word, we can't store using a SUBREG - that would clobber
1960 And storing with a SUBREG is only possible for the least
1961 significant part, hence we can't do it for big endian
1962 (unless we want to permute the evaluation order. */
1963 if (GET_CODE (target) == REG
1964 && (BYTES_BIG_ENDIAN
1965 ? subsize < UNITS_PER_WORD
1966 : ((i * subsize) % UNITS_PER_WORD) != 0))
1969 t = simplify_gen_subreg (submode, target, mode, i * subsize);
1970 if (CONSTANT_P (op0))
1971 a = simplify_gen_subreg (submode, op0, mode, i * subsize);
1973 a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp,
1974 NULL_RTX, submode, submode, size);
1975 if (CONSTANT_P (op1))
1976 b = simplify_gen_subreg (submode, op1, mode, i * subsize);
1978 b = extract_bit_field (op1, subbitsize, i * subbitsize, unsignedp,
1979 NULL_RTX, submode, submode, size);
1981 if (binoptab->code == DIV)
1983 if (class == MODE_VECTOR_FLOAT)
1984 res = expand_binop (submode, binoptab, a, b, t,
1985 unsignedp, methods);
1987 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1988 a, b, t, unsignedp);
1991 res = expand_binop (submode, binoptab, a, b, t,
1992 unsignedp, methods);
1998 emit_move_insn (t, res);
2000 store_bit_field (target, subbitsize, i * subbitsize, submode, res,
2016 /* Like expand_unop but for open-coding vector unops. */
2019 expand_vector_unop (mode, unoptab, op0, target, unsignedp)
2020 enum machine_mode mode;
2026 enum machine_mode submode, tmode;
2027 int size, elts, subsize, subbitsize, i;
2030 size = GET_MODE_SIZE (mode);
2031 submode = GET_MODE_INNER (mode);
2033 /* Search for the widest vector mode with the same inner mode that is
2034 still narrower than MODE and that allows to open-code this operator.
2035 Note, if we find such a mode and the handler later decides it can't
2036 do the expansion, we'll be called recursively with the narrower mode. */
2037 for (tmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (mode));
2038 GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode);
2039 tmode = GET_MODE_WIDER_MODE (tmode))
2041 if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode)
2042 && unoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing)
2045 /* If there is no negate operation, try doing a subtract from zero. */
2046 if (unoptab == neg_optab && GET_MODE_CLASS (submode) == MODE_INT
2047 /* Avoid infinite recursion when an
2048 error has left us with the wrong mode. */
2049 && GET_MODE (op0) == mode)
2052 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2053 target, unsignedp, OPTAB_DIRECT);
2058 if (unoptab == one_cmpl_optab)
2060 tmode = int_mode_for_mode (mode);
2061 if (tmode != BLKmode)
2065 subsize = GET_MODE_SIZE (submode);
2066 subbitsize = GET_MODE_BITSIZE (submode);
2067 elts = size / subsize;
2069 /* Errors can leave us with a const0_rtx as operand. */
2070 if (GET_MODE (op0) != mode)
2071 op0 = copy_to_mode_reg (mode, op0);
2074 target = gen_reg_rtx (mode);
2078 for (i = 0; i < elts; ++i)
2080 /* If this is part of a register, and not the first item in the
2081 word, we can't store using a SUBREG - that would clobber
2083 And storing with a SUBREG is only possible for the least
2084 significant part, hence we can't do it for big endian
2085 (unless we want to permute the evaluation order. */
2086 if (GET_CODE (target) == REG
2087 && (BYTES_BIG_ENDIAN
2088 ? subsize < UNITS_PER_WORD
2089 : ((i * subsize) % UNITS_PER_WORD) != 0))
2092 t = simplify_gen_subreg (submode, target, mode, i * subsize);
2093 if (CONSTANT_P (op0))
2094 a = simplify_gen_subreg (submode, op0, mode, i * subsize);
2096 a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp,
2097 t, submode, submode, size);
2099 res = expand_unop (submode, unoptab, a, t, unsignedp);
2102 emit_move_insn (t, res);
2104 store_bit_field (target, subbitsize, i * subbitsize, submode, res,
2115 /* Expand a binary operator which has both signed and unsigned forms.
2116 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2119 If we widen unsigned operands, we may use a signed wider operation instead
2120 of an unsigned wider operation, since the result would be the same. */
2123 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
2124 enum machine_mode mode;
2125 optab uoptab, soptab;
2126 rtx op0, op1, target;
2128 enum optab_methods methods;
2131 optab direct_optab = unsignedp ? uoptab : soptab;
2132 struct optab wide_soptab;
2134 /* Do it without widening, if possible. */
2135 temp = expand_binop (mode, direct_optab, op0, op1, target,
2136 unsignedp, OPTAB_DIRECT);
2137 if (temp || methods == OPTAB_DIRECT)
2140 /* Try widening to a signed int. Make a fake signed optab that
2141 hides any signed insn for direct use. */
2142 wide_soptab = *soptab;
2143 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
2144 wide_soptab.handlers[(int) mode].libfunc = 0;
2146 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2147 unsignedp, OPTAB_WIDEN);
2149 /* For unsigned operands, try widening to an unsigned int. */
2150 if (temp == 0 && unsignedp)
2151 temp = expand_binop (mode, uoptab, op0, op1, target,
2152 unsignedp, OPTAB_WIDEN);
2153 if (temp || methods == OPTAB_WIDEN)
2156 /* Use the right width lib call if that exists. */
2157 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
2158 if (temp || methods == OPTAB_LIB)
2161 /* Must widen and use a lib call, use either signed or unsigned. */
2162 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2163 unsignedp, methods);
2167 return expand_binop (mode, uoptab, op0, op1, target,
2168 unsignedp, methods);
2172 /* Generate code to perform an operation specified by BINOPTAB
2173 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2174 We assume that the order of the operands for the instruction
2175 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2176 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2178 Either TARG0 or TARG1 may be zero, but what that means is that
2179 the result is not actually wanted. We will generate it into
2180 a dummy pseudo-reg and discard it. They may not both be zero.
2182 Returns 1 if this operation can be performed; 0 if not. */
2185 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
2191 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2192 enum mode_class class;
2193 enum machine_mode wider_mode;
2194 rtx entry_last = get_last_insn ();
2197 class = GET_MODE_CLASS (mode);
2199 op0 = protect_from_queue (op0, 0);
2200 op1 = protect_from_queue (op1, 0);
2204 op0 = force_not_mem (op0);
2205 op1 = force_not_mem (op1);
2208 /* If we are inside an appropriately-short loop and one operand is an
2209 expensive constant, force it into a register. */
2210 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
2211 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
2212 op0 = force_reg (mode, op0);
2214 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
2215 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
2216 op1 = force_reg (mode, op1);
2219 targ0 = protect_from_queue (targ0, 1);
2221 targ0 = gen_reg_rtx (mode);
2223 targ1 = protect_from_queue (targ1, 1);
2225 targ1 = gen_reg_rtx (mode);
2227 /* Record where to go back to if we fail. */
2228 last = get_last_insn ();
2230 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2232 int icode = (int) binoptab->handlers[(int) mode].insn_code;
2233 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2234 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2236 rtx xop0 = op0, xop1 = op1;
2238 /* In case this insn wants input operands in modes different from the
2239 result, convert the operands. */
2240 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
2241 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2243 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
2244 xop1 = convert_to_mode (mode1, xop1, unsignedp);
2246 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2247 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2248 xop0 = copy_to_mode_reg (mode0, xop0);
2250 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
2251 xop1 = copy_to_mode_reg (mode1, xop1);
2253 /* We could handle this, but we should always be called with a pseudo
2254 for our targets and all insns should take them as outputs. */
2255 if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
2256 || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
2259 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2266 delete_insns_since (last);
2269 /* It can't be done in this mode. Can we do it in a wider mode? */
2271 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2273 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2274 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2276 if (binoptab->handlers[(int) wider_mode].insn_code
2277 != CODE_FOR_nothing)
2279 rtx t0 = gen_reg_rtx (wider_mode);
2280 rtx t1 = gen_reg_rtx (wider_mode);
2281 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2282 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2284 if (expand_twoval_binop (binoptab, cop0, cop1,
2287 convert_move (targ0, t0, unsignedp);
2288 convert_move (targ1, t1, unsignedp);
2292 delete_insns_since (last);
2297 delete_insns_since (entry_last);
2301 /* Wrapper around expand_unop which takes an rtx code to specify
2302 the operation to perform, not an optab pointer. All other
2303 arguments are the same. */
2305 expand_simple_unop (mode, code, op0, target, unsignedp)
2306 enum machine_mode mode;
2312 optab unop = code_to_optab [(int) code];
2316 return expand_unop (mode, unop, op0, target, unsignedp);
2319 /* Generate code to perform an operation specified by UNOPTAB
2320 on operand OP0, with result having machine-mode MODE.
2322 UNSIGNEDP is for the case where we have to widen the operands
2323 to perform the operation. It says to use zero-extension.
2325 If TARGET is nonzero, the value
2326 is generated there, if it is convenient to do so.
2327 In all cases an rtx is returned for the locus of the value;
2328 this may or may not be TARGET. */
2331 expand_unop (mode, unoptab, op0, target, unsignedp)
2332 enum machine_mode mode;
2338 enum mode_class class;
2339 enum machine_mode wider_mode;
2341 rtx last = get_last_insn ();
2344 class = GET_MODE_CLASS (mode);
2346 op0 = protect_from_queue (op0, 0);
2350 op0 = force_not_mem (op0);
2354 target = protect_from_queue (target, 1);
2356 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2358 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2359 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2365 temp = gen_reg_rtx (mode);
2367 if (GET_MODE (xop0) != VOIDmode
2368 && GET_MODE (xop0) != mode0)
2369 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2371 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2373 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2374 xop0 = copy_to_mode_reg (mode0, xop0);
2376 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
2377 temp = gen_reg_rtx (mode);
2379 pat = GEN_FCN (icode) (temp, xop0);
2382 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2383 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2385 delete_insns_since (last);
2386 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2394 delete_insns_since (last);
2397 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2399 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2400 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2401 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2403 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2407 /* For certain operations, we need not actually extend
2408 the narrow operand, as long as we will truncate the
2409 results to the same narrowness. */
2411 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2412 (unoptab == neg_optab
2413 || unoptab == one_cmpl_optab)
2414 && class == MODE_INT);
2416 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2421 if (class != MODE_INT)
2424 target = gen_reg_rtx (mode);
2425 convert_move (target, temp, 0);
2429 return gen_lowpart (mode, temp);
2432 delete_insns_since (last);
2436 /* These can be done a word at a time. */
2437 if (unoptab == one_cmpl_optab
2438 && class == MODE_INT
2439 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2440 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2445 if (target == 0 || target == op0)
2446 target = gen_reg_rtx (mode);
2450 /* Do the actual arithmetic. */
2451 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2453 rtx target_piece = operand_subword (target, i, 1, mode);
2454 rtx x = expand_unop (word_mode, unoptab,
2455 operand_subword_force (op0, i, mode),
2456 target_piece, unsignedp);
2458 if (target_piece != x)
2459 emit_move_insn (target_piece, x);
2462 insns = get_insns ();
2465 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2466 gen_rtx_fmt_e (unoptab->code, mode,
2471 /* Open-code the complex negation operation. */
2472 else if (unoptab->code == NEG
2473 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2479 /* Find the correct mode for the real and imaginary parts */
2480 enum machine_mode submode
2481 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2482 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2485 if (submode == BLKmode)
2489 target = gen_reg_rtx (mode);
2493 target_piece = gen_imagpart (submode, target);
2494 x = expand_unop (submode, unoptab,
2495 gen_imagpart (submode, op0),
2496 target_piece, unsignedp);
2497 if (target_piece != x)
2498 emit_move_insn (target_piece, x);
2500 target_piece = gen_realpart (submode, target);
2501 x = expand_unop (submode, unoptab,
2502 gen_realpart (submode, op0),
2503 target_piece, unsignedp);
2504 if (target_piece != x)
2505 emit_move_insn (target_piece, x);
2510 emit_no_conflict_block (seq, target, op0, 0,
2511 gen_rtx_fmt_e (unoptab->code, mode,
2516 /* Now try a library call in this mode. */
2517 if (unoptab->handlers[(int) mode].libfunc)
2524 /* Pass 1 for NO_QUEUE so we don't lose any increments
2525 if the libcall is cse'd or moved. */
2526 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2527 NULL_RTX, LCT_CONST, mode, 1, op0, mode);
2528 insns = get_insns ();
2531 target = gen_reg_rtx (mode);
2532 emit_libcall_block (insns, target, value,
2533 gen_rtx_fmt_e (unoptab->code, mode, op0));
2538 if (class == MODE_VECTOR_FLOAT || class == MODE_VECTOR_INT)
2539 return expand_vector_unop (mode, unoptab, op0, target, unsignedp);
2541 /* It can't be done in this mode. Can we do it in a wider mode? */
2543 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2545 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2546 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2548 if ((unoptab->handlers[(int) wider_mode].insn_code
2549 != CODE_FOR_nothing)
2550 || unoptab->handlers[(int) wider_mode].libfunc)
2554 /* For certain operations, we need not actually extend
2555 the narrow operand, as long as we will truncate the
2556 results to the same narrowness. */
2558 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2559 (unoptab == neg_optab
2560 || unoptab == one_cmpl_optab)
2561 && class == MODE_INT);
2563 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2568 if (class != MODE_INT)
2571 target = gen_reg_rtx (mode);
2572 convert_move (target, temp, 0);
2576 return gen_lowpart (mode, temp);
2579 delete_insns_since (last);
2584 /* If there is no negate operation, try doing a subtract from zero.
2585 The US Software GOFAST library needs this. */
2586 if (unoptab->code == NEG)
2589 temp = expand_binop (mode,
2590 unoptab == negv_optab ? subv_optab : sub_optab,
2591 CONST0_RTX (mode), op0,
2592 target, unsignedp, OPTAB_LIB_WIDEN);
2600 /* Emit code to compute the absolute value of OP0, with result to
2601 TARGET if convenient. (TARGET may be 0.) The return value says
2602 where the result actually is to be found.
2604 MODE is the mode of the operand; the mode of the result is
2605 different but can be deduced from MODE.
2610 expand_abs (mode, op0, target, result_unsignedp, safe)
2611 enum machine_mode mode;
2614 int result_unsignedp;
2620 result_unsignedp = 1;
2622 /* First try to do it with a special abs instruction. */
2623 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2628 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2629 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2631 rtx last = get_last_insn ();
2633 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2635 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2641 delete_insns_since (last);
2644 /* If this machine has expensive jumps, we can do integer absolute
2645 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2646 where W is the width of MODE. */
2648 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2650 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2651 size_int (GET_MODE_BITSIZE (mode) - 1),
2654 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2657 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2658 temp, extended, target, 0, OPTAB_LIB_WIDEN);
2664 /* If that does not win, use conditional jump and negate. */
2666 /* It is safe to use the target if it is the same
2667 as the source if this is also a pseudo register */
2668 if (op0 == target && GET_CODE (op0) == REG
2669 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2672 op1 = gen_label_rtx ();
2673 if (target == 0 || ! safe
2674 || GET_MODE (target) != mode
2675 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2676 || (GET_CODE (target) == REG
2677 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2678 target = gen_reg_rtx (mode);
2680 emit_move_insn (target, op0);
2683 /* If this mode is an integer too wide to compare properly,
2684 compare word by word. Rely on CSE to optimize constant cases. */
2685 if (GET_MODE_CLASS (mode) == MODE_INT
2686 && ! can_compare_p (GE, mode, ccp_jump))
2687 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2690 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2691 NULL_RTX, NULL_RTX, op1);
2693 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2696 emit_move_insn (target, op0);
2702 /* Emit code to compute the absolute value of OP0, with result to
2703 TARGET if convenient. (TARGET may be 0.) The return value says
2704 where the result actually is to be found.
2706 MODE is the mode of the operand; the mode of the result is
2707 different but can be deduced from MODE.
2709 UNSIGNEDP is relevant for complex integer modes. */
2712 expand_complex_abs (mode, op0, target, unsignedp)
2713 enum machine_mode mode;
2718 enum mode_class class = GET_MODE_CLASS (mode);
2719 enum machine_mode wider_mode;
2721 rtx entry_last = get_last_insn ();
2724 optab this_abs_optab;
2726 /* Find the correct mode for the real and imaginary parts. */
2727 enum machine_mode submode
2728 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2729 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2732 if (submode == BLKmode)
2735 op0 = protect_from_queue (op0, 0);
2739 op0 = force_not_mem (op0);
2742 last = get_last_insn ();
2745 target = protect_from_queue (target, 1);
2747 this_abs_optab = ! unsignedp && flag_trapv
2748 && (GET_MODE_CLASS(mode) == MODE_INT)
2749 ? absv_optab : abs_optab;
2751 if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2753 int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
2754 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2760 temp = gen_reg_rtx (submode);
2762 if (GET_MODE (xop0) != VOIDmode
2763 && GET_MODE (xop0) != mode0)
2764 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2766 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2768 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2769 xop0 = copy_to_mode_reg (mode0, xop0);
2771 if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
2772 temp = gen_reg_rtx (submode);
2774 pat = GEN_FCN (icode) (temp, xop0);
2777 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2778 && ! add_equal_note (pat, temp, this_abs_optab->code, xop0,
2781 delete_insns_since (last);
2782 return expand_unop (mode, this_abs_optab, op0, NULL_RTX,
2791 delete_insns_since (last);
2794 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2796 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2797 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2799 if (this_abs_optab->handlers[(int) wider_mode].insn_code
2800 != CODE_FOR_nothing)
2804 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2805 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2809 if (class != MODE_COMPLEX_INT)
2812 target = gen_reg_rtx (submode);
2813 convert_move (target, temp, 0);
2817 return gen_lowpart (submode, temp);
2820 delete_insns_since (last);
2824 /* Open-code the complex absolute-value operation
2825 if we can open-code sqrt. Otherwise it's not worth while. */
2826 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
2829 rtx real, imag, total;
2831 real = gen_realpart (submode, op0);
2832 imag = gen_imagpart (submode, op0);
2834 /* Square both parts. */
2835 real = expand_mult (submode, real, real, NULL_RTX, 0);
2836 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2838 /* Sum the parts. */
2839 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2840 0, OPTAB_LIB_WIDEN);
2842 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2843 target = expand_unop (submode, sqrt_optab, total, target, 0);
2845 delete_insns_since (last);
2850 /* Now try a library call in this mode. */
2851 if (this_abs_optab->handlers[(int) mode].libfunc)
2858 /* Pass 1 for NO_QUEUE so we don't lose any increments
2859 if the libcall is cse'd or moved. */
2860 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2861 NULL_RTX, LCT_CONST, submode, 1, op0, mode);
2862 insns = get_insns ();
2865 target = gen_reg_rtx (submode);
2866 emit_libcall_block (insns, target, value,
2867 gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
2872 /* It can't be done in this mode. Can we do it in a wider mode? */
2874 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2875 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2877 if ((this_abs_optab->handlers[(int) wider_mode].insn_code
2878 != CODE_FOR_nothing)
2879 || this_abs_optab->handlers[(int) wider_mode].libfunc)
2883 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2885 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2889 if (class != MODE_COMPLEX_INT)
2892 target = gen_reg_rtx (submode);
2893 convert_move (target, temp, 0);
2897 return gen_lowpart (submode, temp);
2900 delete_insns_since (last);
2904 delete_insns_since (entry_last);
2908 /* Generate an instruction whose insn-code is INSN_CODE,
2909 with two operands: an output TARGET and an input OP0.
2910 TARGET *must* be nonzero, and the output is always stored there.
2911 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2912 the value that is stored into TARGET. */
2915 emit_unop_insn (icode, target, op0, code)
2922 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2925 temp = target = protect_from_queue (target, 1);
2927 op0 = protect_from_queue (op0, 0);
2929 /* Sign and zero extension from memory is often done specially on
2930 RISC machines, so forcing into a register here can pessimize
2932 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2933 op0 = force_not_mem (op0);
2935 /* Now, if insn does not accept our operands, put them into pseudos. */
2937 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2938 op0 = copy_to_mode_reg (mode0, op0);
2940 if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
2941 || (flag_force_mem && GET_CODE (temp) == MEM))
2942 temp = gen_reg_rtx (GET_MODE (temp));
2944 pat = GEN_FCN (icode) (temp, op0);
2946 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
2947 add_equal_note (pat, temp, code, op0, NULL_RTX);
2952 emit_move_insn (target, temp);
2955 /* Emit code to perform a series of operations on a multi-word quantity, one
2958 Such a block is preceded by a CLOBBER of the output, consists of multiple
2959 insns, each setting one word of the output, and followed by a SET copying
2960 the output to itself.
2962 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2963 note indicating that it doesn't conflict with the (also multi-word)
2964 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2967 INSNS is a block of code generated to perform the operation, not including
2968 the CLOBBER and final copy. All insns that compute intermediate values
2969 are first emitted, followed by the block as described above.
2971 TARGET, OP0, and OP1 are the output and inputs of the operations,
2972 respectively. OP1 may be zero for a unary operation.
2974 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2977 If TARGET is not a register, INSNS is simply emitted with no special
2978 processing. Likewise if anything in INSNS is not an INSN or if
2979 there is a libcall block inside INSNS.
2981 The final insn emitted is returned. */
2984 emit_no_conflict_block (insns, target, op0, op1, equiv)
2990 rtx prev, next, first, last, insn;
2992 if (GET_CODE (target) != REG || reload_in_progress)
2993 return emit_insn (insns);
2995 for (insn = insns; insn; insn = NEXT_INSN (insn))
2996 if (GET_CODE (insn) != INSN
2997 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2998 return emit_insn (insns);
3000 /* First emit all insns that do not store into words of the output and remove
3001 these from the list. */
3002 for (insn = insns; insn; insn = next)
3007 next = NEXT_INSN (insn);
3009 /* Some ports (cris) create an libcall regions at their own. We must
3010 avoid any potential nesting of LIBCALLs. */
3011 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3012 remove_note (insn, note);
3013 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3014 remove_note (insn, note);
3016 if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
3017 || GET_CODE (PATTERN (insn)) == CLOBBER)
3018 set = PATTERN (insn);
3019 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
3021 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
3022 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
3024 set = XVECEXP (PATTERN (insn), 0, i);
3032 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
3034 if (PREV_INSN (insn))
3035 NEXT_INSN (PREV_INSN (insn)) = next;
3040 PREV_INSN (next) = PREV_INSN (insn);
3046 prev = get_last_insn ();
3048 /* Now write the CLOBBER of the output, followed by the setting of each
3049 of the words, followed by the final copy. */
3050 if (target != op0 && target != op1)
3051 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3053 for (insn = insns; insn; insn = next)
3055 next = NEXT_INSN (insn);
3058 if (op1 && GET_CODE (op1) == REG)
3059 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3062 if (op0 && GET_CODE (op0) == REG)
3063 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3067 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3068 != CODE_FOR_nothing)
3070 last = emit_move_insn (target, target);
3072 set_unique_reg_note (last, REG_EQUAL, equiv);
3076 last = get_last_insn ();
3078 /* Remove any existing REG_EQUAL note from "last", or else it will
3079 be mistaken for a note referring to the full contents of the
3080 alleged libcall value when found together with the REG_RETVAL
3081 note added below. An existing note can come from an insn
3082 expansion at "last". */
3083 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3087 first = get_insns ();
3089 first = NEXT_INSN (prev);
3091 /* Encapsulate the block so it gets manipulated as a unit. */
3092 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3094 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3099 /* Emit code to make a call to a constant function or a library call.
3101 INSNS is a list containing all insns emitted in the call.
3102 These insns leave the result in RESULT. Our block is to copy RESULT
3103 to TARGET, which is logically equivalent to EQUIV.
3105 We first emit any insns that set a pseudo on the assumption that these are
3106 loading constants into registers; doing so allows them to be safely cse'ed
3107 between blocks. Then we emit all the other insns in the block, followed by
3108 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3109 note with an operand of EQUIV.
3111 Moving assignments to pseudos outside of the block is done to improve
3112 the generated code, but is not required to generate correct code,
3113 hence being unable to move an assignment is not grounds for not making
3114 a libcall block. There are two reasons why it is safe to leave these
3115 insns inside the block: First, we know that these pseudos cannot be
3116 used in generated RTL outside the block since they are created for
3117 temporary purposes within the block. Second, CSE will not record the
3118 values of anything set inside a libcall block, so we know they must
3119 be dead at the end of the block.
3121 Except for the first group of insns (the ones setting pseudos), the
3122 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
3125 emit_libcall_block (insns, target, result, equiv)
3131 rtx final_dest = target;
3132 rtx prev, next, first, last, insn;
3134 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3135 into a MEM later. Protect the libcall block from this change. */
3136 if (! REG_P (target) || REG_USERVAR_P (target))
3137 target = gen_reg_rtx (GET_MODE (target));
3139 /* If we're using non-call exceptions, a libcall corresponding to an
3140 operation that may trap may also trap. */
3141 if (flag_non_call_exceptions && may_trap_p (equiv))
3143 for (insn = insns; insn; insn = NEXT_INSN (insn))
3144 if (GET_CODE (insn) == CALL_INSN)
3146 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3148 if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3149 remove_note (insn, note);
3153 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3154 reg note to indicate that this call cannot throw or execute a nonlocal
3155 goto (unless there is already a REG_EH_REGION note, in which case
3157 for (insn = insns; insn; insn = NEXT_INSN (insn))
3158 if (GET_CODE (insn) == CALL_INSN)
3160 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3163 XEXP (note, 0) = GEN_INT (-1);
3165 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
3169 /* First emit all insns that set pseudos. Remove them from the list as
3170 we go. Avoid insns that set pseudos which were referenced in previous
3171 insns. These can be generated by move_by_pieces, for example,
3172 to update an address. Similarly, avoid insns that reference things
3173 set in previous insns. */
3175 for (insn = insns; insn; insn = next)
3177 rtx set = single_set (insn);
3180 /* Some ports (cris) create an libcall regions at their own. We must
3181 avoid any potential nesting of LIBCALLs. */
3182 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3183 remove_note (insn, note);
3184 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3185 remove_note (insn, note);
3187 next = NEXT_INSN (insn);
3189 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
3190 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
3192 || ((! INSN_P(insns)
3193 || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
3194 && ! reg_used_between_p (SET_DEST (set), insns, insn)
3195 && ! modified_in_p (SET_SRC (set), insns)
3196 && ! modified_between_p (SET_SRC (set), insns, insn))))
3198 if (PREV_INSN (insn))
3199 NEXT_INSN (PREV_INSN (insn)) = next;
3204 PREV_INSN (next) = PREV_INSN (insn);
3210 prev = get_last_insn ();
3212 /* Write the remaining insns followed by the final copy. */
3214 for (insn = insns; insn; insn = next)
3216 next = NEXT_INSN (insn);
3221 last = emit_move_insn (target, result);
3222 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3223 != CODE_FOR_nothing)
3224 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3227 /* Remove any existing REG_EQUAL note from "last", or else it will
3228 be mistaken for a note referring to the full contents of the
3229 libcall value when found together with the REG_RETVAL note added
3230 below. An existing note can come from an insn expansion at
3232 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3235 if (final_dest != target)
3236 emit_move_insn (final_dest, target);
3239 first = get_insns ();
3241 first = NEXT_INSN (prev);
3243 /* Encapsulate the block so it gets manipulated as a unit. */
3244 if (!flag_non_call_exceptions || !may_trap_p (equiv))
3246 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3248 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3253 /* Generate code to store zero in X. */
3259 emit_move_insn (x, const0_rtx);
3262 /* Generate code to store 1 in X
3263 assuming it contains zero beforehand. */
3266 emit_0_to_1_insn (x)
3269 emit_move_insn (x, const1_rtx);
3272 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3273 PURPOSE describes how this comparison will be used. CODE is the rtx
3274 comparison code we will be using.
3276 ??? Actually, CODE is slightly weaker than that. A target is still
3277 required to implement all of the normal bcc operations, but not
3278 required to implement all (or any) of the unordered bcc operations. */
3281 can_compare_p (code, mode, purpose)
3283 enum machine_mode mode;
3284 enum can_compare_purpose purpose;
3288 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3290 if (purpose == ccp_jump)
3291 return bcc_gen_fctn[(int)code] != NULL;
3292 else if (purpose == ccp_store_flag)
3293 return setcc_gen_code[(int)code] != CODE_FOR_nothing;
3295 /* There's only one cmov entry point, and it's allowed to fail. */
3298 if (purpose == ccp_jump
3299 && cbranch_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3301 if (purpose == ccp_cmov
3302 && cmov_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3304 if (purpose == ccp_store_flag
3305 && cstore_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3308 mode = GET_MODE_WIDER_MODE (mode);
3310 while (mode != VOIDmode);
3315 /* This function is called when we are going to emit a compare instruction that
3316 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3318 *PMODE is the mode of the inputs (in case they are const_int).
3319 *PUNSIGNEDP nonzero says that the operands are unsigned;
3320 this matters if they need to be widened.
3322 If they have mode BLKmode, then SIZE specifies the size of both operands.
3324 This function performs all the setup necessary so that the caller only has
3325 to emit a single comparison insn. This setup can involve doing a BLKmode
3326 comparison or emitting a library call to perform the comparison if no insn
3327 is available to handle it.
3328 The values which are passed in through pointers can be modified; the caller
3329 should perform the comparison on the modified values. */
3332 prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose)
3334 enum rtx_code *pcomparison;
3336 enum machine_mode *pmode;
3338 enum can_compare_purpose purpose;
3340 enum machine_mode mode = *pmode;
3341 rtx x = *px, y = *py;
3342 int unsignedp = *punsignedp;
3343 enum mode_class class;
3345 class = GET_MODE_CLASS (mode);
3347 /* They could both be VOIDmode if both args are immediate constants,
3348 but we should fold that at an earlier stage.
3349 With no special code here, this will call abort,
3350 reminding the programmer to implement such folding. */
3352 if (mode != BLKmode && flag_force_mem)
3354 x = force_not_mem (x);
3355 y = force_not_mem (y);
3358 /* If we are inside an appropriately-short loop and one operand is an
3359 expensive constant, force it into a register. */
3360 if (CONSTANT_P (x) && preserve_subexpressions_p ()
3361 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3362 x = force_reg (mode, x);
3364 if (CONSTANT_P (y) && preserve_subexpressions_p ()
3365 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3366 y = force_reg (mode, y);
3369 /* Abort if we have a non-canonical comparison. The RTL documentation
3370 states that canonical comparisons are required only for targets which
3372 if (CONSTANT_P (x) && ! CONSTANT_P (y))
3376 /* Don't let both operands fail to indicate the mode. */
3377 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3378 x = force_reg (mode, x);
3380 /* Handle all BLKmode compares. */
3382 if (mode == BLKmode)
3385 enum machine_mode result_mode;
3386 rtx opalign ATTRIBUTE_UNUSED
3387 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3390 x = protect_from_queue (x, 0);
3391 y = protect_from_queue (y, 0);
3395 #ifdef HAVE_cmpstrqi
3397 && GET_CODE (size) == CONST_INT
3398 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3400 result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
3401 result = gen_reg_rtx (result_mode);
3402 emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
3406 #ifdef HAVE_cmpstrhi
3408 && GET_CODE (size) == CONST_INT
3409 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3411 result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
3412 result = gen_reg_rtx (result_mode);
3413 emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
3417 #ifdef HAVE_cmpstrsi
3420 result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3421 result = gen_reg_rtx (result_mode);
3422 size = protect_from_queue (size, 0);
3423 emit_insn (gen_cmpstrsi (result, x, y,
3424 convert_to_mode (SImode, size, 1),
3430 #ifdef TARGET_MEM_FUNCTIONS
3431 emit_library_call (memcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3432 TYPE_MODE (integer_type_node), 3,
3433 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3434 convert_to_mode (TYPE_MODE (sizetype), size,
3435 TREE_UNSIGNED (sizetype)),
3436 TYPE_MODE (sizetype));
3438 emit_library_call (bcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3439 TYPE_MODE (integer_type_node), 3,
3440 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3441 convert_to_mode (TYPE_MODE (integer_type_node),
3443 TREE_UNSIGNED (integer_type_node)),
3444 TYPE_MODE (integer_type_node));
3447 /* Immediately move the result of the libcall into a pseudo
3448 register so reload doesn't clobber the value if it needs
3449 the return register for a spill reg. */
3450 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3451 result_mode = TYPE_MODE (integer_type_node);
3452 emit_move_insn (result,
3453 hard_libcall_value (result_mode));
3457 *pmode = result_mode;
3463 if (can_compare_p (*pcomparison, mode, purpose))
3466 /* Handle a lib call just for the mode we are using. */
3468 if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3470 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3473 /* If we want unsigned, and this mode has a distinct unsigned
3474 comparison routine, use that. */
3475 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3476 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3478 emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode,
3481 /* Immediately move the result of the libcall into a pseudo
3482 register so reload doesn't clobber the value if it needs
3483 the return register for a spill reg. */
3484 result = gen_reg_rtx (word_mode);
3485 emit_move_insn (result, hard_libcall_value (word_mode));
3487 /* Integer comparison returns a result that must be compared against 1,
3488 so that even if we do an unsigned compare afterward,
3489 there is still a value that can represent the result "less than". */
3496 if (class == MODE_FLOAT)
3497 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3503 /* Before emitting an insn with code ICODE, make sure that X, which is going
3504 to be used for operand OPNUM of the insn, is converted from mode MODE to
3505 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3506 that it is accepted by the operand predicate. Return the new value. */
3509 prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
3513 enum machine_mode mode, wider_mode;
3516 x = protect_from_queue (x, 0);
3518 if (mode != wider_mode)
3519 x = convert_modes (wider_mode, mode, x, unsignedp);
3521 if (! (*insn_data[icode].operand[opnum].predicate)
3522 (x, insn_data[icode].operand[opnum].mode))
3523 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3527 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3528 we can do the comparison.
3529 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3530 be NULL_RTX which indicates that only a comparison is to be generated. */
3533 emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
3535 enum machine_mode mode;
3536 enum rtx_code comparison;
3540 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3541 enum mode_class class = GET_MODE_CLASS (mode);
3542 enum machine_mode wider_mode = mode;
3544 /* Try combined insns first. */
3547 enum insn_code icode;
3548 PUT_MODE (test, wider_mode);
3552 icode = cbranch_optab->handlers[(int)wider_mode].insn_code;
3554 if (icode != CODE_FOR_nothing
3555 && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3557 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3558 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3559 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3564 /* Handle some compares against zero. */
3565 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3566 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3568 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3569 emit_insn (GEN_FCN (icode) (x));
3571 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3575 /* Handle compares for which there is a directly suitable insn. */
3577 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3578 if (icode != CODE_FOR_nothing)
3580 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3581 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3582 emit_insn (GEN_FCN (icode) (x, y));
3584 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3588 if (class != MODE_INT && class != MODE_FLOAT
3589 && class != MODE_COMPLEX_FLOAT)
3592 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3593 } while (wider_mode != VOIDmode);
3598 /* Generate code to compare X with Y so that the condition codes are
3599 set and to jump to LABEL if the condition is true. If X is a
3600 constant and Y is not a constant, then the comparison is swapped to
3601 ensure that the comparison RTL has the canonical form.
3603 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3604 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3605 the proper branch condition code.
3607 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3609 MODE is the mode of the inputs (in case they are const_int).
3611 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3612 be passed unchanged to emit_cmp_insn, then potentially converted into an
3613 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3616 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, label)
3618 enum rtx_code comparison;
3620 enum machine_mode mode;
3624 rtx op0 = x, op1 = y;
3626 /* Swap operands and condition to ensure canonical RTL. */
3627 if (swap_commutative_operands_p (x, y))
3629 /* If we're not emitting a branch, this means some caller
3635 comparison = swap_condition (comparison);
3639 /* If OP0 is still a constant, then both X and Y must be constants. Force
3640 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3642 if (CONSTANT_P (op0))
3643 op0 = force_reg (mode, op0);
3648 comparison = unsigned_condition (comparison);
3650 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3652 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3655 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3658 emit_cmp_insn (x, y, comparison, size, mode, unsignedp)
3660 enum rtx_code comparison;
3662 enum machine_mode mode;
3665 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3668 /* Emit a library call comparison between floating point X and Y.
3669 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3672 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
3674 enum rtx_code *pcomparison;
3675 enum machine_mode *pmode;
3678 enum rtx_code comparison = *pcomparison;
3680 rtx x = *px = protect_from_queue (*px, 0);
3681 rtx y = *py = protect_from_queue (*py, 0);
3682 enum machine_mode mode = GET_MODE (x);
3690 libfunc = eqhf2_libfunc;
3694 libfunc = nehf2_libfunc;
3698 libfunc = gthf2_libfunc;
3699 if (libfunc == NULL_RTX)
3701 tmp = x; x = y; y = tmp;
3703 libfunc = lthf2_libfunc;
3708 libfunc = gehf2_libfunc;
3709 if (libfunc == NULL_RTX)
3711 tmp = x; x = y; y = tmp;
3713 libfunc = lehf2_libfunc;
3718 libfunc = lthf2_libfunc;
3719 if (libfunc == NULL_RTX)
3721 tmp = x; x = y; y = tmp;
3723 libfunc = gthf2_libfunc;
3728 libfunc = lehf2_libfunc;
3729 if (libfunc == NULL_RTX)
3731 tmp = x; x = y; y = tmp;
3733 libfunc = gehf2_libfunc;
3738 libfunc = unordhf2_libfunc;
3744 else if (mode == SFmode)
3748 libfunc = eqsf2_libfunc;
3752 libfunc = nesf2_libfunc;
3756 libfunc = gtsf2_libfunc;
3757 if (libfunc == NULL_RTX)
3759 tmp = x; x = y; y = tmp;
3761 libfunc = ltsf2_libfunc;
3766 libfunc = gesf2_libfunc;
3767 if (libfunc == NULL_RTX)
3769 tmp = x; x = y; y = tmp;
3771 libfunc = lesf2_libfunc;
3776 libfunc = ltsf2_libfunc;
3777 if (libfunc == NULL_RTX)
3779 tmp = x; x = y; y = tmp;
3781 libfunc = gtsf2_libfunc;
3786 libfunc = lesf2_libfunc;
3787 if (libfunc == NULL_RTX)
3789 tmp = x; x = y; y = tmp;
3791 libfunc = gesf2_libfunc;
3796 libfunc = unordsf2_libfunc;
3802 else if (mode == DFmode)
3806 libfunc = eqdf2_libfunc;
3810 libfunc = nedf2_libfunc;
3814 libfunc = gtdf2_libfunc;
3815 if (libfunc == NULL_RTX)
3817 tmp = x; x = y; y = tmp;
3819 libfunc = ltdf2_libfunc;
3824 libfunc = gedf2_libfunc;
3825 if (libfunc == NULL_RTX)
3827 tmp = x; x = y; y = tmp;
3829 libfunc = ledf2_libfunc;
3834 libfunc = ltdf2_libfunc;
3835 if (libfunc == NULL_RTX)
3837 tmp = x; x = y; y = tmp;
3839 libfunc = gtdf2_libfunc;
3844 libfunc = ledf2_libfunc;
3845 if (libfunc == NULL_RTX)
3847 tmp = x; x = y; y = tmp;
3849 libfunc = gedf2_libfunc;
3854 libfunc = unorddf2_libfunc;
3860 else if (mode == XFmode)
3864 libfunc = eqxf2_libfunc;
3868 libfunc = nexf2_libfunc;
3872 libfunc = gtxf2_libfunc;
3873 if (libfunc == NULL_RTX)
3875 tmp = x; x = y; y = tmp;
3877 libfunc = ltxf2_libfunc;
3882 libfunc = gexf2_libfunc;
3883 if (libfunc == NULL_RTX)
3885 tmp = x; x = y; y = tmp;
3887 libfunc = lexf2_libfunc;
3892 libfunc = ltxf2_libfunc;
3893 if (libfunc == NULL_RTX)
3895 tmp = x; x = y; y = tmp;
3897 libfunc = gtxf2_libfunc;
3902 libfunc = lexf2_libfunc;
3903 if (libfunc == NULL_RTX)
3905 tmp = x; x = y; y = tmp;
3907 libfunc = gexf2_libfunc;
3912 libfunc = unordxf2_libfunc;
3918 else if (mode == TFmode)
3922 libfunc = eqtf2_libfunc;
3926 libfunc = netf2_libfunc;
3930 libfunc = gttf2_libfunc;
3931 if (libfunc == NULL_RTX)
3933 tmp = x; x = y; y = tmp;
3935 libfunc = lttf2_libfunc;
3940 libfunc = getf2_libfunc;
3941 if (libfunc == NULL_RTX)
3943 tmp = x; x = y; y = tmp;
3945 libfunc = letf2_libfunc;
3950 libfunc = lttf2_libfunc;
3951 if (libfunc == NULL_RTX)
3953 tmp = x; x = y; y = tmp;
3955 libfunc = gttf2_libfunc;
3960 libfunc = letf2_libfunc;
3961 if (libfunc == NULL_RTX)
3963 tmp = x; x = y; y = tmp;
3965 libfunc = getf2_libfunc;
3970 libfunc = unordtf2_libfunc;
3978 enum machine_mode wider_mode;
3980 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3981 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3983 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3984 != CODE_FOR_nothing)
3985 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3987 x = protect_from_queue (x, 0);
3988 y = protect_from_queue (y, 0);
3989 *px = convert_to_mode (wider_mode, x, 0);
3990 *py = convert_to_mode (wider_mode, y, 0);
3991 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
4001 emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode, y,
4004 /* Immediately move the result of the libcall into a pseudo
4005 register so reload doesn't clobber the value if it needs
4006 the return register for a spill reg. */
4007 result = gen_reg_rtx (word_mode);
4008 emit_move_insn (result, hard_libcall_value (word_mode));
4012 if (comparison == UNORDERED)
4014 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
4015 else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4021 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4024 emit_indirect_jump (loc)
4027 if (! ((*insn_data[(int)CODE_FOR_indirect_jump].operand[0].predicate)
4029 loc = copy_to_mode_reg (Pmode, loc);
4031 emit_jump_insn (gen_indirect_jump (loc));
4035 #ifdef HAVE_conditional_move
4037 /* Emit a conditional move instruction if the machine supports one for that
4038 condition and machine mode.
4040 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4041 the mode to use should they be constants. If it is VOIDmode, they cannot
4044 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4045 should be stored there. MODE is the mode to use should they be constants.
4046 If it is VOIDmode, they cannot both be constants.
4048 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4049 is not supported. */
4052 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
4057 enum machine_mode cmode;
4059 enum machine_mode mode;
4062 rtx tem, subtarget, comparison, insn;
4063 enum insn_code icode;
4064 enum rtx_code reversed;
4066 /* If one operand is constant, make it the second one. Only do this
4067 if the other operand is not constant as well. */
4069 if (swap_commutative_operands_p (op0, op1))
4074 code = swap_condition (code);
4077 /* get_condition will prefer to generate LT and GT even if the old
4078 comparison was against zero, so undo that canonicalization here since
4079 comparisons against zero are cheaper. */
4080 if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
4081 code = LE, op1 = const0_rtx;
4082 else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
4083 code = GE, op1 = const0_rtx;
4085 if (cmode == VOIDmode)
4086 cmode = GET_MODE (op0);
4088 if (swap_commutative_operands_p (op2, op3)
4089 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4098 if (mode == VOIDmode)
4099 mode = GET_MODE (op2);
4101 icode = movcc_gen_code[mode];
4103 if (icode == CODE_FOR_nothing)
4108 op2 = force_not_mem (op2);
4109 op3 = force_not_mem (op3);
4113 target = protect_from_queue (target, 1);
4115 target = gen_reg_rtx (mode);
4121 op2 = protect_from_queue (op2, 0);
4122 op3 = protect_from_queue (op3, 0);
4124 /* If the insn doesn't accept these operands, put them in pseudos. */
4126 if (! (*insn_data[icode].operand[0].predicate)
4127 (subtarget, insn_data[icode].operand[0].mode))
4128 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4130 if (! (*insn_data[icode].operand[2].predicate)
4131 (op2, insn_data[icode].operand[2].mode))
4132 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4134 if (! (*insn_data[icode].operand[3].predicate)
4135 (op3, insn_data[icode].operand[3].mode))
4136 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4138 /* Everything should now be in the suitable form, so emit the compare insn
4139 and then the conditional move. */
4142 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4144 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
4145 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4146 return NULL and let the caller figure out how best to deal with this
4148 if (GET_CODE (comparison) != code)
4151 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4153 /* If that failed, then give up. */
4159 if (subtarget != target)
4160 convert_move (target, subtarget, 0);
4165 /* Return non-zero if a conditional move of mode MODE is supported.
4167 This function is for combine so it can tell whether an insn that looks
4168 like a conditional move is actually supported by the hardware. If we
4169 guess wrong we lose a bit on optimization, but that's it. */
4170 /* ??? sparc64 supports conditionally moving integers values based on fp
4171 comparisons, and vice versa. How do we handle them? */
4174 can_conditionally_move_p (mode)
4175 enum machine_mode mode;
4177 if (movcc_gen_code[mode] != CODE_FOR_nothing)
4183 #endif /* HAVE_conditional_move */
4185 /* These functions generate an insn body and return it
4186 rather than emitting the insn.
4188 They do not protect from queued increments,
4189 because they may be used 1) in protect_from_queue itself
4190 and 2) in other passes where there is no queue. */
4192 /* Generate and return an insn body to add Y to X. */
4195 gen_add2_insn (x, y)
4198 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4200 if (! ((*insn_data[icode].operand[0].predicate)
4201 (x, insn_data[icode].operand[0].mode))
4202 || ! ((*insn_data[icode].operand[1].predicate)
4203 (x, insn_data[icode].operand[1].mode))
4204 || ! ((*insn_data[icode].operand[2].predicate)
4205 (y, insn_data[icode].operand[2].mode)))
4208 return (GEN_FCN (icode) (x, x, y));
4211 /* Generate and return an insn body to add r1 and c,
4212 storing the result in r0. */
4214 gen_add3_insn (r0, r1, c)
4217 int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4219 if (icode == CODE_FOR_nothing
4220 || ! ((*insn_data[icode].operand[0].predicate)
4221 (r0, insn_data[icode].operand[0].mode))
4222 || ! ((*insn_data[icode].operand[1].predicate)
4223 (r1, insn_data[icode].operand[1].mode))
4224 || ! ((*insn_data[icode].operand[2].predicate)
4225 (c, insn_data[icode].operand[2].mode)))
4228 return (GEN_FCN (icode) (r0, r1, c));
4232 have_add2_insn (x, y)
4237 if (GET_MODE (x) == VOIDmode)
4240 icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4242 if (icode == CODE_FOR_nothing)
4245 if (! ((*insn_data[icode].operand[0].predicate)
4246 (x, insn_data[icode].operand[0].mode))
4247 || ! ((*insn_data[icode].operand[1].predicate)
4248 (x, insn_data[icode].operand[1].mode))
4249 || ! ((*insn_data[icode].operand[2].predicate)
4250 (y, insn_data[icode].operand[2].mode)))
4256 /* Generate and return an insn body to subtract Y from X. */
4259 gen_sub2_insn (x, y)
4262 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4264 if (! ((*insn_data[icode].operand[0].predicate)
4265 (x, insn_data[icode].operand[0].mode))
4266 || ! ((*insn_data[icode].operand[1].predicate)
4267 (x, insn_data[icode].operand[1].mode))
4268 || ! ((*insn_data[icode].operand[2].predicate)
4269 (y, insn_data[icode].operand[2].mode)))
4272 return (GEN_FCN (icode) (x, x, y));
4275 /* Generate and return an insn body to subtract r1 and c,
4276 storing the result in r0. */
4278 gen_sub3_insn (r0, r1, c)
4281 int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4283 if (icode == CODE_FOR_nothing
4284 || ! ((*insn_data[icode].operand[0].predicate)
4285 (r0, insn_data[icode].operand[0].mode))
4286 || ! ((*insn_data[icode].operand[1].predicate)
4287 (r1, insn_data[icode].operand[1].mode))
4288 || ! ((*insn_data[icode].operand[2].predicate)
4289 (c, insn_data[icode].operand[2].mode)))
4292 return (GEN_FCN (icode) (r0, r1, c));
4296 have_sub2_insn (x, y)
4301 if (GET_MODE (x) == VOIDmode)
4304 icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4306 if (icode == CODE_FOR_nothing)
4309 if (! ((*insn_data[icode].operand[0].predicate)
4310 (x, insn_data[icode].operand[0].mode))
4311 || ! ((*insn_data[icode].operand[1].predicate)
4312 (x, insn_data[icode].operand[1].mode))
4313 || ! ((*insn_data[icode].operand[2].predicate)
4314 (y, insn_data[icode].operand[2].mode)))
4320 /* Generate the body of an instruction to copy Y into X.
4321 It may be a list of insns, if one insn isn't enough. */
4324 gen_move_insn (x, y)
4327 enum machine_mode mode = GET_MODE (x);
4328 enum insn_code insn_code;
4331 if (mode == VOIDmode)
4332 mode = GET_MODE (y);
4334 insn_code = mov_optab->handlers[(int) mode].insn_code;
4336 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
4337 find a mode to do it in. If we have a movcc, use it. Otherwise,
4338 find the MODE_INT mode of the same width. */
4340 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
4342 enum machine_mode tmode = VOIDmode;
4346 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
4349 for (tmode = QImode; tmode != VOIDmode;
4350 tmode = GET_MODE_WIDER_MODE (tmode))
4351 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
4354 if (tmode == VOIDmode)
4357 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
4358 may call change_address which is not appropriate if we were
4359 called when a reload was in progress. We don't have to worry
4360 about changing the address since the size in bytes is supposed to
4361 be the same. Copy the MEM to change the mode and move any
4362 substitutions from the old MEM to the new one. */
4364 if (reload_in_progress)
4366 x = gen_lowpart_common (tmode, x1);
4367 if (x == 0 && GET_CODE (x1) == MEM)
4369 x = adjust_address_nv (x1, tmode, 0);
4370 copy_replacements (x1, x);
4373 y = gen_lowpart_common (tmode, y1);
4374 if (y == 0 && GET_CODE (y1) == MEM)
4376 y = adjust_address_nv (y1, tmode, 0);
4377 copy_replacements (y1, y);
4382 x = gen_lowpart (tmode, x);
4383 y = gen_lowpart (tmode, y);
4386 insn_code = mov_optab->handlers[(int) tmode].insn_code;
4387 return (GEN_FCN (insn_code) (x, y));
4391 emit_move_insn_1 (x, y);
4397 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4398 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4399 no such operation exists, CODE_FOR_nothing will be returned. */
4402 can_extend_p (to_mode, from_mode, unsignedp)
4403 enum machine_mode to_mode, from_mode;
4406 #ifdef HAVE_ptr_extend
4408 return CODE_FOR_ptr_extend;
4411 return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
4414 /* Generate the body of an insn to extend Y (with mode MFROM)
4415 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4418 gen_extend_insn (x, y, mto, mfrom, unsignedp)
4420 enum machine_mode mto, mfrom;
4423 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
4426 /* can_fix_p and can_float_p say whether the target machine
4427 can directly convert a given fixed point type to
4428 a given floating point type, or vice versa.
4429 The returned value is the CODE_FOR_... value to use,
4430 or CODE_FOR_nothing if these modes cannot be directly converted.
4432 *TRUNCP_PTR is set to 1 if it is necessary to output
4433 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4435 static enum insn_code
4436 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
4437 enum machine_mode fltmode, fixmode;
4442 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
4443 != CODE_FOR_nothing)
4444 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
4446 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
4449 return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
4451 return CODE_FOR_nothing;
4454 static enum insn_code
4455 can_float_p (fltmode, fixmode, unsignedp)
4456 enum machine_mode fixmode, fltmode;
4459 return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
4462 /* Generate code to convert FROM to floating point
4463 and store in TO. FROM must be fixed point and not VOIDmode.
4464 UNSIGNEDP nonzero means regard FROM as unsigned.
4465 Normally this is done by correcting the final value
4466 if it is negative. */
4469 expand_float (to, from, unsignedp)
4473 enum insn_code icode;
4475 enum machine_mode fmode, imode;
4477 /* Crash now, because we won't be able to decide which mode to use. */
4478 if (GET_MODE (from) == VOIDmode)
4481 /* Look for an insn to do the conversion. Do it in the specified
4482 modes if possible; otherwise convert either input, output or both to
4483 wider mode. If the integer mode is wider than the mode of FROM,
4484 we can do the conversion signed even if the input is unsigned. */
4486 for (imode = GET_MODE (from); imode != VOIDmode;
4487 imode = GET_MODE_WIDER_MODE (imode))
4488 for (fmode = GET_MODE (to); fmode != VOIDmode;
4489 fmode = GET_MODE_WIDER_MODE (fmode))
4491 int doing_unsigned = unsignedp;
4493 if (fmode != GET_MODE (to)
4494 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4497 icode = can_float_p (fmode, imode, unsignedp);
4498 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
4499 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
4501 if (icode != CODE_FOR_nothing)
4503 to = protect_from_queue (to, 1);
4504 from = protect_from_queue (from, 0);
4506 if (imode != GET_MODE (from))
4507 from = convert_to_mode (imode, from, unsignedp);
4509 if (fmode != GET_MODE (to))
4510 target = gen_reg_rtx (fmode);
4512 emit_unop_insn (icode, target, from,
4513 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4516 convert_move (to, target, 0);
4521 /* Unsigned integer, and no way to convert directly.
4522 Convert as signed, then conditionally adjust the result. */
4525 rtx label = gen_label_rtx ();
4527 REAL_VALUE_TYPE offset;
4531 to = protect_from_queue (to, 1);
4532 from = protect_from_queue (from, 0);
4535 from = force_not_mem (from);
4537 /* Look for a usable floating mode FMODE wider than the source and at
4538 least as wide as the target. Using FMODE will avoid rounding woes
4539 with unsigned values greater than the signed maximum value. */
4541 for (fmode = GET_MODE (to); fmode != VOIDmode;
4542 fmode = GET_MODE_WIDER_MODE (fmode))
4543 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4544 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4547 if (fmode == VOIDmode)
4549 /* There is no such mode. Pretend the target is wide enough. */
4550 fmode = GET_MODE (to);
4552 /* Avoid double-rounding when TO is narrower than FROM. */
4553 if ((significand_size (fmode) + 1)
4554 < GET_MODE_BITSIZE (GET_MODE (from)))
4557 rtx neglabel = gen_label_rtx ();
4559 /* Don't use TARGET if it isn't a register, is a hard register,
4560 or is the wrong mode. */
4561 if (GET_CODE (target) != REG
4562 || REGNO (target) < FIRST_PSEUDO_REGISTER
4563 || GET_MODE (target) != fmode)
4564 target = gen_reg_rtx (fmode);
4566 imode = GET_MODE (from);
4567 do_pending_stack_adjust ();
4569 /* Test whether the sign bit is set. */
4570 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4573 /* The sign bit is not set. Convert as signed. */
4574 expand_float (target, from, 0);
4575 emit_jump_insn (gen_jump (label));
4578 /* The sign bit is set.
4579 Convert to a usable (positive signed) value by shifting right
4580 one bit, while remembering if a nonzero bit was shifted
4581 out; i.e., compute (from & 1) | (from >> 1). */
4583 emit_label (neglabel);
4584 temp = expand_binop (imode, and_optab, from, const1_rtx,
4585 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4586 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4588 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4590 expand_float (target, temp, 0);
4592 /* Multiply by 2 to undo the shift above. */
4593 temp = expand_binop (fmode, add_optab, target, target,
4594 target, 0, OPTAB_LIB_WIDEN);
4596 emit_move_insn (target, temp);
4598 do_pending_stack_adjust ();
4604 /* If we are about to do some arithmetic to correct for an
4605 unsigned operand, do it in a pseudo-register. */
4607 if (GET_MODE (to) != fmode
4608 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4609 target = gen_reg_rtx (fmode);
4611 /* Convert as signed integer to floating. */
4612 expand_float (target, from, 0);
4614 /* If FROM is negative (and therefore TO is negative),
4615 correct its value by 2**bitwidth. */
4617 do_pending_stack_adjust ();
4618 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4621 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4622 Rather than setting up a dconst_dot_5, let's hope SCO
4624 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4625 temp = expand_binop (fmode, add_optab, target,
4626 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4627 target, 0, OPTAB_LIB_WIDEN);
4629 emit_move_insn (target, temp);
4631 do_pending_stack_adjust ();
4636 /* No hardware instruction available; call a library routine to convert from
4637 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4643 to = protect_from_queue (to, 1);
4644 from = protect_from_queue (from, 0);
4646 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4647 from = convert_to_mode (SImode, from, unsignedp);
4650 from = force_not_mem (from);
4652 if (GET_MODE (to) == SFmode)
4654 if (GET_MODE (from) == SImode)
4655 libfcn = floatsisf_libfunc;
4656 else if (GET_MODE (from) == DImode)
4657 libfcn = floatdisf_libfunc;
4658 else if (GET_MODE (from) == TImode)
4659 libfcn = floattisf_libfunc;
4663 else if (GET_MODE (to) == DFmode)
4665 if (GET_MODE (from) == SImode)
4666 libfcn = floatsidf_libfunc;
4667 else if (GET_MODE (from) == DImode)
4668 libfcn = floatdidf_libfunc;
4669 else if (GET_MODE (from) == TImode)
4670 libfcn = floattidf_libfunc;
4674 else if (GET_MODE (to) == XFmode)
4676 if (GET_MODE (from) == SImode)
4677 libfcn = floatsixf_libfunc;
4678 else if (GET_MODE (from) == DImode)
4679 libfcn = floatdixf_libfunc;
4680 else if (GET_MODE (from) == TImode)
4681 libfcn = floattixf_libfunc;
4685 else if (GET_MODE (to) == TFmode)
4687 if (GET_MODE (from) == SImode)
4688 libfcn = floatsitf_libfunc;
4689 else if (GET_MODE (from) == DImode)
4690 libfcn = floatditf_libfunc;
4691 else if (GET_MODE (from) == TImode)
4692 libfcn = floattitf_libfunc;
4701 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4702 GET_MODE (to), 1, from,
4704 insns = get_insns ();
4707 emit_libcall_block (insns, target, value,
4708 gen_rtx_FLOAT (GET_MODE (to), from));
4713 /* Copy result to requested destination
4714 if we have been computing in a temp location. */
4718 if (GET_MODE (target) == GET_MODE (to))
4719 emit_move_insn (to, target);
4721 convert_move (to, target, 0);
4725 /* expand_fix: generate code to convert FROM to fixed point
4726 and store in TO. FROM must be floating point. */
4732 rtx temp = gen_reg_rtx (GET_MODE (x));
4733 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4737 expand_fix (to, from, unsignedp)
4741 enum insn_code icode;
4743 enum machine_mode fmode, imode;
4747 /* We first try to find a pair of modes, one real and one integer, at
4748 least as wide as FROM and TO, respectively, in which we can open-code
4749 this conversion. If the integer mode is wider than the mode of TO,
4750 we can do the conversion either signed or unsigned. */
4752 for (fmode = GET_MODE (from); fmode != VOIDmode;
4753 fmode = GET_MODE_WIDER_MODE (fmode))
4754 for (imode = GET_MODE (to); imode != VOIDmode;
4755 imode = GET_MODE_WIDER_MODE (imode))
4757 int doing_unsigned = unsignedp;
4759 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4760 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4761 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4763 if (icode != CODE_FOR_nothing)
4765 to = protect_from_queue (to, 1);
4766 from = protect_from_queue (from, 0);
4768 if (fmode != GET_MODE (from))
4769 from = convert_to_mode (fmode, from, 0);
4772 from = ftruncify (from);
4774 if (imode != GET_MODE (to))
4775 target = gen_reg_rtx (imode);
4777 emit_unop_insn (icode, target, from,
4778 doing_unsigned ? UNSIGNED_FIX : FIX);
4780 convert_move (to, target, unsignedp);
4785 /* For an unsigned conversion, there is one more way to do it.
4786 If we have a signed conversion, we generate code that compares
4787 the real value to the largest representable positive number. If if
4788 is smaller, the conversion is done normally. Otherwise, subtract
4789 one plus the highest signed number, convert, and add it back.
4791 We only need to check all real modes, since we know we didn't find
4792 anything with a wider integer mode. */
4794 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4795 for (fmode = GET_MODE (from); fmode != VOIDmode;
4796 fmode = GET_MODE_WIDER_MODE (fmode))
4797 /* Make sure we won't lose significant bits doing this. */
4798 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4799 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4803 REAL_VALUE_TYPE offset;
4804 rtx limit, lab1, lab2, insn;
4806 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4807 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4808 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4809 lab1 = gen_label_rtx ();
4810 lab2 = gen_label_rtx ();
4813 to = protect_from_queue (to, 1);
4814 from = protect_from_queue (from, 0);
4817 from = force_not_mem (from);
4819 if (fmode != GET_MODE (from))
4820 from = convert_to_mode (fmode, from, 0);
4822 /* See if we need to do the subtraction. */
4823 do_pending_stack_adjust ();
4824 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4827 /* If not, do the signed "fix" and branch around fixup code. */
4828 expand_fix (to, from, 0);
4829 emit_jump_insn (gen_jump (lab2));
4832 /* Otherwise, subtract 2**(N-1), convert to signed number,
4833 then add 2**(N-1). Do the addition using XOR since this
4834 will often generate better code. */
4836 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4837 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4838 expand_fix (to, target, 0);
4839 target = expand_binop (GET_MODE (to), xor_optab, to,
4841 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4843 to, 1, OPTAB_LIB_WIDEN);
4846 emit_move_insn (to, target);
4850 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4851 != CODE_FOR_nothing)
4853 /* Make a place for a REG_NOTE and add it. */
4854 insn = emit_move_insn (to, to);
4855 set_unique_reg_note (insn,
4857 gen_rtx_fmt_e (UNSIGNED_FIX,
4865 /* We can't do it with an insn, so use a library call. But first ensure
4866 that the mode of TO is at least as wide as SImode, since those are the
4867 only library calls we know about. */
4869 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4871 target = gen_reg_rtx (SImode);
4873 expand_fix (target, from, unsignedp);
4875 else if (GET_MODE (from) == SFmode)
4877 if (GET_MODE (to) == SImode)
4878 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4879 else if (GET_MODE (to) == DImode)
4880 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4881 else if (GET_MODE (to) == TImode)
4882 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4886 else if (GET_MODE (from) == DFmode)
4888 if (GET_MODE (to) == SImode)
4889 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4890 else if (GET_MODE (to) == DImode)
4891 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4892 else if (GET_MODE (to) == TImode)
4893 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4897 else if (GET_MODE (from) == XFmode)
4899 if (GET_MODE (to) == SImode)
4900 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4901 else if (GET_MODE (to) == DImode)
4902 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4903 else if (GET_MODE (to) == TImode)
4904 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4908 else if (GET_MODE (from) == TFmode)
4910 if (GET_MODE (to) == SImode)
4911 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4912 else if (GET_MODE (to) == DImode)
4913 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4914 else if (GET_MODE (to) == TImode)
4915 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4927 to = protect_from_queue (to, 1);
4928 from = protect_from_queue (from, 0);
4931 from = force_not_mem (from);
4935 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4936 GET_MODE (to), 1, from,
4938 insns = get_insns ();
4941 emit_libcall_block (insns, target, value,
4942 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4943 GET_MODE (to), from));
4948 if (GET_MODE (to) == GET_MODE (target))
4949 emit_move_insn (to, target);
4951 convert_move (to, target, 0);
4955 /* Report whether we have an instruction to perform the operation
4956 specified by CODE on operands of mode MODE. */
4958 have_insn_for (code, mode)
4960 enum machine_mode mode;
4962 return (code_to_optab[(int) code] != 0
4963 && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
4964 != CODE_FOR_nothing));
4967 /* Create a blank optab. */
4972 optab op = (optab) ggc_alloc (sizeof (struct optab));
4973 for (i = 0; i < NUM_MACHINE_MODES; i++)
4975 op->handlers[i].insn_code = CODE_FOR_nothing;
4976 op->handlers[i].libfunc = 0;
4982 /* Same, but fill in its code as CODE, and write it into the
4983 code_to_optab table. */
4988 optab op = new_optab ();
4990 code_to_optab[(int) code] = op;
4994 /* Same, but fill in its code as CODE, and do _not_ write it into
4995 the code_to_optab table. */
5000 optab op = new_optab ();
5005 /* Initialize the libfunc fields of an entire group of entries in some
5006 optab. Each entry is set equal to a string consisting of a leading
5007 pair of underscores followed by a generic operation name followed by
5008 a mode name (downshifted to lower case) followed by a single character
5009 representing the number of operands for the given operation (which is
5010 usually one of the characters '2', '3', or '4').
5012 OPTABLE is the table in which libfunc fields are to be initialized.
5013 FIRST_MODE is the first machine mode index in the given optab to
5015 LAST_MODE is the last machine mode index in the given optab to
5017 OPNAME is the generic (string) name of the operation.
5018 SUFFIX is the character which specifies the number of operands for
5019 the given generic operation.
5023 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
5031 unsigned opname_len = strlen (opname);
5033 for (mode = first_mode; (int) mode <= (int) last_mode;
5034 mode = (enum machine_mode) ((int) mode + 1))
5036 const char *mname = GET_MODE_NAME(mode);
5037 unsigned mname_len = strlen (mname);
5038 char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5045 for (q = opname; *q; )
5047 for (q = mname; *q; q++)
5048 *p++ = TOLOWER (*q);
5052 optable->handlers[(int) mode].libfunc
5053 = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
5058 /* Initialize the libfunc fields of an entire group of entries in some
5059 optab which correspond to all integer mode operations. The parameters
5060 have the same meaning as similarly named ones for the `init_libfuncs'
5061 routine. (See above). */
5064 init_integral_libfuncs (optable, opname, suffix)
5069 init_libfuncs (optable, SImode, TImode, opname, suffix);
5072 /* Initialize the libfunc fields of an entire group of entries in some
5073 optab which correspond to all real mode operations. The parameters
5074 have the same meaning as similarly named ones for the `init_libfuncs'
5075 routine. (See above). */
5078 init_floating_libfuncs (optable, opname, suffix)
5083 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
5087 init_one_libfunc (name)
5090 /* Create a FUNCTION_DECL that can be passed to
5091 targetm.encode_section_info. */
5092 /* ??? We don't have any type information except for this is
5093 a function. Pretend this is "int foo()". */
5094 tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
5095 build_function_type (integer_type_node, NULL_TREE));
5096 DECL_ARTIFICIAL (decl) = 1;
5097 DECL_EXTERNAL (decl) = 1;
5098 TREE_PUBLIC (decl) = 1;
5100 /* Return the symbol_ref from the mem rtx. */
5101 return XEXP (DECL_RTL (decl), 0);
5104 /* Call this once to initialize the contents of the optabs
5105 appropriately for the current target machine. */
5110 unsigned int i, j, k;
5112 /* Start by initializing all tables to contain CODE_FOR_nothing. */
5114 for (i = 0; i < ARRAY_SIZE (fixtab); i++)
5115 for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
5116 for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
5117 fixtab[i][j][k] = CODE_FOR_nothing;
5119 for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
5120 for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
5121 for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
5122 fixtrunctab[i][j][k] = CODE_FOR_nothing;
5124 for (i = 0; i < ARRAY_SIZE (floattab); i++)
5125 for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
5126 for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
5127 floattab[i][j][k] = CODE_FOR_nothing;
5129 for (i = 0; i < ARRAY_SIZE (extendtab); i++)
5130 for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
5131 for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
5132 extendtab[i][j][k] = CODE_FOR_nothing;
5134 for (i = 0; i < NUM_RTX_CODE; i++)
5135 setcc_gen_code[i] = CODE_FOR_nothing;
5137 #ifdef HAVE_conditional_move
5138 for (i = 0; i < NUM_MACHINE_MODES; i++)
5139 movcc_gen_code[i] = CODE_FOR_nothing;
5142 add_optab = init_optab (PLUS);
5143 addv_optab = init_optabv (PLUS);
5144 sub_optab = init_optab (MINUS);
5145 subv_optab = init_optabv (MINUS);
5146 smul_optab = init_optab (MULT);
5147 smulv_optab = init_optabv (MULT);
5148 smul_highpart_optab = init_optab (UNKNOWN);
5149 umul_highpart_optab = init_optab (UNKNOWN);
5150 smul_widen_optab = init_optab (UNKNOWN);
5151 umul_widen_optab = init_optab (UNKNOWN);
5152 sdiv_optab = init_optab (DIV);
5153 sdivv_optab = init_optabv (DIV);
5154 sdivmod_optab = init_optab (UNKNOWN);
5155 udiv_optab = init_optab (UDIV);
5156 udivmod_optab = init_optab (UNKNOWN);
5157 smod_optab = init_optab (MOD);
5158 umod_optab = init_optab (UMOD);
5159 ftrunc_optab = init_optab (UNKNOWN);
5160 and_optab = init_optab (AND);
5161 ior_optab = init_optab (IOR);
5162 xor_optab = init_optab (XOR);
5163 ashl_optab = init_optab (ASHIFT);
5164 ashr_optab = init_optab (ASHIFTRT);
5165 lshr_optab = init_optab (LSHIFTRT);
5166 rotl_optab = init_optab (ROTATE);
5167 rotr_optab = init_optab (ROTATERT);
5168 smin_optab = init_optab (SMIN);
5169 smax_optab = init_optab (SMAX);
5170 umin_optab = init_optab (UMIN);
5171 umax_optab = init_optab (UMAX);
5173 /* These three have codes assigned exclusively for the sake of
5175 mov_optab = init_optab (SET);
5176 movstrict_optab = init_optab (STRICT_LOW_PART);
5177 cmp_optab = init_optab (COMPARE);
5179 ucmp_optab = init_optab (UNKNOWN);
5180 tst_optab = init_optab (UNKNOWN);
5181 neg_optab = init_optab (NEG);
5182 negv_optab = init_optabv (NEG);
5183 abs_optab = init_optab (ABS);
5184 absv_optab = init_optabv (ABS);
5185 one_cmpl_optab = init_optab (NOT);
5186 ffs_optab = init_optab (FFS);
5187 sqrt_optab = init_optab (SQRT);
5188 sin_optab = init_optab (UNKNOWN);
5189 cos_optab = init_optab (UNKNOWN);
5190 exp_optab = init_optab (UNKNOWN);
5191 log_optab = init_optab (UNKNOWN);
5192 strlen_optab = init_optab (UNKNOWN);
5193 cbranch_optab = init_optab (UNKNOWN);
5194 cmov_optab = init_optab (UNKNOWN);
5195 cstore_optab = init_optab (UNKNOWN);
5196 push_optab = init_optab (UNKNOWN);
5198 for (i = 0; i < NUM_MACHINE_MODES; i++)
5200 movstr_optab[i] = CODE_FOR_nothing;
5201 clrstr_optab[i] = CODE_FOR_nothing;
5203 #ifdef HAVE_SECONDARY_RELOADS
5204 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5208 /* Fill in the optabs with the insns we support. */
5211 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
5212 /* This flag says the same insns that convert to a signed fixnum
5213 also convert validly to an unsigned one. */
5214 for (i = 0; i < NUM_MACHINE_MODES; i++)
5215 for (j = 0; j < NUM_MACHINE_MODES; j++)
5216 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
5219 /* Initialize the optabs with the names of the library functions. */
5220 init_integral_libfuncs (add_optab, "add", '3');
5221 init_floating_libfuncs (add_optab, "add", '3');
5222 init_integral_libfuncs (addv_optab, "addv", '3');
5223 init_floating_libfuncs (addv_optab, "add", '3');
5224 init_integral_libfuncs (sub_optab, "sub", '3');
5225 init_floating_libfuncs (sub_optab, "sub", '3');
5226 init_integral_libfuncs (subv_optab, "subv", '3');
5227 init_floating_libfuncs (subv_optab, "sub", '3');
5228 init_integral_libfuncs (smul_optab, "mul", '3');
5229 init_floating_libfuncs (smul_optab, "mul", '3');
5230 init_integral_libfuncs (smulv_optab, "mulv", '3');
5231 init_floating_libfuncs (smulv_optab, "mul", '3');
5232 init_integral_libfuncs (sdiv_optab, "div", '3');
5233 init_floating_libfuncs (sdiv_optab, "div", '3');
5234 init_integral_libfuncs (sdivv_optab, "divv", '3');
5235 init_integral_libfuncs (udiv_optab, "udiv", '3');
5236 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5237 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5238 init_integral_libfuncs (smod_optab, "mod", '3');
5239 init_integral_libfuncs (umod_optab, "umod", '3');
5240 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5241 init_integral_libfuncs (and_optab, "and", '3');
5242 init_integral_libfuncs (ior_optab, "ior", '3');
5243 init_integral_libfuncs (xor_optab, "xor", '3');
5244 init_integral_libfuncs (ashl_optab, "ashl", '3');
5245 init_integral_libfuncs (ashr_optab, "ashr", '3');
5246 init_integral_libfuncs (lshr_optab, "lshr", '3');
5247 init_integral_libfuncs (smin_optab, "min", '3');
5248 init_floating_libfuncs (smin_optab, "min", '3');
5249 init_integral_libfuncs (smax_optab, "max", '3');
5250 init_floating_libfuncs (smax_optab, "max", '3');
5251 init_integral_libfuncs (umin_optab, "umin", '3');
5252 init_integral_libfuncs (umax_optab, "umax", '3');
5253 init_integral_libfuncs (neg_optab, "neg", '2');
5254 init_floating_libfuncs (neg_optab, "neg", '2');
5255 init_integral_libfuncs (negv_optab, "negv", '2');
5256 init_floating_libfuncs (negv_optab, "neg", '2');
5257 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5258 init_integral_libfuncs (ffs_optab, "ffs", '2');
5260 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
5261 init_integral_libfuncs (cmp_optab, "cmp", '2');
5262 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5263 init_floating_libfuncs (cmp_optab, "cmp", '2');
5265 #ifdef MULSI3_LIBCALL
5266 smul_optab->handlers[(int) SImode].libfunc
5267 = init_one_libfunc (MULSI3_LIBCALL);
5269 #ifdef MULDI3_LIBCALL
5270 smul_optab->handlers[(int) DImode].libfunc
5271 = init_one_libfunc (MULDI3_LIBCALL);
5274 #ifdef DIVSI3_LIBCALL
5275 sdiv_optab->handlers[(int) SImode].libfunc
5276 = init_one_libfunc (DIVSI3_LIBCALL);
5278 #ifdef DIVDI3_LIBCALL
5279 sdiv_optab->handlers[(int) DImode].libfunc
5280 = init_one_libfunc (DIVDI3_LIBCALL);
5283 #ifdef UDIVSI3_LIBCALL
5284 udiv_optab->handlers[(int) SImode].libfunc
5285 = init_one_libfunc (UDIVSI3_LIBCALL);
5287 #ifdef UDIVDI3_LIBCALL
5288 udiv_optab->handlers[(int) DImode].libfunc
5289 = init_one_libfunc (UDIVDI3_LIBCALL);
5292 #ifdef MODSI3_LIBCALL
5293 smod_optab->handlers[(int) SImode].libfunc
5294 = init_one_libfunc (MODSI3_LIBCALL);
5296 #ifdef MODDI3_LIBCALL
5297 smod_optab->handlers[(int) DImode].libfunc
5298 = init_one_libfunc (MODDI3_LIBCALL);
5301 #ifdef UMODSI3_LIBCALL
5302 umod_optab->handlers[(int) SImode].libfunc
5303 = init_one_libfunc (UMODSI3_LIBCALL);
5305 #ifdef UMODDI3_LIBCALL
5306 umod_optab->handlers[(int) DImode].libfunc
5307 = init_one_libfunc (UMODDI3_LIBCALL);
5310 /* Use cabs for DC complex abs, since systems generally have cabs.
5311 Don't define any libcall for SCmode, so that cabs will be used. */
5312 abs_optab->handlers[(int) DCmode].libfunc
5313 = init_one_libfunc ("cabs");
5315 /* The ffs function operates on `int'. */
5316 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5317 = init_one_libfunc ("ffs");
5319 extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
5320 extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
5321 extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
5322 extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
5323 extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
5325 truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
5326 truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
5327 trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
5328 truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
5329 trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
5331 abort_libfunc = init_one_libfunc ("abort");
5332 memcpy_libfunc = init_one_libfunc ("memcpy");
5333 memmove_libfunc = init_one_libfunc ("memmove");
5334 bcopy_libfunc = init_one_libfunc ("bcopy");
5335 memcmp_libfunc = init_one_libfunc ("memcmp");
5336 bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
5337 memset_libfunc = init_one_libfunc ("memset");
5338 bzero_libfunc = init_one_libfunc ("bzero");
5340 unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
5341 ? "_Unwind_SjLj_Resume"
5342 : "_Unwind_Resume");
5343 #ifndef DONT_USE_BUILTIN_SETJMP
5344 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5345 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5347 setjmp_libfunc = init_one_libfunc ("setjmp");
5348 longjmp_libfunc = init_one_libfunc ("longjmp");
5350 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5351 unwind_sjlj_unregister_libfunc
5352 = init_one_libfunc ("_Unwind_SjLj_Unregister");
5354 eqhf2_libfunc = init_one_libfunc ("__eqhf2");
5355 nehf2_libfunc = init_one_libfunc ("__nehf2");
5356 gthf2_libfunc = init_one_libfunc ("__gthf2");
5357 gehf2_libfunc = init_one_libfunc ("__gehf2");
5358 lthf2_libfunc = init_one_libfunc ("__lthf2");
5359 lehf2_libfunc = init_one_libfunc ("__lehf2");
5360 unordhf2_libfunc = init_one_libfunc ("__unordhf2");
5362 eqsf2_libfunc = init_one_libfunc ("__eqsf2");
5363 nesf2_libfunc = init_one_libfunc ("__nesf2");
5364 gtsf2_libfunc = init_one_libfunc ("__gtsf2");
5365 gesf2_libfunc = init_one_libfunc ("__gesf2");
5366 ltsf2_libfunc = init_one_libfunc ("__ltsf2");
5367 lesf2_libfunc = init_one_libfunc ("__lesf2");
5368 unordsf2_libfunc = init_one_libfunc ("__unordsf2");
5370 eqdf2_libfunc = init_one_libfunc ("__eqdf2");
5371 nedf2_libfunc = init_one_libfunc ("__nedf2");
5372 gtdf2_libfunc = init_one_libfunc ("__gtdf2");
5373 gedf2_libfunc = init_one_libfunc ("__gedf2");
5374 ltdf2_libfunc = init_one_libfunc ("__ltdf2");
5375 ledf2_libfunc = init_one_libfunc ("__ledf2");
5376 unorddf2_libfunc = init_one_libfunc ("__unorddf2");
5378 eqxf2_libfunc = init_one_libfunc ("__eqxf2");
5379 nexf2_libfunc = init_one_libfunc ("__nexf2");
5380 gtxf2_libfunc = init_one_libfunc ("__gtxf2");
5381 gexf2_libfunc = init_one_libfunc ("__gexf2");
5382 ltxf2_libfunc = init_one_libfunc ("__ltxf2");
5383 lexf2_libfunc = init_one_libfunc ("__lexf2");
5384 unordxf2_libfunc = init_one_libfunc ("__unordxf2");
5386 eqtf2_libfunc = init_one_libfunc ("__eqtf2");
5387 netf2_libfunc = init_one_libfunc ("__netf2");
5388 gttf2_libfunc = init_one_libfunc ("__gttf2");
5389 getf2_libfunc = init_one_libfunc ("__getf2");
5390 lttf2_libfunc = init_one_libfunc ("__lttf2");
5391 letf2_libfunc = init_one_libfunc ("__letf2");
5392 unordtf2_libfunc = init_one_libfunc ("__unordtf2");
5394 floatsisf_libfunc = init_one_libfunc ("__floatsisf");
5395 floatdisf_libfunc = init_one_libfunc ("__floatdisf");
5396 floattisf_libfunc = init_one_libfunc ("__floattisf");
5398 floatsidf_libfunc = init_one_libfunc ("__floatsidf");
5399 floatdidf_libfunc = init_one_libfunc ("__floatdidf");
5400 floattidf_libfunc = init_one_libfunc ("__floattidf");
5402 floatsixf_libfunc = init_one_libfunc ("__floatsixf");
5403 floatdixf_libfunc = init_one_libfunc ("__floatdixf");
5404 floattixf_libfunc = init_one_libfunc ("__floattixf");
5406 floatsitf_libfunc = init_one_libfunc ("__floatsitf");
5407 floatditf_libfunc = init_one_libfunc ("__floatditf");
5408 floattitf_libfunc = init_one_libfunc ("__floattitf");
5410 fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
5411 fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
5412 fixsfti_libfunc = init_one_libfunc ("__fixsfti");
5414 fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
5415 fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
5416 fixdfti_libfunc = init_one_libfunc ("__fixdfti");
5418 fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
5419 fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
5420 fixxfti_libfunc = init_one_libfunc ("__fixxfti");
5422 fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
5423 fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
5424 fixtfti_libfunc = init_one_libfunc ("__fixtfti");
5426 fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
5427 fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
5428 fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
5430 fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
5431 fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
5432 fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
5434 fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
5435 fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
5436 fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
5438 fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
5439 fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
5440 fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
5442 /* For function entry/exit instrumentation. */
5443 profile_function_entry_libfunc
5444 = init_one_libfunc ("__cyg_profile_func_enter");
5445 profile_function_exit_libfunc
5446 = init_one_libfunc ("__cyg_profile_func_exit");
5448 #ifdef HAVE_conditional_trap
5452 #ifdef INIT_TARGET_OPTABS
5453 /* Allow the target to add more libcalls or rename some, etc. */
5458 static GTY(()) rtx trap_rtx;
5460 #ifdef HAVE_conditional_trap
5461 /* The insn generating function can not take an rtx_code argument.
5462 TRAP_RTX is used as an rtx argument. Its code is replaced with
5463 the code to be used in the trap insn and all other fields are
5469 if (HAVE_conditional_trap)
5471 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5476 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5477 CODE. Return 0 on failure. */
5480 gen_cond_trap (code, op1, op2, tcode)
5481 enum rtx_code code ATTRIBUTE_UNUSED;
5482 rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
5484 enum machine_mode mode = GET_MODE (op1);
5486 if (mode == VOIDmode)
5489 #ifdef HAVE_conditional_trap
5490 if (HAVE_conditional_trap
5491 && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
5495 emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
5496 PUT_CODE (trap_rtx, code);
5497 insn = gen_conditional_trap (trap_rtx, tcode);
5501 insn = get_insns ();
5511 #include "gt-optabs.h"