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, 2002, 2003, 2004, 2005, 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA
25 #include "coretypes.h"
29 /* Include insn-config.h before expr.h so that HAVE_conditional_move
30 is properly defined. */
31 #include "insn-config.h"
45 #include "basic-block.h"
48 /* Each optab contains info on how this target machine
49 can perform a particular operation
50 for all sizes and kinds of operands.
52 The operation to be performed is often specified
53 by passing one of these optabs as an argument.
55 See expr.h for documentation of these optabs. */
57 optab optab_table[OTI_MAX];
59 rtx libfunc_table[LTI_MAX];
61 /* Tables of patterns for converting one mode to another. */
62 convert_optab convert_optab_table[COI_MAX];
64 /* Contains the optab used for each rtx code. */
65 optab code_to_optab[NUM_RTX_CODE + 1];
67 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
68 gives the gen_function to make a branch to test that condition. */
70 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
72 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
73 gives the insn code to make a store-condition insn
74 to test that condition. */
76 enum insn_code setcc_gen_code[NUM_RTX_CODE];
78 #ifdef HAVE_conditional_move
79 /* Indexed by the machine mode, gives the insn code to make a conditional
80 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
81 setcc_gen_code to cut down on the number of named patterns. Consider a day
82 when a lot more rtx codes are conditional (eg: for the ARM). */
84 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
87 /* Indexed by the machine mode, gives the insn code for vector conditional
90 enum insn_code vcond_gen_code[NUM_MACHINE_MODES];
91 enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
93 /* The insn generating function can not take an rtx_code argument.
94 TRAP_RTX is used as an rtx argument. Its code is replaced with
95 the code to be used in the trap insn and all other fields are ignored. */
96 static GTY(()) rtx trap_rtx;
98 static int add_equal_note (rtx, rtx, enum rtx_code, rtx, rtx);
99 static rtx widen_operand (rtx, enum machine_mode, enum machine_mode, int,
101 static void prepare_cmp_insn (rtx *, rtx *, enum rtx_code *, rtx,
102 enum machine_mode *, int *,
103 enum can_compare_purpose);
104 static enum insn_code can_fix_p (enum machine_mode, enum machine_mode, int,
106 static enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
107 static optab new_optab (void);
108 static convert_optab new_convert_optab (void);
109 static inline optab init_optab (enum rtx_code);
110 static inline optab init_optabv (enum rtx_code);
111 static inline convert_optab init_convert_optab (enum rtx_code);
112 static void init_libfuncs (optab, int, int, const char *, int);
113 static void init_integral_libfuncs (optab, const char *, int);
114 static void init_floating_libfuncs (optab, const char *, int);
115 static void init_interclass_conv_libfuncs (convert_optab, const char *,
116 enum mode_class, enum mode_class);
117 static void init_intraclass_conv_libfuncs (convert_optab, const char *,
118 enum mode_class, bool);
119 static void emit_cmp_and_jump_insn_1 (rtx, rtx, enum machine_mode,
120 enum rtx_code, int, rtx);
121 static void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
122 enum machine_mode *, int *);
123 static rtx widen_clz (enum machine_mode, rtx, rtx);
124 static rtx expand_parity (enum machine_mode, rtx, rtx);
125 static enum rtx_code get_rtx_code (enum tree_code, bool);
126 static rtx vector_compare_rtx (tree, bool, enum insn_code);
128 #ifndef HAVE_conditional_trap
129 #define HAVE_conditional_trap 0
130 #define gen_conditional_trap(a,b) (gcc_unreachable (), NULL_RTX)
133 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
134 the result of operation CODE applied to OP0 (and OP1 if it is a binary
137 If the last insn does not set TARGET, don't do anything, but return 1.
139 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
140 don't add the REG_EQUAL note but return 0. Our caller can then try
141 again, ensuring that TARGET is not one of the operands. */
144 add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
146 rtx last_insn, insn, set;
149 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
151 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
152 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
153 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
154 && GET_RTX_CLASS (code) != RTX_COMPARE
155 && GET_RTX_CLASS (code) != RTX_UNARY)
158 if (GET_CODE (target) == ZERO_EXTRACT)
161 for (last_insn = insns;
162 NEXT_INSN (last_insn) != NULL_RTX;
163 last_insn = NEXT_INSN (last_insn))
166 set = single_set (last_insn);
170 if (! rtx_equal_p (SET_DEST (set), target)
171 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
172 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
173 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
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) == RTX_UNARY)
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 (rtx op, enum machine_mode mode, enum machine_mode oldmode,
209 int unsignedp, int no_extend)
213 /* If we don't have to extend and this is a constant, return it. */
214 if (no_extend && GET_MODE (op) == VOIDmode)
217 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
218 extend since it will be more efficient to do so unless the signedness of
219 a promoted object differs from our extension. */
221 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
222 && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
223 return convert_modes (mode, oldmode, op, unsignedp);
225 /* If MODE is no wider than a single word, we return a paradoxical
227 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
228 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
230 /* Otherwise, get an object of MODE, clobber it, and set the low-order
233 result = gen_reg_rtx (mode);
234 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
235 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
239 /* Return the optab used for computing the operation given by
240 the tree code, CODE. This function is not always usable (for
241 example, it cannot give complete results for multiplication
242 or division) but probably ought to be relied on more widely
243 throughout the expander. */
245 optab_for_tree_code (enum tree_code code, tree type)
257 return one_cmpl_optab;
266 return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
274 return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
280 return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
289 return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
292 return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
294 case REALIGN_LOAD_EXPR:
295 return vec_realign_load_optab;
298 return TYPE_UNSIGNED (type) ? usum_widen_optab : ssum_widen_optab;
301 return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
304 return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab;
307 return TYPE_UNSIGNED (type) ? reduc_umin_optab : reduc_smin_optab;
309 case REDUC_PLUS_EXPR:
310 return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
312 case VEC_LSHIFT_EXPR:
313 return vec_shl_optab;
315 case VEC_RSHIFT_EXPR:
316 return vec_shr_optab;
322 trapv = flag_trapv && INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type);
326 return trapv ? addv_optab : add_optab;
329 return trapv ? subv_optab : sub_optab;
332 return trapv ? smulv_optab : smul_optab;
335 return trapv ? negv_optab : neg_optab;
338 return trapv ? absv_optab : abs_optab;
346 /* Expand vector widening operations.
348 There are two different classes of operations handled here:
349 1) Operations whose result is wider than all the arguments to the operation.
350 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
351 In this case OP0 and optionally OP1 would be initialized,
352 but WIDE_OP wouldn't (not relevant for this case).
353 2) Operations whose result is of the same size as the last argument to the
354 operation, but wider than all the other arguments to the operation.
355 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
356 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
358 E.g, when called to expand the following operations, this is how
359 the arguments will be initialized:
361 widening-sum 2 oprnd0 - oprnd1
362 widening-dot-product 3 oprnd0 oprnd1 oprnd2
363 widening-mult 2 oprnd0 oprnd1 -
364 type-promotion (vec-unpack) 1 oprnd0 - - */
367 expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op, rtx target,
370 tree oprnd0, oprnd1, oprnd2;
371 enum machine_mode wmode = 0, tmode0, tmode1 = 0;
372 optab widen_pattern_optab;
374 enum machine_mode xmode0, xmode1 = 0, wxmode = 0;
377 rtx xop0, xop1, wxop;
378 int nops = TREE_CODE_LENGTH (TREE_CODE (exp));
380 oprnd0 = TREE_OPERAND (exp, 0);
381 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
382 widen_pattern_optab =
383 optab_for_tree_code (TREE_CODE (exp), TREE_TYPE (oprnd0));
384 icode = (int) widen_pattern_optab->handlers[(int) tmode0].insn_code;
385 gcc_assert (icode != CODE_FOR_nothing);
386 xmode0 = insn_data[icode].operand[1].mode;
390 oprnd1 = TREE_OPERAND (exp, 1);
391 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
392 xmode1 = insn_data[icode].operand[2].mode;
395 /* The last operand is of a wider mode than the rest of the operands. */
403 gcc_assert (tmode1 == tmode0);
405 oprnd2 = TREE_OPERAND (exp, 2);
406 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
407 wxmode = insn_data[icode].operand[3].mode;
411 wmode = wxmode = insn_data[icode].operand[0].mode;
414 || ! (*insn_data[icode].operand[0].predicate) (target, wmode))
415 temp = gen_reg_rtx (wmode);
423 /* In case the insn wants input operands in modes different from
424 those of the actual operands, convert the operands. It would
425 seem that we don't need to convert CONST_INTs, but we do, so
426 that they're properly zero-extended, sign-extended or truncated
429 if (GET_MODE (op0) != xmode0 && xmode0 != VOIDmode)
430 xop0 = convert_modes (xmode0,
431 GET_MODE (op0) != VOIDmode
437 if (GET_MODE (op1) != xmode1 && xmode1 != VOIDmode)
438 xop1 = convert_modes (xmode1,
439 GET_MODE (op1) != VOIDmode
445 if (GET_MODE (wide_op) != wxmode && wxmode != VOIDmode)
446 wxop = convert_modes (wxmode,
447 GET_MODE (wide_op) != VOIDmode
452 /* Now, if insn's predicates don't allow our operands, put them into
455 if (! (*insn_data[icode].operand[1].predicate) (xop0, xmode0)
456 && xmode0 != VOIDmode)
457 xop0 = copy_to_mode_reg (xmode0, xop0);
461 if (! (*insn_data[icode].operand[2].predicate) (xop1, xmode1)
462 && xmode1 != VOIDmode)
463 xop1 = copy_to_mode_reg (xmode1, xop1);
467 if (! (*insn_data[icode].operand[3].predicate) (wxop, wxmode)
468 && wxmode != VOIDmode)
469 wxop = copy_to_mode_reg (wxmode, wxop);
471 pat = GEN_FCN (icode) (temp, xop0, xop1, wxop);
474 pat = GEN_FCN (icode) (temp, xop0, xop1);
480 if (! (*insn_data[icode].operand[2].predicate) (wxop, wxmode)
481 && wxmode != VOIDmode)
482 wxop = copy_to_mode_reg (wxmode, wxop);
484 pat = GEN_FCN (icode) (temp, xop0, wxop);
487 pat = GEN_FCN (icode) (temp, xop0);
494 /* Generate code to perform an operation specified by TERNARY_OPTAB
495 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
497 UNSIGNEDP is for the case where we have to widen the operands
498 to perform the operation. It says to use zero-extension.
500 If TARGET is nonzero, the value
501 is generated there, if it is convenient to do so.
502 In all cases an rtx is returned for the locus of the value;
503 this may or may not be TARGET. */
506 expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
507 rtx op1, rtx op2, rtx target, int unsignedp)
509 int icode = (int) ternary_optab->handlers[(int) mode].insn_code;
510 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
511 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
512 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
515 rtx xop0 = op0, xop1 = op1, xop2 = op2;
517 gcc_assert (ternary_optab->handlers[(int) mode].insn_code
518 != CODE_FOR_nothing);
520 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
521 temp = gen_reg_rtx (mode);
525 /* In case the insn wants input operands in modes different from
526 those of the actual operands, convert the operands. It would
527 seem that we don't need to convert CONST_INTs, but we do, so
528 that they're properly zero-extended, sign-extended or truncated
531 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
532 xop0 = convert_modes (mode0,
533 GET_MODE (op0) != VOIDmode
538 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
539 xop1 = convert_modes (mode1,
540 GET_MODE (op1) != VOIDmode
545 if (GET_MODE (op2) != mode2 && mode2 != VOIDmode)
546 xop2 = convert_modes (mode2,
547 GET_MODE (op2) != VOIDmode
552 /* Now, if insn's predicates don't allow our operands, put them into
555 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
556 && mode0 != VOIDmode)
557 xop0 = copy_to_mode_reg (mode0, xop0);
559 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
560 && mode1 != VOIDmode)
561 xop1 = copy_to_mode_reg (mode1, xop1);
563 if (!insn_data[icode].operand[3].predicate (xop2, mode2)
564 && mode2 != VOIDmode)
565 xop2 = copy_to_mode_reg (mode2, xop2);
567 pat = GEN_FCN (icode) (temp, xop0, xop1, xop2);
574 /* Like expand_binop, but return a constant rtx if the result can be
575 calculated at compile time. The arguments and return value are
576 otherwise the same as for expand_binop. */
579 simplify_expand_binop (enum machine_mode mode, optab binoptab,
580 rtx op0, rtx op1, rtx target, int unsignedp,
581 enum optab_methods methods)
583 if (CONSTANT_P (op0) && CONSTANT_P (op1))
585 rtx x = simplify_binary_operation (binoptab->code, mode, op0, op1);
591 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
594 /* Like simplify_expand_binop, but always put the result in TARGET.
595 Return true if the expansion succeeded. */
598 force_expand_binop (enum machine_mode mode, optab binoptab,
599 rtx op0, rtx op1, rtx target, int unsignedp,
600 enum optab_methods methods)
602 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
603 target, unsignedp, methods);
607 emit_move_insn (target, x);
611 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */
614 expand_vec_shift_expr (tree vec_shift_expr, rtx target)
616 enum insn_code icode;
617 rtx rtx_op1, rtx_op2;
618 enum machine_mode mode1;
619 enum machine_mode mode2;
620 enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_shift_expr));
621 tree vec_oprnd = TREE_OPERAND (vec_shift_expr, 0);
622 tree shift_oprnd = TREE_OPERAND (vec_shift_expr, 1);
626 switch (TREE_CODE (vec_shift_expr))
628 case VEC_RSHIFT_EXPR:
629 shift_optab = vec_shr_optab;
631 case VEC_LSHIFT_EXPR:
632 shift_optab = vec_shl_optab;
638 icode = (int) shift_optab->handlers[(int) mode].insn_code;
639 gcc_assert (icode != CODE_FOR_nothing);
641 mode1 = insn_data[icode].operand[1].mode;
642 mode2 = insn_data[icode].operand[2].mode;
644 rtx_op1 = expand_expr (vec_oprnd, NULL_RTX, VOIDmode, EXPAND_NORMAL);
645 if (!(*insn_data[icode].operand[1].predicate) (rtx_op1, mode1)
646 && mode1 != VOIDmode)
647 rtx_op1 = force_reg (mode1, rtx_op1);
649 rtx_op2 = expand_expr (shift_oprnd, NULL_RTX, VOIDmode, EXPAND_NORMAL);
650 if (!(*insn_data[icode].operand[2].predicate) (rtx_op2, mode2)
651 && mode2 != VOIDmode)
652 rtx_op2 = force_reg (mode2, rtx_op2);
655 || ! (*insn_data[icode].operand[0].predicate) (target, mode))
656 target = gen_reg_rtx (mode);
658 /* Emit instruction */
659 pat = GEN_FCN (icode) (target, rtx_op1, rtx_op2);
666 /* This subroutine of expand_doubleword_shift handles the cases in which
667 the effective shift value is >= BITS_PER_WORD. The arguments and return
668 value are the same as for the parent routine, except that SUPERWORD_OP1
669 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
670 INTO_TARGET may be null if the caller has decided to calculate it. */
673 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
674 rtx outof_target, rtx into_target,
675 int unsignedp, enum optab_methods methods)
677 if (into_target != 0)
678 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
679 into_target, unsignedp, methods))
682 if (outof_target != 0)
684 /* For a signed right shift, we must fill OUTOF_TARGET with copies
685 of the sign bit, otherwise we must fill it with zeros. */
686 if (binoptab != ashr_optab)
687 emit_move_insn (outof_target, CONST0_RTX (word_mode));
689 if (!force_expand_binop (word_mode, binoptab,
690 outof_input, GEN_INT (BITS_PER_WORD - 1),
691 outof_target, unsignedp, methods))
697 /* This subroutine of expand_doubleword_shift handles the cases in which
698 the effective shift value is < BITS_PER_WORD. The arguments and return
699 value are the same as for the parent routine. */
702 expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
703 rtx outof_input, rtx into_input, rtx op1,
704 rtx outof_target, rtx into_target,
705 int unsignedp, enum optab_methods methods,
706 unsigned HOST_WIDE_INT shift_mask)
708 optab reverse_unsigned_shift, unsigned_shift;
711 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
712 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
714 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
715 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
716 the opposite direction to BINOPTAB. */
717 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
719 carries = outof_input;
720 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
721 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
726 /* We must avoid shifting by BITS_PER_WORD bits since that is either
727 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
728 has unknown behavior. Do a single shift first, then shift by the
729 remainder. It's OK to use ~OP1 as the remainder if shift counts
730 are truncated to the mode size. */
731 carries = expand_binop (word_mode, reverse_unsigned_shift,
732 outof_input, const1_rtx, 0, unsignedp, methods);
733 if (shift_mask == BITS_PER_WORD - 1)
735 tmp = immed_double_const (-1, -1, op1_mode);
736 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
741 tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
742 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
746 if (tmp == 0 || carries == 0)
748 carries = expand_binop (word_mode, reverse_unsigned_shift,
749 carries, tmp, 0, unsignedp, methods);
753 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
754 so the result can go directly into INTO_TARGET if convenient. */
755 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
756 into_target, unsignedp, methods);
760 /* Now OR in the bits carried over from OUTOF_INPUT. */
761 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
762 into_target, unsignedp, methods))
765 /* Use a standard word_mode shift for the out-of half. */
766 if (outof_target != 0)
767 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
768 outof_target, unsignedp, methods))
775 #ifdef HAVE_conditional_move
776 /* Try implementing expand_doubleword_shift using conditional moves.
777 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
778 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
779 are the shift counts to use in the former and latter case. All other
780 arguments are the same as the parent routine. */
783 expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
784 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
785 rtx outof_input, rtx into_input,
786 rtx subword_op1, rtx superword_op1,
787 rtx outof_target, rtx into_target,
788 int unsignedp, enum optab_methods methods,
789 unsigned HOST_WIDE_INT shift_mask)
791 rtx outof_superword, into_superword;
793 /* Put the superword version of the output into OUTOF_SUPERWORD and
795 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
796 if (outof_target != 0 && subword_op1 == superword_op1)
798 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
799 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
800 into_superword = outof_target;
801 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
802 outof_superword, 0, unsignedp, methods))
807 into_superword = gen_reg_rtx (word_mode);
808 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
809 outof_superword, into_superword,
814 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
815 if (!expand_subword_shift (op1_mode, binoptab,
816 outof_input, into_input, subword_op1,
817 outof_target, into_target,
818 unsignedp, methods, shift_mask))
821 /* Select between them. Do the INTO half first because INTO_SUPERWORD
822 might be the current value of OUTOF_TARGET. */
823 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
824 into_target, into_superword, word_mode, false))
827 if (outof_target != 0)
828 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
829 outof_target, outof_superword,
837 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
838 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
839 input operand; the shift moves bits in the direction OUTOF_INPUT->
840 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
841 of the target. OP1 is the shift count and OP1_MODE is its mode.
842 If OP1 is constant, it will have been truncated as appropriate
843 and is known to be nonzero.
845 If SHIFT_MASK is zero, the result of word shifts is undefined when the
846 shift count is outside the range [0, BITS_PER_WORD). This routine must
847 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
849 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
850 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
851 fill with zeros or sign bits as appropriate.
853 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
854 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
855 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
856 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
859 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
860 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
861 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
862 function wants to calculate it itself.
864 Return true if the shift could be successfully synthesized. */
867 expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
868 rtx outof_input, rtx into_input, rtx op1,
869 rtx outof_target, rtx into_target,
870 int unsignedp, enum optab_methods methods,
871 unsigned HOST_WIDE_INT shift_mask)
873 rtx superword_op1, tmp, cmp1, cmp2;
874 rtx subword_label, done_label;
875 enum rtx_code cmp_code;
877 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
878 fill the result with sign or zero bits as appropriate. If so, the value
879 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
880 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
881 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
883 This isn't worthwhile for constant shifts since the optimizers will
884 cope better with in-range shift counts. */
885 if (shift_mask >= BITS_PER_WORD
887 && !CONSTANT_P (op1))
889 if (!expand_doubleword_shift (op1_mode, binoptab,
890 outof_input, into_input, op1,
892 unsignedp, methods, shift_mask))
894 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
895 outof_target, unsignedp, methods))
900 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
901 is true when the effective shift value is less than BITS_PER_WORD.
902 Set SUPERWORD_OP1 to the shift count that should be used to shift
903 OUTOF_INPUT into INTO_TARGET when the condition is false. */
904 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
905 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
907 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
908 is a subword shift count. */
909 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
911 cmp2 = CONST0_RTX (op1_mode);
917 /* Set CMP1 to OP1 - BITS_PER_WORD. */
918 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
920 cmp2 = CONST0_RTX (op1_mode);
922 superword_op1 = cmp1;
927 /* If we can compute the condition at compile time, pick the
928 appropriate subroutine. */
929 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
930 if (tmp != 0 && GET_CODE (tmp) == CONST_INT)
932 if (tmp == const0_rtx)
933 return expand_superword_shift (binoptab, outof_input, superword_op1,
934 outof_target, into_target,
937 return expand_subword_shift (op1_mode, binoptab,
938 outof_input, into_input, op1,
939 outof_target, into_target,
940 unsignedp, methods, shift_mask);
943 #ifdef HAVE_conditional_move
944 /* Try using conditional moves to generate straight-line code. */
946 rtx start = get_last_insn ();
947 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
948 cmp_code, cmp1, cmp2,
949 outof_input, into_input,
951 outof_target, into_target,
952 unsignedp, methods, shift_mask))
954 delete_insns_since (start);
958 /* As a last resort, use branches to select the correct alternative. */
959 subword_label = gen_label_rtx ();
960 done_label = gen_label_rtx ();
963 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
964 0, 0, subword_label);
967 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
968 outof_target, into_target,
972 emit_jump_insn (gen_jump (done_label));
974 emit_label (subword_label);
976 if (!expand_subword_shift (op1_mode, binoptab,
977 outof_input, into_input, op1,
978 outof_target, into_target,
979 unsignedp, methods, shift_mask))
982 emit_label (done_label);
986 /* Subroutine of expand_binop. Perform a double word multiplication of
987 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
988 as the target's word_mode. This function return NULL_RTX if anything
989 goes wrong, in which case it may have already emitted instructions
990 which need to be deleted.
992 If we want to multiply two two-word values and have normal and widening
993 multiplies of single-word values, we can do this with three smaller
994 multiplications. Note that we do not make a REG_NO_CONFLICT block here
995 because we are not operating on one word at a time.
997 The multiplication proceeds as follows:
998 _______________________
999 [__op0_high_|__op0_low__]
1000 _______________________
1001 * [__op1_high_|__op1_low__]
1002 _______________________________________________
1003 _______________________
1004 (1) [__op0_low__*__op1_low__]
1005 _______________________
1006 (2a) [__op0_low__*__op1_high_]
1007 _______________________
1008 (2b) [__op0_high_*__op1_low__]
1009 _______________________
1010 (3) [__op0_high_*__op1_high_]
1013 This gives a 4-word result. Since we are only interested in the
1014 lower 2 words, partial result (3) and the upper words of (2a) and
1015 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1016 calculated using non-widening multiplication.
1018 (1), however, needs to be calculated with an unsigned widening
1019 multiplication. If this operation is not directly supported we
1020 try using a signed widening multiplication and adjust the result.
1021 This adjustment works as follows:
1023 If both operands are positive then no adjustment is needed.
1025 If the operands have different signs, for example op0_low < 0 and
1026 op1_low >= 0, the instruction treats the most significant bit of
1027 op0_low as a sign bit instead of a bit with significance
1028 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1029 with 2**BITS_PER_WORD - op0_low, and two's complements the
1030 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1033 Similarly, if both operands are negative, we need to add
1034 (op0_low + op1_low) * 2**BITS_PER_WORD.
1036 We use a trick to adjust quickly. We logically shift op0_low right
1037 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1038 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1039 logical shift exists, we do an arithmetic right shift and subtract
1043 expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
1044 bool umulp, enum optab_methods methods)
1046 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1047 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1048 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
1049 rtx product, adjust, product_high, temp;
1051 rtx op0_high = operand_subword_force (op0, high, mode);
1052 rtx op0_low = operand_subword_force (op0, low, mode);
1053 rtx op1_high = operand_subword_force (op1, high, mode);
1054 rtx op1_low = operand_subword_force (op1, low, mode);
1056 /* If we're using an unsigned multiply to directly compute the product
1057 of the low-order words of the operands and perform any required
1058 adjustments of the operands, we begin by trying two more multiplications
1059 and then computing the appropriate sum.
1061 We have checked above that the required addition is provided.
1062 Full-word addition will normally always succeed, especially if
1063 it is provided at all, so we don't worry about its failure. The
1064 multiplication may well fail, however, so we do handle that. */
1068 /* ??? This could be done with emit_store_flag where available. */
1069 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1070 NULL_RTX, 1, methods);
1072 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
1073 NULL_RTX, 0, OPTAB_DIRECT);
1076 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1077 NULL_RTX, 0, methods);
1080 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
1081 NULL_RTX, 0, OPTAB_DIRECT);
1088 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
1089 NULL_RTX, 0, OPTAB_DIRECT);
1093 /* OP0_HIGH should now be dead. */
1097 /* ??? This could be done with emit_store_flag where available. */
1098 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1099 NULL_RTX, 1, methods);
1101 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
1102 NULL_RTX, 0, OPTAB_DIRECT);
1105 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1106 NULL_RTX, 0, methods);
1109 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
1110 NULL_RTX, 0, OPTAB_DIRECT);
1117 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
1118 NULL_RTX, 0, OPTAB_DIRECT);
1122 /* OP1_HIGH should now be dead. */
1124 adjust = expand_binop (word_mode, add_optab, adjust, temp,
1125 adjust, 0, OPTAB_DIRECT);
1127 if (target && !REG_P (target))
1131 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1132 target, 1, OPTAB_DIRECT);
1134 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1135 target, 1, OPTAB_DIRECT);
1140 product_high = operand_subword (product, high, 1, mode);
1141 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
1142 REG_P (product_high) ? product_high : adjust,
1144 emit_move_insn (product_high, adjust);
1148 /* Wrapper around expand_binop which takes an rtx code to specify
1149 the operation to perform, not an optab pointer. All other
1150 arguments are the same. */
1152 expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
1153 rtx op1, rtx target, int unsignedp,
1154 enum optab_methods methods)
1156 optab binop = code_to_optab[(int) code];
1159 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1162 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1163 binop. Order them according to commutative_operand_precedence and, if
1164 possible, try to put TARGET or a pseudo first. */
1166 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1168 int op0_prec = commutative_operand_precedence (op0);
1169 int op1_prec = commutative_operand_precedence (op1);
1171 if (op0_prec < op1_prec)
1174 if (op0_prec > op1_prec)
1177 /* With equal precedence, both orders are ok, but it is better if the
1178 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1179 if (target == 0 || REG_P (target))
1180 return (REG_P (op1) && !REG_P (op0)) || target == op1;
1182 return rtx_equal_p (op1, target);
1186 /* Generate code to perform an operation specified by BINOPTAB
1187 on operands OP0 and OP1, with result having machine-mode MODE.
1189 UNSIGNEDP is for the case where we have to widen the operands
1190 to perform the operation. It says to use zero-extension.
1192 If TARGET is nonzero, the value
1193 is generated there, if it is convenient to do so.
1194 In all cases an rtx is returned for the locus of the value;
1195 this may or may not be TARGET. */
1198 expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
1199 rtx target, int unsignedp, enum optab_methods methods)
1201 enum optab_methods next_methods
1202 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1203 ? OPTAB_WIDEN : methods);
1204 enum mode_class class;
1205 enum machine_mode wider_mode;
1207 int commutative_op = 0;
1208 int shift_op = (binoptab->code == ASHIFT
1209 || binoptab->code == ASHIFTRT
1210 || binoptab->code == LSHIFTRT
1211 || binoptab->code == ROTATE
1212 || binoptab->code == ROTATERT);
1213 rtx entry_last = get_last_insn ();
1215 bool first_pass_p = true;
1217 class = GET_MODE_CLASS (mode);
1219 /* If subtracting an integer constant, convert this into an addition of
1220 the negated constant. */
1222 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
1224 op1 = negate_rtx (mode, op1);
1225 binoptab = add_optab;
1228 /* If we are inside an appropriately-short loop and we are optimizing,
1229 force expensive constants into a register. */
1230 if (CONSTANT_P (op0) && optimize
1231 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
1233 if (GET_MODE (op0) != VOIDmode)
1234 op0 = convert_modes (mode, VOIDmode, op0, unsignedp);
1235 op0 = force_reg (mode, op0);
1238 if (CONSTANT_P (op1) && optimize
1239 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
1241 if (GET_MODE (op1) != VOIDmode)
1242 op1 = convert_modes (mode, VOIDmode, op1, unsignedp);
1243 op1 = force_reg (mode, op1);
1246 /* Record where to delete back to if we backtrack. */
1247 last = get_last_insn ();
1249 /* If operation is commutative,
1250 try to make the first operand a register.
1251 Even better, try to make it the same as the target.
1252 Also try to make the last operand a constant. */
1253 if (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
1254 || binoptab == smul_widen_optab
1255 || binoptab == umul_widen_optab
1256 || binoptab == smul_highpart_optab
1257 || binoptab == umul_highpart_optab)
1261 if (swap_commutative_operands_with_target (target, op0, op1))
1271 /* If we can do it with a three-operand insn, do so. */
1273 if (methods != OPTAB_MUST_WIDEN
1274 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1276 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1277 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1278 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1280 rtx xop0 = op0, xop1 = op1;
1285 temp = gen_reg_rtx (mode);
1287 /* If it is a commutative operator and the modes would match
1288 if we would swap the operands, we can save the conversions. */
1291 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
1292 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
1296 tmp = op0; op0 = op1; op1 = tmp;
1297 tmp = xop0; xop0 = xop1; xop1 = tmp;
1301 /* In case the insn wants input operands in modes different from
1302 those of the actual operands, convert the operands. It would
1303 seem that we don't need to convert CONST_INTs, but we do, so
1304 that they're properly zero-extended, sign-extended or truncated
1307 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
1308 xop0 = convert_modes (mode0,
1309 GET_MODE (op0) != VOIDmode
1314 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
1315 xop1 = convert_modes (mode1,
1316 GET_MODE (op1) != VOIDmode
1321 /* Now, if insn's predicates don't allow our operands, put them into
1324 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
1325 && mode0 != VOIDmode)
1326 xop0 = copy_to_mode_reg (mode0, xop0);
1328 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
1329 && mode1 != VOIDmode)
1330 xop1 = copy_to_mode_reg (mode1, xop1);
1332 if (!insn_data[icode].operand[0].predicate (temp, mode))
1333 temp = gen_reg_rtx (mode);
1335 pat = GEN_FCN (icode) (temp, xop0, xop1);
1338 /* If PAT is composed of more than one insn, try to add an appropriate
1339 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1340 operand, call ourselves again, this time without a target. */
1341 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1342 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
1344 delete_insns_since (last);
1345 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1346 unsignedp, methods);
1353 delete_insns_since (last);
1356 /* If we were trying to rotate by a constant value, and that didn't
1357 work, try rotating the other direction before falling back to
1358 shifts and bitwise-or. */
1360 && (binoptab == rotl_optab || binoptab == rotr_optab)
1361 && class == MODE_INT
1362 && GET_CODE (op1) == CONST_INT
1364 && (unsigned int) INTVAL (op1) < GET_MODE_BITSIZE (mode))
1366 first_pass_p = false;
1367 op1 = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1));
1368 binoptab = binoptab == rotl_optab ? rotr_optab : rotl_optab;
1372 /* If this is a multiply, see if we can do a widening operation that
1373 takes operands of this mode and makes a wider mode. */
1375 if (binoptab == smul_optab
1376 && GET_MODE_WIDER_MODE (mode) != VOIDmode
1377 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
1378 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
1379 != CODE_FOR_nothing))
1381 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
1382 unsignedp ? umul_widen_optab : smul_widen_optab,
1383 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1387 if (GET_MODE_CLASS (mode) == MODE_INT
1388 && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1389 GET_MODE_BITSIZE (GET_MODE (temp))))
1390 return gen_lowpart (mode, temp);
1392 return convert_to_mode (mode, temp, unsignedp);
1396 /* Look for a wider mode of the same class for which we think we
1397 can open-code the operation. Check for a widening multiply at the
1398 wider mode as well. */
1400 if (CLASS_HAS_WIDER_MODES_P (class)
1401 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1402 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1403 wider_mode != VOIDmode;
1404 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1406 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
1407 || (binoptab == smul_optab
1408 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1409 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
1410 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
1411 != CODE_FOR_nothing)))
1413 rtx xop0 = op0, xop1 = op1;
1416 /* For certain integer operations, we need not actually extend
1417 the narrow operands, as long as we will truncate
1418 the results to the same narrowness. */
1420 if ((binoptab == ior_optab || binoptab == and_optab
1421 || binoptab == xor_optab
1422 || binoptab == add_optab || binoptab == sub_optab
1423 || binoptab == smul_optab || binoptab == ashl_optab)
1424 && class == MODE_INT)
1427 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1429 /* The second operand of a shift must always be extended. */
1430 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1431 no_extend && binoptab != ashl_optab);
1433 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1434 unsignedp, OPTAB_DIRECT);
1437 if (class != MODE_INT
1438 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1439 GET_MODE_BITSIZE (wider_mode)))
1442 target = gen_reg_rtx (mode);
1443 convert_move (target, temp, 0);
1447 return gen_lowpart (mode, temp);
1450 delete_insns_since (last);
1454 /* These can be done a word at a time. */
1455 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1456 && class == MODE_INT
1457 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1458 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1464 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1465 won't be accurate, so use a new target. */
1466 if (target == 0 || target == op0 || target == op1)
1467 target = gen_reg_rtx (mode);
1471 /* Do the actual arithmetic. */
1472 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1474 rtx target_piece = operand_subword (target, i, 1, mode);
1475 rtx x = expand_binop (word_mode, binoptab,
1476 operand_subword_force (op0, i, mode),
1477 operand_subword_force (op1, i, mode),
1478 target_piece, unsignedp, next_methods);
1483 if (target_piece != x)
1484 emit_move_insn (target_piece, x);
1487 insns = get_insns ();
1490 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1492 if (binoptab->code != UNKNOWN)
1494 = gen_rtx_fmt_ee (binoptab->code, mode,
1495 copy_rtx (op0), copy_rtx (op1));
1499 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1504 /* Synthesize double word shifts from single word shifts. */
1505 if ((binoptab == lshr_optab || binoptab == ashl_optab
1506 || binoptab == ashr_optab)
1507 && class == MODE_INT
1508 && (GET_CODE (op1) == CONST_INT || !optimize_size)
1509 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1510 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1511 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1512 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1514 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1515 enum machine_mode op1_mode;
1517 double_shift_mask = targetm.shift_truncation_mask (mode);
1518 shift_mask = targetm.shift_truncation_mask (word_mode);
1519 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1521 /* Apply the truncation to constant shifts. */
1522 if (double_shift_mask > 0 && GET_CODE (op1) == CONST_INT)
1523 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1525 if (op1 == CONST0_RTX (op1_mode))
1528 /* Make sure that this is a combination that expand_doubleword_shift
1529 can handle. See the comments there for details. */
1530 if (double_shift_mask == 0
1531 || (shift_mask == BITS_PER_WORD - 1
1532 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1534 rtx insns, equiv_value;
1535 rtx into_target, outof_target;
1536 rtx into_input, outof_input;
1537 int left_shift, outof_word;
1539 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1540 won't be accurate, so use a new target. */
1541 if (target == 0 || target == op0 || target == op1)
1542 target = gen_reg_rtx (mode);
1546 /* OUTOF_* is the word we are shifting bits away from, and
1547 INTO_* is the word that we are shifting bits towards, thus
1548 they differ depending on the direction of the shift and
1549 WORDS_BIG_ENDIAN. */
1551 left_shift = binoptab == ashl_optab;
1552 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1554 outof_target = operand_subword (target, outof_word, 1, mode);
1555 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1557 outof_input = operand_subword_force (op0, outof_word, mode);
1558 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1560 if (expand_doubleword_shift (op1_mode, binoptab,
1561 outof_input, into_input, op1,
1562 outof_target, into_target,
1563 unsignedp, next_methods, shift_mask))
1565 insns = get_insns ();
1568 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1569 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1576 /* Synthesize double word rotates from single word shifts. */
1577 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1578 && class == MODE_INT
1579 && GET_CODE (op1) == CONST_INT
1580 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1581 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1582 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1585 rtx into_target, outof_target;
1586 rtx into_input, outof_input;
1588 int shift_count, left_shift, outof_word;
1590 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1591 won't be accurate, so use a new target. Do this also if target is not
1592 a REG, first because having a register instead may open optimization
1593 opportunities, and second because if target and op0 happen to be MEMs
1594 designating the same location, we would risk clobbering it too early
1595 in the code sequence we generate below. */
1596 if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
1597 target = gen_reg_rtx (mode);
1601 shift_count = INTVAL (op1);
1603 /* OUTOF_* is the word we are shifting bits away from, and
1604 INTO_* is the word that we are shifting bits towards, thus
1605 they differ depending on the direction of the shift and
1606 WORDS_BIG_ENDIAN. */
1608 left_shift = (binoptab == rotl_optab);
1609 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1611 outof_target = operand_subword (target, outof_word, 1, mode);
1612 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1614 outof_input = operand_subword_force (op0, outof_word, mode);
1615 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1617 if (shift_count == BITS_PER_WORD)
1619 /* This is just a word swap. */
1620 emit_move_insn (outof_target, into_input);
1621 emit_move_insn (into_target, outof_input);
1626 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1627 rtx first_shift_count, second_shift_count;
1628 optab reverse_unsigned_shift, unsigned_shift;
1630 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1631 ? lshr_optab : ashl_optab);
1633 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1634 ? ashl_optab : lshr_optab);
1636 if (shift_count > BITS_PER_WORD)
1638 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1639 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1643 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1644 second_shift_count = GEN_INT (shift_count);
1647 into_temp1 = expand_binop (word_mode, unsigned_shift,
1648 outof_input, first_shift_count,
1649 NULL_RTX, unsignedp, next_methods);
1650 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1651 into_input, second_shift_count,
1652 NULL_RTX, unsignedp, next_methods);
1654 if (into_temp1 != 0 && into_temp2 != 0)
1655 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1656 into_target, unsignedp, next_methods);
1660 if (inter != 0 && inter != into_target)
1661 emit_move_insn (into_target, inter);
1663 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1664 into_input, first_shift_count,
1665 NULL_RTX, unsignedp, next_methods);
1666 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1667 outof_input, second_shift_count,
1668 NULL_RTX, unsignedp, next_methods);
1670 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1671 inter = expand_binop (word_mode, ior_optab,
1672 outof_temp1, outof_temp2,
1673 outof_target, unsignedp, next_methods);
1675 if (inter != 0 && inter != outof_target)
1676 emit_move_insn (outof_target, inter);
1679 insns = get_insns ();
1684 /* One may be tempted to wrap the insns in a REG_NO_CONFLICT
1685 block to help the register allocator a bit. But a multi-word
1686 rotate will need all the input bits when setting the output
1687 bits, so there clearly is a conflict between the input and
1688 output registers. So we can't use a no-conflict block here. */
1694 /* These can be done a word at a time by propagating carries. */
1695 if ((binoptab == add_optab || binoptab == sub_optab)
1696 && class == MODE_INT
1697 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1698 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1701 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1702 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1703 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1704 rtx xop0, xop1, xtarget;
1706 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1707 value is one of those, use it. Otherwise, use 1 since it is the
1708 one easiest to get. */
1709 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1710 int normalizep = STORE_FLAG_VALUE;
1715 /* Prepare the operands. */
1716 xop0 = force_reg (mode, op0);
1717 xop1 = force_reg (mode, op1);
1719 xtarget = gen_reg_rtx (mode);
1721 if (target == 0 || !REG_P (target))
1724 /* Indicate for flow that the entire target reg is being set. */
1726 emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
1728 /* Do the actual arithmetic. */
1729 for (i = 0; i < nwords; i++)
1731 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1732 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1733 rtx op0_piece = operand_subword_force (xop0, index, mode);
1734 rtx op1_piece = operand_subword_force (xop1, index, mode);
1737 /* Main add/subtract of the input operands. */
1738 x = expand_binop (word_mode, binoptab,
1739 op0_piece, op1_piece,
1740 target_piece, unsignedp, next_methods);
1746 /* Store carry from main add/subtract. */
1747 carry_out = gen_reg_rtx (word_mode);
1748 carry_out = emit_store_flag_force (carry_out,
1749 (binoptab == add_optab
1752 word_mode, 1, normalizep);
1759 /* Add/subtract previous carry to main result. */
1760 newx = expand_binop (word_mode,
1761 normalizep == 1 ? binoptab : otheroptab,
1763 NULL_RTX, 1, next_methods);
1767 /* Get out carry from adding/subtracting carry in. */
1768 rtx carry_tmp = gen_reg_rtx (word_mode);
1769 carry_tmp = emit_store_flag_force (carry_tmp,
1770 (binoptab == add_optab
1773 word_mode, 1, normalizep);
1775 /* Logical-ior the two poss. carry together. */
1776 carry_out = expand_binop (word_mode, ior_optab,
1777 carry_out, carry_tmp,
1778 carry_out, 0, next_methods);
1782 emit_move_insn (target_piece, newx);
1786 if (x != target_piece)
1787 emit_move_insn (target_piece, x);
1790 carry_in = carry_out;
1793 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1795 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
1796 || ! rtx_equal_p (target, xtarget))
1798 rtx temp = emit_move_insn (target, xtarget);
1800 set_unique_reg_note (temp,
1802 gen_rtx_fmt_ee (binoptab->code, mode,
1813 delete_insns_since (last);
1816 /* Attempt to synthesize double word multiplies using a sequence of word
1817 mode multiplications. We first attempt to generate a sequence using a
1818 more efficient unsigned widening multiply, and if that fails we then
1819 try using a signed widening multiply. */
1821 if (binoptab == smul_optab
1822 && class == MODE_INT
1823 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1824 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1825 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1827 rtx product = NULL_RTX;
1829 if (umul_widen_optab->handlers[(int) mode].insn_code
1830 != CODE_FOR_nothing)
1832 product = expand_doubleword_mult (mode, op0, op1, target,
1835 delete_insns_since (last);
1838 if (product == NULL_RTX
1839 && smul_widen_optab->handlers[(int) mode].insn_code
1840 != CODE_FOR_nothing)
1842 product = expand_doubleword_mult (mode, op0, op1, target,
1845 delete_insns_since (last);
1848 if (product != NULL_RTX)
1850 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1852 temp = emit_move_insn (target ? target : product, product);
1853 set_unique_reg_note (temp,
1855 gen_rtx_fmt_ee (MULT, mode,
1863 /* It can't be open-coded in this mode.
1864 Use a library call if one is available and caller says that's ok. */
1866 if (binoptab->handlers[(int) mode].libfunc
1867 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1871 enum machine_mode op1_mode = mode;
1878 op1_mode = word_mode;
1879 /* Specify unsigned here,
1880 since negative shift counts are meaningless. */
1881 op1x = convert_to_mode (word_mode, op1, 1);
1884 if (GET_MODE (op0) != VOIDmode
1885 && GET_MODE (op0) != mode)
1886 op0 = convert_to_mode (mode, op0, unsignedp);
1888 /* Pass 1 for NO_QUEUE so we don't lose any increments
1889 if the libcall is cse'd or moved. */
1890 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1891 NULL_RTX, LCT_CONST, mode, 2,
1892 op0, mode, op1x, op1_mode);
1894 insns = get_insns ();
1897 target = gen_reg_rtx (mode);
1898 emit_libcall_block (insns, target, value,
1899 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1904 delete_insns_since (last);
1906 /* It can't be done in this mode. Can we do it in a wider mode? */
1908 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1909 || methods == OPTAB_MUST_WIDEN))
1911 /* Caller says, don't even try. */
1912 delete_insns_since (entry_last);
1916 /* Compute the value of METHODS to pass to recursive calls.
1917 Don't allow widening to be tried recursively. */
1919 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1921 /* Look for a wider mode of the same class for which it appears we can do
1924 if (CLASS_HAS_WIDER_MODES_P (class))
1926 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1927 wider_mode != VOIDmode;
1928 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1930 if ((binoptab->handlers[(int) wider_mode].insn_code
1931 != CODE_FOR_nothing)
1932 || (methods == OPTAB_LIB
1933 && binoptab->handlers[(int) wider_mode].libfunc))
1935 rtx xop0 = op0, xop1 = op1;
1938 /* For certain integer operations, we need not actually extend
1939 the narrow operands, as long as we will truncate
1940 the results to the same narrowness. */
1942 if ((binoptab == ior_optab || binoptab == and_optab
1943 || binoptab == xor_optab
1944 || binoptab == add_optab || binoptab == sub_optab
1945 || binoptab == smul_optab || binoptab == ashl_optab)
1946 && class == MODE_INT)
1949 xop0 = widen_operand (xop0, wider_mode, mode,
1950 unsignedp, no_extend);
1952 /* The second operand of a shift must always be extended. */
1953 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1954 no_extend && binoptab != ashl_optab);
1956 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1957 unsignedp, methods);
1960 if (class != MODE_INT
1961 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1962 GET_MODE_BITSIZE (wider_mode)))
1965 target = gen_reg_rtx (mode);
1966 convert_move (target, temp, 0);
1970 return gen_lowpart (mode, temp);
1973 delete_insns_since (last);
1978 delete_insns_since (entry_last);
1982 /* Expand a binary operator which has both signed and unsigned forms.
1983 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1986 If we widen unsigned operands, we may use a signed wider operation instead
1987 of an unsigned wider operation, since the result would be the same. */
1990 sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
1991 rtx op0, rtx op1, rtx target, int unsignedp,
1992 enum optab_methods methods)
1995 optab direct_optab = unsignedp ? uoptab : soptab;
1996 struct optab wide_soptab;
1998 /* Do it without widening, if possible. */
1999 temp = expand_binop (mode, direct_optab, op0, op1, target,
2000 unsignedp, OPTAB_DIRECT);
2001 if (temp || methods == OPTAB_DIRECT)
2004 /* Try widening to a signed int. Make a fake signed optab that
2005 hides any signed insn for direct use. */
2006 wide_soptab = *soptab;
2007 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
2008 wide_soptab.handlers[(int) mode].libfunc = 0;
2010 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2011 unsignedp, OPTAB_WIDEN);
2013 /* For unsigned operands, try widening to an unsigned int. */
2014 if (temp == 0 && unsignedp)
2015 temp = expand_binop (mode, uoptab, op0, op1, target,
2016 unsignedp, OPTAB_WIDEN);
2017 if (temp || methods == OPTAB_WIDEN)
2020 /* Use the right width lib call if that exists. */
2021 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
2022 if (temp || methods == OPTAB_LIB)
2025 /* Must widen and use a lib call, use either signed or unsigned. */
2026 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2027 unsignedp, methods);
2031 return expand_binop (mode, uoptab, op0, op1, target,
2032 unsignedp, methods);
2036 /* Generate code to perform an operation specified by UNOPPTAB
2037 on operand OP0, with two results to TARG0 and TARG1.
2038 We assume that the order of the operands for the instruction
2039 is TARG0, TARG1, OP0.
2041 Either TARG0 or TARG1 may be zero, but what that means is that
2042 the result is not actually wanted. We will generate it into
2043 a dummy pseudo-reg and discard it. They may not both be zero.
2045 Returns 1 if this operation can be performed; 0 if not. */
2048 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2051 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2052 enum mode_class class;
2053 enum machine_mode wider_mode;
2054 rtx entry_last = get_last_insn ();
2057 class = GET_MODE_CLASS (mode);
2060 targ0 = gen_reg_rtx (mode);
2062 targ1 = gen_reg_rtx (mode);
2064 /* Record where to go back to if we fail. */
2065 last = get_last_insn ();
2067 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2069 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2070 enum machine_mode mode0 = insn_data[icode].operand[2].mode;
2074 if (GET_MODE (xop0) != VOIDmode
2075 && GET_MODE (xop0) != mode0)
2076 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2078 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2079 if (!insn_data[icode].operand[2].predicate (xop0, mode0))
2080 xop0 = copy_to_mode_reg (mode0, xop0);
2082 /* We could handle this, but we should always be called with a pseudo
2083 for our targets and all insns should take them as outputs. */
2084 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2085 gcc_assert (insn_data[icode].operand[1].predicate (targ1, mode));
2087 pat = GEN_FCN (icode) (targ0, targ1, xop0);
2094 delete_insns_since (last);
2097 /* It can't be done in this mode. Can we do it in a wider mode? */
2099 if (CLASS_HAS_WIDER_MODES_P (class))
2101 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2102 wider_mode != VOIDmode;
2103 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2105 if (unoptab->handlers[(int) wider_mode].insn_code
2106 != CODE_FOR_nothing)
2108 rtx t0 = gen_reg_rtx (wider_mode);
2109 rtx t1 = gen_reg_rtx (wider_mode);
2110 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2112 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2114 convert_move (targ0, t0, unsignedp);
2115 convert_move (targ1, t1, unsignedp);
2119 delete_insns_since (last);
2124 delete_insns_since (entry_last);
2128 /* Generate code to perform an operation specified by BINOPTAB
2129 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2130 We assume that the order of the operands for the instruction
2131 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2132 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2134 Either TARG0 or TARG1 may be zero, but what that means is that
2135 the result is not actually wanted. We will generate it into
2136 a dummy pseudo-reg and discard it. They may not both be zero.
2138 Returns 1 if this operation can be performed; 0 if not. */
2141 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2144 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2145 enum mode_class class;
2146 enum machine_mode wider_mode;
2147 rtx entry_last = get_last_insn ();
2150 class = GET_MODE_CLASS (mode);
2152 /* If we are inside an appropriately-short loop and we are optimizing,
2153 force expensive constants into a register. */
2154 if (CONSTANT_P (op0) && optimize
2155 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
2156 op0 = force_reg (mode, op0);
2158 if (CONSTANT_P (op1) && optimize
2159 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
2160 op1 = force_reg (mode, op1);
2163 targ0 = gen_reg_rtx (mode);
2165 targ1 = gen_reg_rtx (mode);
2167 /* Record where to go back to if we fail. */
2168 last = get_last_insn ();
2170 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2172 int icode = (int) binoptab->handlers[(int) mode].insn_code;
2173 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2174 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2176 rtx xop0 = op0, xop1 = op1;
2178 /* In case the insn wants input operands in modes different from
2179 those of the actual operands, convert the operands. It would
2180 seem that we don't need to convert CONST_INTs, but we do, so
2181 that they're properly zero-extended, sign-extended or truncated
2184 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
2185 xop0 = convert_modes (mode0,
2186 GET_MODE (op0) != VOIDmode
2191 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
2192 xop1 = convert_modes (mode1,
2193 GET_MODE (op1) != VOIDmode
2198 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2199 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2200 xop0 = copy_to_mode_reg (mode0, xop0);
2202 if (!insn_data[icode].operand[2].predicate (xop1, mode1))
2203 xop1 = copy_to_mode_reg (mode1, xop1);
2205 /* We could handle this, but we should always be called with a pseudo
2206 for our targets and all insns should take them as outputs. */
2207 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2208 gcc_assert (insn_data[icode].operand[3].predicate (targ1, mode));
2210 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2217 delete_insns_since (last);
2220 /* It can't be done in this mode. Can we do it in a wider mode? */
2222 if (CLASS_HAS_WIDER_MODES_P (class))
2224 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2225 wider_mode != VOIDmode;
2226 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2228 if (binoptab->handlers[(int) wider_mode].insn_code
2229 != CODE_FOR_nothing)
2231 rtx t0 = gen_reg_rtx (wider_mode);
2232 rtx t1 = gen_reg_rtx (wider_mode);
2233 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2234 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2236 if (expand_twoval_binop (binoptab, cop0, cop1,
2239 convert_move (targ0, t0, unsignedp);
2240 convert_move (targ1, t1, unsignedp);
2244 delete_insns_since (last);
2249 delete_insns_since (entry_last);
2253 /* Expand the two-valued library call indicated by BINOPTAB, but
2254 preserve only one of the values. If TARG0 is non-NULL, the first
2255 value is placed into TARG0; otherwise the second value is placed
2256 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2257 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2258 This routine assumes that the value returned by the library call is
2259 as if the return value was of an integral mode twice as wide as the
2260 mode of OP0. Returns 1 if the call was successful. */
2263 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2264 rtx targ0, rtx targ1, enum rtx_code code)
2266 enum machine_mode mode;
2267 enum machine_mode libval_mode;
2271 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2272 gcc_assert (!targ0 != !targ1);
2274 mode = GET_MODE (op0);
2275 if (!binoptab->handlers[(int) mode].libfunc)
2278 /* The value returned by the library function will have twice as
2279 many bits as the nominal MODE. */
2280 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2283 libval = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
2284 NULL_RTX, LCT_CONST,
2288 /* Get the part of VAL containing the value that we want. */
2289 libval = simplify_gen_subreg (mode, libval, libval_mode,
2290 targ0 ? 0 : GET_MODE_SIZE (mode));
2291 insns = get_insns ();
2293 /* Move the into the desired location. */
2294 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2295 gen_rtx_fmt_ee (code, mode, op0, op1));
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 (enum machine_mode mode, enum rtx_code code, rtx op0,
2306 rtx target, int unsignedp)
2308 optab unop = code_to_optab[(int) code];
2311 return expand_unop (mode, unop, op0, target, unsignedp);
2317 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)). */
2319 widen_clz (enum machine_mode mode, rtx op0, rtx target)
2321 enum mode_class class = GET_MODE_CLASS (mode);
2322 if (CLASS_HAS_WIDER_MODES_P (class))
2324 enum machine_mode wider_mode;
2325 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2326 wider_mode != VOIDmode;
2327 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2329 if (clz_optab->handlers[(int) wider_mode].insn_code
2330 != CODE_FOR_nothing)
2332 rtx xop0, temp, last;
2334 last = get_last_insn ();
2337 target = gen_reg_rtx (mode);
2338 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2339 temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2341 temp = expand_binop (wider_mode, sub_optab, temp,
2342 GEN_INT (GET_MODE_BITSIZE (wider_mode)
2343 - GET_MODE_BITSIZE (mode)),
2344 target, true, OPTAB_DIRECT);
2346 delete_insns_since (last);
2355 /* Try calculating (parity x) as (and (popcount x) 1), where
2356 popcount can also be done in a wider mode. */
2358 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2360 enum mode_class class = GET_MODE_CLASS (mode);
2361 if (CLASS_HAS_WIDER_MODES_P (class))
2363 enum machine_mode wider_mode;
2364 for (wider_mode = mode; wider_mode != VOIDmode;
2365 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2367 if (popcount_optab->handlers[(int) wider_mode].insn_code
2368 != CODE_FOR_nothing)
2370 rtx xop0, temp, last;
2372 last = get_last_insn ();
2375 target = gen_reg_rtx (mode);
2376 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2377 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2380 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2381 target, true, OPTAB_DIRECT);
2383 delete_insns_since (last);
2392 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2393 conditions, VAL may already be a SUBREG against which we cannot generate
2394 a further SUBREG. In this case, we expect forcing the value into a
2395 register will work around the situation. */
2398 lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2399 enum machine_mode imode)
2402 ret = lowpart_subreg (omode, val, imode);
2405 val = force_reg (imode, val);
2406 ret = lowpart_subreg (omode, val, imode);
2407 gcc_assert (ret != NULL);
2412 /* Expand a floating point absolute value or negation operation via a
2413 logical operation on the sign bit. */
2416 expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2417 rtx op0, rtx target)
2419 const struct real_format *fmt;
2420 int bitpos, word, nwords, i;
2421 enum machine_mode imode;
2422 HOST_WIDE_INT hi, lo;
2425 /* The format has to have a simple sign bit. */
2426 fmt = REAL_MODE_FORMAT (mode);
2430 bitpos = fmt->signbit_rw;
2434 /* Don't create negative zeros if the format doesn't support them. */
2435 if (code == NEG && !fmt->has_signed_zero)
2438 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2440 imode = int_mode_for_mode (mode);
2441 if (imode == BLKmode)
2450 if (FLOAT_WORDS_BIG_ENDIAN)
2451 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2453 word = bitpos / BITS_PER_WORD;
2454 bitpos = bitpos % BITS_PER_WORD;
2455 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2458 if (bitpos < HOST_BITS_PER_WIDE_INT)
2461 lo = (HOST_WIDE_INT) 1 << bitpos;
2465 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2471 if (target == 0 || target == op0)
2472 target = gen_reg_rtx (mode);
2478 for (i = 0; i < nwords; ++i)
2480 rtx targ_piece = operand_subword (target, i, 1, mode);
2481 rtx op0_piece = operand_subword_force (op0, i, mode);
2485 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2487 immed_double_const (lo, hi, imode),
2488 targ_piece, 1, OPTAB_LIB_WIDEN);
2489 if (temp != targ_piece)
2490 emit_move_insn (targ_piece, temp);
2493 emit_move_insn (targ_piece, op0_piece);
2496 insns = get_insns ();
2499 temp = gen_rtx_fmt_e (code, mode, copy_rtx (op0));
2500 emit_no_conflict_block (insns, target, op0, NULL_RTX, temp);
2504 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2505 gen_lowpart (imode, op0),
2506 immed_double_const (lo, hi, imode),
2507 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2508 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2510 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2511 gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
2517 /* Generate code to perform an operation specified by UNOPTAB
2518 on operand OP0, with result having machine-mode MODE.
2520 UNSIGNEDP is for the case where we have to widen the operands
2521 to perform the operation. It says to use zero-extension.
2523 If TARGET is nonzero, the value
2524 is generated there, if it is convenient to do so.
2525 In all cases an rtx is returned for the locus of the value;
2526 this may or may not be TARGET. */
2529 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2532 enum mode_class class;
2533 enum machine_mode wider_mode;
2535 rtx last = get_last_insn ();
2538 class = GET_MODE_CLASS (mode);
2540 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2542 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2543 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2549 temp = gen_reg_rtx (mode);
2551 if (GET_MODE (xop0) != VOIDmode
2552 && GET_MODE (xop0) != mode0)
2553 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2555 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2557 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2558 xop0 = copy_to_mode_reg (mode0, xop0);
2560 if (!insn_data[icode].operand[0].predicate (temp, mode))
2561 temp = gen_reg_rtx (mode);
2563 pat = GEN_FCN (icode) (temp, xop0);
2566 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2567 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2569 delete_insns_since (last);
2570 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2578 delete_insns_since (last);
2581 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2583 /* Widening clz needs special treatment. */
2584 if (unoptab == clz_optab)
2586 temp = widen_clz (mode, op0, target);
2593 if (CLASS_HAS_WIDER_MODES_P (class))
2594 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2595 wider_mode != VOIDmode;
2596 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2598 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2602 /* For certain operations, we need not actually extend
2603 the narrow operand, as long as we will truncate the
2604 results to the same narrowness. */
2606 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2607 (unoptab == neg_optab
2608 || unoptab == one_cmpl_optab)
2609 && class == MODE_INT);
2611 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2616 if (class != MODE_INT
2617 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
2618 GET_MODE_BITSIZE (wider_mode)))
2621 target = gen_reg_rtx (mode);
2622 convert_move (target, temp, 0);
2626 return gen_lowpart (mode, temp);
2629 delete_insns_since (last);
2633 /* These can be done a word at a time. */
2634 if (unoptab == one_cmpl_optab
2635 && class == MODE_INT
2636 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2637 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2642 if (target == 0 || target == op0)
2643 target = gen_reg_rtx (mode);
2647 /* Do the actual arithmetic. */
2648 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2650 rtx target_piece = operand_subword (target, i, 1, mode);
2651 rtx x = expand_unop (word_mode, unoptab,
2652 operand_subword_force (op0, i, mode),
2653 target_piece, unsignedp);
2655 if (target_piece != x)
2656 emit_move_insn (target_piece, x);
2659 insns = get_insns ();
2662 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2663 gen_rtx_fmt_e (unoptab->code, mode,
2668 if (unoptab->code == NEG)
2670 /* Try negating floating point values by flipping the sign bit. */
2671 if (SCALAR_FLOAT_MODE_P (mode))
2673 temp = expand_absneg_bit (NEG, mode, op0, target);
2678 /* If there is no negation pattern, and we have no negative zero,
2679 try subtracting from zero. */
2680 if (!HONOR_SIGNED_ZEROS (mode))
2682 temp = expand_binop (mode, (unoptab == negv_optab
2683 ? subv_optab : sub_optab),
2684 CONST0_RTX (mode), op0, target,
2685 unsignedp, OPTAB_DIRECT);
2691 /* Try calculating parity (x) as popcount (x) % 2. */
2692 if (unoptab == parity_optab)
2694 temp = expand_parity (mode, op0, target);
2700 /* Now try a library call in this mode. */
2701 if (unoptab->handlers[(int) mode].libfunc)
2705 enum machine_mode outmode = mode;
2707 /* All of these functions return small values. Thus we choose to
2708 have them return something that isn't a double-word. */
2709 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2710 || unoptab == popcount_optab || unoptab == parity_optab)
2712 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
2716 /* Pass 1 for NO_QUEUE so we don't lose any increments
2717 if the libcall is cse'd or moved. */
2718 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2719 NULL_RTX, LCT_CONST, outmode,
2721 insns = get_insns ();
2724 target = gen_reg_rtx (outmode);
2725 emit_libcall_block (insns, target, value,
2726 gen_rtx_fmt_e (unoptab->code, outmode, op0));
2731 /* It can't be done in this mode. Can we do it in a wider mode? */
2733 if (CLASS_HAS_WIDER_MODES_P (class))
2735 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2736 wider_mode != VOIDmode;
2737 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2739 if ((unoptab->handlers[(int) wider_mode].insn_code
2740 != CODE_FOR_nothing)
2741 || unoptab->handlers[(int) wider_mode].libfunc)
2745 /* For certain operations, we need not actually extend
2746 the narrow operand, as long as we will truncate the
2747 results to the same narrowness. */
2749 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2750 (unoptab == neg_optab
2751 || unoptab == one_cmpl_optab)
2752 && class == MODE_INT);
2754 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2757 /* If we are generating clz using wider mode, adjust the
2759 if (unoptab == clz_optab && temp != 0)
2760 temp = expand_binop (wider_mode, sub_optab, temp,
2761 GEN_INT (GET_MODE_BITSIZE (wider_mode)
2762 - GET_MODE_BITSIZE (mode)),
2763 target, true, OPTAB_DIRECT);
2767 if (class != MODE_INT)
2770 target = gen_reg_rtx (mode);
2771 convert_move (target, temp, 0);
2775 return gen_lowpart (mode, temp);
2778 delete_insns_since (last);
2783 /* One final attempt at implementing negation via subtraction,
2784 this time allowing widening of the operand. */
2785 if (unoptab->code == NEG && !HONOR_SIGNED_ZEROS (mode))
2788 temp = expand_binop (mode,
2789 unoptab == negv_optab ? subv_optab : sub_optab,
2790 CONST0_RTX (mode), op0,
2791 target, unsignedp, OPTAB_LIB_WIDEN);
2799 /* Emit code to compute the absolute value of OP0, with result to
2800 TARGET if convenient. (TARGET may be 0.) The return value says
2801 where the result actually is to be found.
2803 MODE is the mode of the operand; the mode of the result is
2804 different but can be deduced from MODE.
2809 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
2810 int result_unsignedp)
2815 result_unsignedp = 1;
2817 /* First try to do it with a special abs instruction. */
2818 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2823 /* For floating point modes, try clearing the sign bit. */
2824 if (SCALAR_FLOAT_MODE_P (mode))
2826 temp = expand_absneg_bit (ABS, mode, op0, target);
2831 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2832 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
2833 && !HONOR_SIGNED_ZEROS (mode))
2835 rtx last = get_last_insn ();
2837 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2839 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2845 delete_insns_since (last);
2848 /* If this machine has expensive jumps, we can do integer absolute
2849 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2850 where W is the width of MODE. */
2852 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2854 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2855 size_int (GET_MODE_BITSIZE (mode) - 1),
2858 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2861 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2862 temp, extended, target, 0, OPTAB_LIB_WIDEN);
2872 expand_abs (enum machine_mode mode, rtx op0, rtx target,
2873 int result_unsignedp, int safe)
2878 result_unsignedp = 1;
2880 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
2884 /* If that does not win, use conditional jump and negate. */
2886 /* It is safe to use the target if it is the same
2887 as the source if this is also a pseudo register */
2888 if (op0 == target && REG_P (op0)
2889 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2892 op1 = gen_label_rtx ();
2893 if (target == 0 || ! safe
2894 || GET_MODE (target) != mode
2895 || (MEM_P (target) && MEM_VOLATILE_P (target))
2897 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2898 target = gen_reg_rtx (mode);
2900 emit_move_insn (target, op0);
2903 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2904 NULL_RTX, NULL_RTX, op1);
2906 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2909 emit_move_insn (target, op0);
2915 /* A subroutine of expand_copysign, perform the copysign operation using the
2916 abs and neg primitives advertised to exist on the target. The assumption
2917 is that we have a split register file, and leaving op0 in fp registers,
2918 and not playing with subregs so much, will help the register allocator. */
2921 expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
2922 int bitpos, bool op0_is_abs)
2924 enum machine_mode imode;
2925 HOST_WIDE_INT hi, lo;
2934 op0 = expand_unop (mode, abs_optab, op0, target, 0);
2941 if (target == NULL_RTX)
2942 target = copy_to_reg (op0);
2944 emit_move_insn (target, op0);
2947 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2949 imode = int_mode_for_mode (mode);
2950 if (imode == BLKmode)
2952 op1 = gen_lowpart (imode, op1);
2957 if (FLOAT_WORDS_BIG_ENDIAN)
2958 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2960 word = bitpos / BITS_PER_WORD;
2961 bitpos = bitpos % BITS_PER_WORD;
2962 op1 = operand_subword_force (op1, word, mode);
2965 if (bitpos < HOST_BITS_PER_WIDE_INT)
2968 lo = (HOST_WIDE_INT) 1 << bitpos;
2972 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2976 op1 = expand_binop (imode, and_optab, op1,
2977 immed_double_const (lo, hi, imode),
2978 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2980 label = gen_label_rtx ();
2981 emit_cmp_and_jump_insns (op1, const0_rtx, EQ, NULL_RTX, imode, 1, label);
2983 if (GET_CODE (op0) == CONST_DOUBLE)
2984 op0 = simplify_unary_operation (NEG, mode, op0, mode);
2986 op0 = expand_unop (mode, neg_optab, op0, target, 0);
2988 emit_move_insn (target, op0);
2996 /* A subroutine of expand_copysign, perform the entire copysign operation
2997 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
2998 is true if op0 is known to have its sign bit clear. */
3001 expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3002 int bitpos, bool op0_is_abs)
3004 enum machine_mode imode;
3005 HOST_WIDE_INT hi, lo;
3006 int word, nwords, i;
3009 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3011 imode = int_mode_for_mode (mode);
3012 if (imode == BLKmode)
3021 if (FLOAT_WORDS_BIG_ENDIAN)
3022 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3024 word = bitpos / BITS_PER_WORD;
3025 bitpos = bitpos % BITS_PER_WORD;
3026 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3029 if (bitpos < HOST_BITS_PER_WIDE_INT)
3032 lo = (HOST_WIDE_INT) 1 << bitpos;
3036 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3040 if (target == 0 || target == op0 || target == op1)
3041 target = gen_reg_rtx (mode);
3047 for (i = 0; i < nwords; ++i)
3049 rtx targ_piece = operand_subword (target, i, 1, mode);
3050 rtx op0_piece = operand_subword_force (op0, i, mode);
3055 op0_piece = expand_binop (imode, and_optab, op0_piece,
3056 immed_double_const (~lo, ~hi, imode),
3057 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3059 op1 = expand_binop (imode, and_optab,
3060 operand_subword_force (op1, i, mode),
3061 immed_double_const (lo, hi, imode),
3062 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3064 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3065 targ_piece, 1, OPTAB_LIB_WIDEN);
3066 if (temp != targ_piece)
3067 emit_move_insn (targ_piece, temp);
3070 emit_move_insn (targ_piece, op0_piece);
3073 insns = get_insns ();
3076 emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
3080 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3081 immed_double_const (lo, hi, imode),
3082 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3084 op0 = gen_lowpart (imode, op0);
3086 op0 = expand_binop (imode, and_optab, op0,
3087 immed_double_const (~lo, ~hi, imode),
3088 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3090 temp = expand_binop (imode, ior_optab, op0, op1,
3091 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3092 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3098 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3099 scalar floating point mode. Return NULL if we do not know how to
3100 expand the operation inline. */
3103 expand_copysign (rtx op0, rtx op1, rtx target)
3105 enum machine_mode mode = GET_MODE (op0);
3106 const struct real_format *fmt;
3110 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3111 gcc_assert (GET_MODE (op1) == mode);
3113 /* First try to do it with a special instruction. */
3114 temp = expand_binop (mode, copysign_optab, op0, op1,
3115 target, 0, OPTAB_DIRECT);
3119 fmt = REAL_MODE_FORMAT (mode);
3120 if (fmt == NULL || !fmt->has_signed_zero)
3124 if (GET_CODE (op0) == CONST_DOUBLE)
3126 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3127 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3131 if (fmt->signbit_ro >= 0
3132 && (GET_CODE (op0) == CONST_DOUBLE
3133 || (neg_optab->handlers[mode].insn_code != CODE_FOR_nothing
3134 && abs_optab->handlers[mode].insn_code != CODE_FOR_nothing)))
3136 temp = expand_copysign_absneg (mode, op0, op1, target,
3137 fmt->signbit_ro, op0_is_abs);
3142 if (fmt->signbit_rw < 0)
3144 return expand_copysign_bit (mode, op0, op1, target,
3145 fmt->signbit_rw, op0_is_abs);
3148 /* Generate an instruction whose insn-code is INSN_CODE,
3149 with two operands: an output TARGET and an input OP0.
3150 TARGET *must* be nonzero, and the output is always stored there.
3151 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3152 the value that is stored into TARGET. */
3155 emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3158 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3163 /* Now, if insn does not accept our operands, put them into pseudos. */
3165 if (!insn_data[icode].operand[1].predicate (op0, mode0))
3166 op0 = copy_to_mode_reg (mode0, op0);
3168 if (!insn_data[icode].operand[0].predicate (temp, GET_MODE (temp)))
3169 temp = gen_reg_rtx (GET_MODE (temp));
3171 pat = GEN_FCN (icode) (temp, op0);
3173 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3174 add_equal_note (pat, temp, code, op0, NULL_RTX);
3179 emit_move_insn (target, temp);
3182 struct no_conflict_data
3184 rtx target, first, insn;
3188 /* Called via note_stores by emit_no_conflict_block and emit_libcall_block.
3189 Set P->must_stay if the currently examined clobber / store has to stay
3190 in the list of insns that constitute the actual no_conflict block /
3193 no_conflict_move_test (rtx dest, rtx set, void *p0)
3195 struct no_conflict_data *p= p0;
3197 /* If this inns directly contributes to setting the target, it must stay. */
3198 if (reg_overlap_mentioned_p (p->target, dest))
3199 p->must_stay = true;
3200 /* If we haven't committed to keeping any other insns in the list yet,
3201 there is nothing more to check. */
3202 else if (p->insn == p->first)
3204 /* If this insn sets / clobbers a register that feeds one of the insns
3205 already in the list, this insn has to stay too. */
3206 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3207 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3208 || reg_used_between_p (dest, p->first, p->insn)
3209 /* Likewise if this insn depends on a register set by a previous
3210 insn in the list, or if it sets a result (presumably a hard
3211 register) that is set or clobbered by a previous insn.
3212 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3213 SET_DEST perform the former check on the address, and the latter
3214 check on the MEM. */
3215 || (GET_CODE (set) == SET
3216 && (modified_in_p (SET_SRC (set), p->first)
3217 || modified_in_p (SET_DEST (set), p->first)
3218 || modified_between_p (SET_SRC (set), p->first, p->insn)
3219 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3220 p->must_stay = true;
3223 /* Encapsulate the block starting at FIRST and ending with LAST, which is
3224 logically equivalent to EQUIV, so it gets manipulated as a unit if it
3225 is possible to do so. */
3228 maybe_encapsulate_block (rtx first, rtx last, rtx equiv)
3230 if (!flag_non_call_exceptions || !may_trap_p (equiv))
3232 /* We can't attach the REG_LIBCALL and REG_RETVAL notes when the
3233 encapsulated region would not be in one basic block, i.e. when
3234 there is a control_flow_insn_p insn between FIRST and LAST. */
3235 bool attach_libcall_retval_notes = true;
3236 rtx insn, next = NEXT_INSN (last);
3238 for (insn = first; insn != next; insn = NEXT_INSN (insn))
3239 if (control_flow_insn_p (insn))
3241 attach_libcall_retval_notes = false;
3245 if (attach_libcall_retval_notes)
3247 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3249 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3255 /* Emit code to perform a series of operations on a multi-word quantity, one
3258 Such a block is preceded by a CLOBBER of the output, consists of multiple
3259 insns, each setting one word of the output, and followed by a SET copying
3260 the output to itself.
3262 Each of the insns setting words of the output receives a REG_NO_CONFLICT
3263 note indicating that it doesn't conflict with the (also multi-word)
3264 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3267 INSNS is a block of code generated to perform the operation, not including
3268 the CLOBBER and final copy. All insns that compute intermediate values
3269 are first emitted, followed by the block as described above.
3271 TARGET, OP0, and OP1 are the output and inputs of the operations,
3272 respectively. OP1 may be zero for a unary operation.
3274 EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3277 If TARGET is not a register, INSNS is simply emitted with no special
3278 processing. Likewise if anything in INSNS is not an INSN or if
3279 there is a libcall block inside INSNS.
3281 The final insn emitted is returned. */
3284 emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
3286 rtx prev, next, first, last, insn;
3288 if (!REG_P (target) || reload_in_progress)
3289 return emit_insn (insns);
3291 for (insn = insns; insn; insn = NEXT_INSN (insn))
3292 if (!NONJUMP_INSN_P (insn)
3293 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3294 return emit_insn (insns);
3296 /* First emit all insns that do not store into words of the output and remove
3297 these from the list. */
3298 for (insn = insns; insn; insn = next)
3301 struct no_conflict_data data;
3303 next = NEXT_INSN (insn);
3305 /* Some ports (cris) create a libcall regions at their own. We must
3306 avoid any potential nesting of LIBCALLs. */
3307 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3308 remove_note (insn, note);
3309 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3310 remove_note (insn, note);
3312 data.target = target;
3316 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3317 if (! data.must_stay)
3319 if (PREV_INSN (insn))
3320 NEXT_INSN (PREV_INSN (insn)) = next;
3325 PREV_INSN (next) = PREV_INSN (insn);
3331 prev = get_last_insn ();
3333 /* Now write the CLOBBER of the output, followed by the setting of each
3334 of the words, followed by the final copy. */
3335 if (target != op0 && target != op1)
3336 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3338 for (insn = insns; insn; insn = next)
3340 next = NEXT_INSN (insn);
3343 if (op1 && REG_P (op1))
3344 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3347 if (op0 && REG_P (op0))
3348 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3352 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3353 != CODE_FOR_nothing)
3355 last = emit_move_insn (target, target);
3357 set_unique_reg_note (last, REG_EQUAL, equiv);
3361 last = get_last_insn ();
3363 /* Remove any existing REG_EQUAL note from "last", or else it will
3364 be mistaken for a note referring to the full contents of the
3365 alleged libcall value when found together with the REG_RETVAL
3366 note added below. An existing note can come from an insn
3367 expansion at "last". */
3368 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3372 first = get_insns ();
3374 first = NEXT_INSN (prev);
3376 maybe_encapsulate_block (first, last, equiv);
3381 /* Emit code to make a call to a constant function or a library call.
3383 INSNS is a list containing all insns emitted in the call.
3384 These insns leave the result in RESULT. Our block is to copy RESULT
3385 to TARGET, which is logically equivalent to EQUIV.
3387 We first emit any insns that set a pseudo on the assumption that these are
3388 loading constants into registers; doing so allows them to be safely cse'ed
3389 between blocks. Then we emit all the other insns in the block, followed by
3390 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3391 note with an operand of EQUIV.
3393 Moving assignments to pseudos outside of the block is done to improve
3394 the generated code, but is not required to generate correct code,
3395 hence being unable to move an assignment is not grounds for not making
3396 a libcall block. There are two reasons why it is safe to leave these
3397 insns inside the block: First, we know that these pseudos cannot be
3398 used in generated RTL outside the block since they are created for
3399 temporary purposes within the block. Second, CSE will not record the
3400 values of anything set inside a libcall block, so we know they must
3401 be dead at the end of the block.
3403 Except for the first group of insns (the ones setting pseudos), the
3404 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
3407 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3409 rtx final_dest = target;
3410 rtx prev, next, first, last, insn;
3412 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3413 into a MEM later. Protect the libcall block from this change. */
3414 if (! REG_P (target) || REG_USERVAR_P (target))
3415 target = gen_reg_rtx (GET_MODE (target));
3417 /* If we're using non-call exceptions, a libcall corresponding to an
3418 operation that may trap may also trap. */
3419 if (flag_non_call_exceptions && may_trap_p (equiv))
3421 for (insn = insns; insn; insn = NEXT_INSN (insn))
3424 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3426 if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3427 remove_note (insn, note);
3431 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3432 reg note to indicate that this call cannot throw or execute a nonlocal
3433 goto (unless there is already a REG_EH_REGION note, in which case
3435 for (insn = insns; insn; insn = NEXT_INSN (insn))
3438 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3441 XEXP (note, 0) = constm1_rtx;
3443 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
3447 /* First emit all insns that set pseudos. Remove them from the list as
3448 we go. Avoid insns that set pseudos which were referenced in previous
3449 insns. These can be generated by move_by_pieces, for example,
3450 to update an address. Similarly, avoid insns that reference things
3451 set in previous insns. */
3453 for (insn = insns; insn; insn = next)
3455 rtx set = single_set (insn);
3458 /* Some ports (cris) create a libcall regions at their own. We must
3459 avoid any potential nesting of LIBCALLs. */
3460 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3461 remove_note (insn, note);
3462 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3463 remove_note (insn, note);
3465 next = NEXT_INSN (insn);
3467 if (set != 0 && REG_P (SET_DEST (set))
3468 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3470 struct no_conflict_data data;
3472 data.target = const0_rtx;
3476 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3477 if (! data.must_stay)
3479 if (PREV_INSN (insn))
3480 NEXT_INSN (PREV_INSN (insn)) = next;
3485 PREV_INSN (next) = PREV_INSN (insn);
3491 /* Some ports use a loop to copy large arguments onto the stack.
3492 Don't move anything outside such a loop. */
3497 prev = get_last_insn ();
3499 /* Write the remaining insns followed by the final copy. */
3501 for (insn = insns; insn; insn = next)
3503 next = NEXT_INSN (insn);
3508 last = emit_move_insn (target, result);
3509 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3510 != CODE_FOR_nothing)
3511 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3514 /* Remove any existing REG_EQUAL note from "last", or else it will
3515 be mistaken for a note referring to the full contents of the
3516 libcall value when found together with the REG_RETVAL note added
3517 below. An existing note can come from an insn expansion at
3519 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3522 if (final_dest != target)
3523 emit_move_insn (final_dest, target);
3526 first = get_insns ();
3528 first = NEXT_INSN (prev);
3530 maybe_encapsulate_block (first, last, equiv);
3533 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3534 PURPOSE describes how this comparison will be used. CODE is the rtx
3535 comparison code we will be using.
3537 ??? Actually, CODE is slightly weaker than that. A target is still
3538 required to implement all of the normal bcc operations, but not
3539 required to implement all (or any) of the unordered bcc operations. */
3542 can_compare_p (enum rtx_code code, enum machine_mode mode,
3543 enum can_compare_purpose purpose)
3547 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3549 if (purpose == ccp_jump)
3550 return bcc_gen_fctn[(int) code] != NULL;
3551 else if (purpose == ccp_store_flag)
3552 return setcc_gen_code[(int) code] != CODE_FOR_nothing;
3554 /* There's only one cmov entry point, and it's allowed to fail. */
3557 if (purpose == ccp_jump
3558 && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3560 if (purpose == ccp_cmov
3561 && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3563 if (purpose == ccp_store_flag
3564 && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3566 mode = GET_MODE_WIDER_MODE (mode);
3568 while (mode != VOIDmode);
3573 /* This function is called when we are going to emit a compare instruction that
3574 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3576 *PMODE is the mode of the inputs (in case they are const_int).
3577 *PUNSIGNEDP nonzero says that the operands are unsigned;
3578 this matters if they need to be widened.
3580 If they have mode BLKmode, then SIZE specifies the size of both operands.
3582 This function performs all the setup necessary so that the caller only has
3583 to emit a single comparison insn. This setup can involve doing a BLKmode
3584 comparison or emitting a library call to perform the comparison if no insn
3585 is available to handle it.
3586 The values which are passed in through pointers can be modified; the caller
3587 should perform the comparison on the modified values. Constant
3588 comparisons must have already been folded. */
3591 prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
3592 enum machine_mode *pmode, int *punsignedp,
3593 enum can_compare_purpose purpose)
3595 enum machine_mode mode = *pmode;
3596 rtx x = *px, y = *py;
3597 int unsignedp = *punsignedp;
3599 /* If we are inside an appropriately-short loop and we are optimizing,
3600 force expensive constants into a register. */
3601 if (CONSTANT_P (x) && optimize
3602 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3603 x = force_reg (mode, x);
3605 if (CONSTANT_P (y) && optimize
3606 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3607 y = force_reg (mode, y);
3610 /* Make sure if we have a canonical comparison. The RTL
3611 documentation states that canonical comparisons are required only
3612 for targets which have cc0. */
3613 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3616 /* Don't let both operands fail to indicate the mode. */
3617 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3618 x = force_reg (mode, x);
3620 /* Handle all BLKmode compares. */
3622 if (mode == BLKmode)
3624 enum machine_mode cmp_mode, result_mode;
3625 enum insn_code cmp_code;
3630 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3634 /* Try to use a memory block compare insn - either cmpstr
3635 or cmpmem will do. */
3636 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3637 cmp_mode != VOIDmode;
3638 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3640 cmp_code = cmpmem_optab[cmp_mode];
3641 if (cmp_code == CODE_FOR_nothing)
3642 cmp_code = cmpstr_optab[cmp_mode];
3643 if (cmp_code == CODE_FOR_nothing)
3644 cmp_code = cmpstrn_optab[cmp_mode];
3645 if (cmp_code == CODE_FOR_nothing)
3648 /* Must make sure the size fits the insn's mode. */
3649 if ((GET_CODE (size) == CONST_INT
3650 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3651 || (GET_MODE_BITSIZE (GET_MODE (size))
3652 > GET_MODE_BITSIZE (cmp_mode)))
3655 result_mode = insn_data[cmp_code].operand[0].mode;
3656 result = gen_reg_rtx (result_mode);
3657 size = convert_to_mode (cmp_mode, size, 1);
3658 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3662 *pmode = result_mode;
3666 /* Otherwise call a library function, memcmp. */
3667 libfunc = memcmp_libfunc;
3668 length_type = sizetype;
3669 result_mode = TYPE_MODE (integer_type_node);
3670 cmp_mode = TYPE_MODE (length_type);
3671 size = convert_to_mode (TYPE_MODE (length_type), size,
3672 TYPE_UNSIGNED (length_type));
3674 result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
3681 *pmode = result_mode;
3685 /* Don't allow operands to the compare to trap, as that can put the
3686 compare and branch in different basic blocks. */
3687 if (flag_non_call_exceptions)
3690 x = force_reg (mode, x);
3692 y = force_reg (mode, y);
3697 if (can_compare_p (*pcomparison, mode, purpose))
3700 /* Handle a lib call just for the mode we are using. */
3702 if (cmp_optab->handlers[(int) mode].libfunc && !SCALAR_FLOAT_MODE_P (mode))
3704 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3707 /* If we want unsigned, and this mode has a distinct unsigned
3708 comparison routine, use that. */
3709 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3710 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3712 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
3713 word_mode, 2, x, mode, y, mode);
3715 /* There are two kinds of comparison routines. Biased routines
3716 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3717 of gcc expect that the comparison operation is equivalent
3718 to the modified comparison. For signed comparisons compare the
3719 result against 1 in the biased case, and zero in the unbiased
3720 case. For unsigned comparisons always compare against 1 after
3721 biasing the unbiased result by adding 1. This gives us a way to
3727 if (!TARGET_LIB_INT_CMP_BIASED)
3730 *px = plus_constant (result, 1);
3737 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3738 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3741 /* Before emitting an insn with code ICODE, make sure that X, which is going
3742 to be used for operand OPNUM of the insn, is converted from mode MODE to
3743 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3744 that it is accepted by the operand predicate. Return the new value. */
3747 prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
3748 enum machine_mode wider_mode, int unsignedp)
3750 if (mode != wider_mode)
3751 x = convert_modes (wider_mode, mode, x, unsignedp);
3753 if (!insn_data[icode].operand[opnum].predicate
3754 (x, insn_data[icode].operand[opnum].mode))
3758 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3764 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3765 we can do the comparison.
3766 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3767 be NULL_RTX which indicates that only a comparison is to be generated. */
3770 emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
3771 enum rtx_code comparison, int unsignedp, rtx label)
3773 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3774 enum mode_class class = GET_MODE_CLASS (mode);
3775 enum machine_mode wider_mode = mode;
3777 /* Try combined insns first. */
3780 enum insn_code icode;
3781 PUT_MODE (test, wider_mode);
3785 icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
3787 if (icode != CODE_FOR_nothing
3788 && insn_data[icode].operand[0].predicate (test, wider_mode))
3790 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3791 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3792 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3797 /* Handle some compares against zero. */
3798 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3799 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3801 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3802 emit_insn (GEN_FCN (icode) (x));
3804 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
3808 /* Handle compares for which there is a directly suitable insn. */
3810 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3811 if (icode != CODE_FOR_nothing)
3813 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3814 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3815 emit_insn (GEN_FCN (icode) (x, y));
3817 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
3821 if (!CLASS_HAS_WIDER_MODES_P (class))
3824 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3826 while (wider_mode != VOIDmode);
3831 /* Generate code to compare X with Y so that the condition codes are
3832 set and to jump to LABEL if the condition is true. If X is a
3833 constant and Y is not a constant, then the comparison is swapped to
3834 ensure that the comparison RTL has the canonical form.
3836 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3837 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3838 the proper branch condition code.
3840 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3842 MODE is the mode of the inputs (in case they are const_int).
3844 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3845 be passed unchanged to emit_cmp_insn, then potentially converted into an
3846 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3849 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
3850 enum machine_mode mode, int unsignedp, rtx label)
3852 rtx op0 = x, op1 = y;
3854 /* Swap operands and condition to ensure canonical RTL. */
3855 if (swap_commutative_operands_p (x, y))
3857 /* If we're not emitting a branch, this means some caller
3862 comparison = swap_condition (comparison);
3866 /* If OP0 is still a constant, then both X and Y must be constants.
3867 Force X into a register to create canonical RTL. */
3868 if (CONSTANT_P (op0))
3869 op0 = force_reg (mode, op0);
3873 comparison = unsigned_condition (comparison);
3875 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3877 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3880 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3883 emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3884 enum machine_mode mode, int unsignedp)
3886 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3889 /* Emit a library call comparison between floating point X and Y.
3890 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3893 prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
3894 enum machine_mode *pmode, int *punsignedp)
3896 enum rtx_code comparison = *pcomparison;
3897 enum rtx_code swapped = swap_condition (comparison);
3898 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
3901 enum machine_mode orig_mode = GET_MODE (x);
3902 enum machine_mode mode;
3903 rtx value, target, insns, equiv;
3905 bool reversed_p = false;
3907 for (mode = orig_mode;
3909 mode = GET_MODE_WIDER_MODE (mode))
3911 if ((libfunc = code_to_optab[comparison]->handlers[mode].libfunc))
3914 if ((libfunc = code_to_optab[swapped]->handlers[mode].libfunc))
3917 tmp = x; x = y; y = tmp;
3918 comparison = swapped;
3922 if ((libfunc = code_to_optab[reversed]->handlers[mode].libfunc)
3923 && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
3925 comparison = reversed;
3931 gcc_assert (mode != VOIDmode);
3933 if (mode != orig_mode)
3935 x = convert_to_mode (mode, x, 0);
3936 y = convert_to_mode (mode, y, 0);
3939 /* Attach a REG_EQUAL note describing the semantics of the libcall to
3940 the RTL. The allows the RTL optimizers to delete the libcall if the
3941 condition can be determined at compile-time. */
3942 if (comparison == UNORDERED)
3944 rtx temp = simplify_gen_relational (NE, word_mode, mode, x, x);
3945 equiv = simplify_gen_relational (NE, word_mode, mode, y, y);
3946 equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3947 temp, const_true_rtx, equiv);
3951 equiv = simplify_gen_relational (comparison, word_mode, mode, x, y);
3952 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3954 rtx true_rtx, false_rtx;
3959 true_rtx = const0_rtx;
3960 false_rtx = const_true_rtx;
3964 true_rtx = const_true_rtx;
3965 false_rtx = const0_rtx;
3969 true_rtx = const1_rtx;
3970 false_rtx = const0_rtx;
3974 true_rtx = const0_rtx;
3975 false_rtx = constm1_rtx;
3979 true_rtx = constm1_rtx;
3980 false_rtx = const0_rtx;
3984 true_rtx = const0_rtx;
3985 false_rtx = const1_rtx;
3991 equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3992 equiv, true_rtx, false_rtx);
3997 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
3998 word_mode, 2, x, mode, y, mode);
3999 insns = get_insns ();
4002 target = gen_reg_rtx (word_mode);
4003 emit_libcall_block (insns, target, value, equiv);
4005 if (comparison == UNORDERED
4006 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4007 comparison = reversed_p ? EQ : NE;
4012 *pcomparison = comparison;
4016 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4019 emit_indirect_jump (rtx loc)
4021 if (!insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate
4023 loc = copy_to_mode_reg (Pmode, loc);
4025 emit_jump_insn (gen_indirect_jump (loc));
4029 #ifdef HAVE_conditional_move
4031 /* Emit a conditional move instruction if the machine supports one for that
4032 condition and machine mode.
4034 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4035 the mode to use should they be constants. If it is VOIDmode, they cannot
4038 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4039 should be stored there. MODE is the mode to use should they be constants.
4040 If it is VOIDmode, they cannot both be constants.
4042 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4043 is not supported. */
4046 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4047 enum machine_mode cmode, rtx op2, rtx op3,
4048 enum machine_mode mode, int unsignedp)
4050 rtx tem, subtarget, comparison, insn;
4051 enum insn_code icode;
4052 enum rtx_code reversed;
4054 /* If one operand is constant, make it the second one. Only do this
4055 if the other operand is not constant as well. */
4057 if (swap_commutative_operands_p (op0, op1))
4062 code = swap_condition (code);
4065 /* get_condition will prefer to generate LT and GT even if the old
4066 comparison was against zero, so undo that canonicalization here since
4067 comparisons against zero are cheaper. */
4068 if (code == LT && op1 == const1_rtx)
4069 code = LE, op1 = const0_rtx;
4070 else if (code == GT && op1 == constm1_rtx)
4071 code = GE, op1 = const0_rtx;
4073 if (cmode == VOIDmode)
4074 cmode = GET_MODE (op0);
4076 if (swap_commutative_operands_p (op2, op3)
4077 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4086 if (mode == VOIDmode)
4087 mode = GET_MODE (op2);
4089 icode = movcc_gen_code[mode];
4091 if (icode == CODE_FOR_nothing)
4095 target = gen_reg_rtx (mode);
4099 /* If the insn doesn't accept these operands, put them in pseudos. */
4101 if (!insn_data[icode].operand[0].predicate
4102 (subtarget, insn_data[icode].operand[0].mode))
4103 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4105 if (!insn_data[icode].operand[2].predicate
4106 (op2, insn_data[icode].operand[2].mode))
4107 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4109 if (!insn_data[icode].operand[3].predicate
4110 (op3, insn_data[icode].operand[3].mode))
4111 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4113 /* Everything should now be in the suitable form, so emit the compare insn
4114 and then the conditional move. */
4117 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4119 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
4120 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4121 return NULL and let the caller figure out how best to deal with this
4123 if (GET_CODE (comparison) != code)
4126 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4128 /* If that failed, then give up. */
4134 if (subtarget != target)
4135 convert_move (target, subtarget, 0);
4140 /* Return nonzero if a conditional move of mode MODE is supported.
4142 This function is for combine so it can tell whether an insn that looks
4143 like a conditional move is actually supported by the hardware. If we
4144 guess wrong we lose a bit on optimization, but that's it. */
4145 /* ??? sparc64 supports conditionally moving integers values based on fp
4146 comparisons, and vice versa. How do we handle them? */
4149 can_conditionally_move_p (enum machine_mode mode)
4151 if (movcc_gen_code[mode] != CODE_FOR_nothing)
4157 #endif /* HAVE_conditional_move */
4159 /* Emit a conditional addition instruction if the machine supports one for that
4160 condition and machine mode.
4162 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4163 the mode to use should they be constants. If it is VOIDmode, they cannot
4166 OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4167 should be stored there. MODE is the mode to use should they be constants.
4168 If it is VOIDmode, they cannot both be constants.
4170 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4171 is not supported. */
4174 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4175 enum machine_mode cmode, rtx op2, rtx op3,
4176 enum machine_mode mode, int unsignedp)
4178 rtx tem, subtarget, comparison, insn;
4179 enum insn_code icode;
4180 enum rtx_code reversed;
4182 /* If one operand is constant, make it the second one. Only do this
4183 if the other operand is not constant as well. */
4185 if (swap_commutative_operands_p (op0, op1))
4190 code = swap_condition (code);
4193 /* get_condition will prefer to generate LT and GT even if the old
4194 comparison was against zero, so undo that canonicalization here since
4195 comparisons against zero are cheaper. */
4196 if (code == LT && op1 == const1_rtx)
4197 code = LE, op1 = const0_rtx;
4198 else if (code == GT && op1 == constm1_rtx)
4199 code = GE, op1 = const0_rtx;
4201 if (cmode == VOIDmode)
4202 cmode = GET_MODE (op0);
4204 if (swap_commutative_operands_p (op2, op3)
4205 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4214 if (mode == VOIDmode)
4215 mode = GET_MODE (op2);
4217 icode = addcc_optab->handlers[(int) mode].insn_code;
4219 if (icode == CODE_FOR_nothing)
4223 target = gen_reg_rtx (mode);
4225 /* If the insn doesn't accept these operands, put them in pseudos. */
4227 if (!insn_data[icode].operand[0].predicate
4228 (target, insn_data[icode].operand[0].mode))
4229 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4233 if (!insn_data[icode].operand[2].predicate
4234 (op2, insn_data[icode].operand[2].mode))
4235 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4237 if (!insn_data[icode].operand[3].predicate
4238 (op3, insn_data[icode].operand[3].mode))
4239 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4241 /* Everything should now be in the suitable form, so emit the compare insn
4242 and then the conditional move. */
4245 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4247 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
4248 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4249 return NULL and let the caller figure out how best to deal with this
4251 if (GET_CODE (comparison) != code)
4254 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4256 /* If that failed, then give up. */
4262 if (subtarget != target)
4263 convert_move (target, subtarget, 0);
4268 /* These functions attempt to generate an insn body, rather than
4269 emitting the insn, but if the gen function already emits them, we
4270 make no attempt to turn them back into naked patterns. */
4272 /* Generate and return an insn body to add Y to X. */
4275 gen_add2_insn (rtx x, rtx y)
4277 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4279 gcc_assert (insn_data[icode].operand[0].predicate
4280 (x, insn_data[icode].operand[0].mode));
4281 gcc_assert (insn_data[icode].operand[1].predicate
4282 (x, insn_data[icode].operand[1].mode));
4283 gcc_assert (insn_data[icode].operand[2].predicate
4284 (y, insn_data[icode].operand[2].mode));
4286 return GEN_FCN (icode) (x, x, y);
4289 /* Generate and return an insn body to add r1 and c,
4290 storing the result in r0. */
4292 gen_add3_insn (rtx r0, rtx r1, rtx c)
4294 int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4296 if (icode == CODE_FOR_nothing
4297 || !(insn_data[icode].operand[0].predicate
4298 (r0, insn_data[icode].operand[0].mode))
4299 || !(insn_data[icode].operand[1].predicate
4300 (r1, insn_data[icode].operand[1].mode))
4301 || !(insn_data[icode].operand[2].predicate
4302 (c, insn_data[icode].operand[2].mode)))
4305 return GEN_FCN (icode) (r0, r1, c);
4309 have_add2_insn (rtx x, rtx y)
4313 gcc_assert (GET_MODE (x) != VOIDmode);
4315 icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4317 if (icode == CODE_FOR_nothing)
4320 if (!(insn_data[icode].operand[0].predicate
4321 (x, insn_data[icode].operand[0].mode))
4322 || !(insn_data[icode].operand[1].predicate
4323 (x, insn_data[icode].operand[1].mode))
4324 || !(insn_data[icode].operand[2].predicate
4325 (y, insn_data[icode].operand[2].mode)))
4331 /* Generate and return an insn body to subtract Y from X. */
4334 gen_sub2_insn (rtx x, rtx y)
4336 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4338 gcc_assert (insn_data[icode].operand[0].predicate
4339 (x, insn_data[icode].operand[0].mode));
4340 gcc_assert (insn_data[icode].operand[1].predicate
4341 (x, insn_data[icode].operand[1].mode));
4342 gcc_assert (insn_data[icode].operand[2].predicate
4343 (y, insn_data[icode].operand[2].mode));
4345 return GEN_FCN (icode) (x, x, y);
4348 /* Generate and return an insn body to subtract r1 and c,
4349 storing the result in r0. */
4351 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4353 int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4355 if (icode == CODE_FOR_nothing
4356 || !(insn_data[icode].operand[0].predicate
4357 (r0, insn_data[icode].operand[0].mode))
4358 || !(insn_data[icode].operand[1].predicate
4359 (r1, insn_data[icode].operand[1].mode))
4360 || !(insn_data[icode].operand[2].predicate
4361 (c, insn_data[icode].operand[2].mode)))
4364 return GEN_FCN (icode) (r0, r1, c);
4368 have_sub2_insn (rtx x, rtx y)
4372 gcc_assert (GET_MODE (x) != VOIDmode);
4374 icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4376 if (icode == CODE_FOR_nothing)
4379 if (!(insn_data[icode].operand[0].predicate
4380 (x, insn_data[icode].operand[0].mode))
4381 || !(insn_data[icode].operand[1].predicate
4382 (x, insn_data[icode].operand[1].mode))
4383 || !(insn_data[icode].operand[2].predicate
4384 (y, insn_data[icode].operand[2].mode)))
4390 /* Generate the body of an instruction to copy Y into X.
4391 It may be a list of insns, if one insn isn't enough. */
4394 gen_move_insn (rtx x, rtx y)
4399 emit_move_insn_1 (x, y);
4405 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4406 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4407 no such operation exists, CODE_FOR_nothing will be returned. */
4410 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4414 #ifdef HAVE_ptr_extend
4416 return CODE_FOR_ptr_extend;
4419 tab = unsignedp ? zext_optab : sext_optab;
4420 return tab->handlers[to_mode][from_mode].insn_code;
4423 /* Generate the body of an insn to extend Y (with mode MFROM)
4424 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4427 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4428 enum machine_mode mfrom, int unsignedp)
4430 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4431 return GEN_FCN (icode) (x, y);
4434 /* can_fix_p and can_float_p say whether the target machine
4435 can directly convert a given fixed point type to
4436 a given floating point type, or vice versa.
4437 The returned value is the CODE_FOR_... value to use,
4438 or CODE_FOR_nothing if these modes cannot be directly converted.
4440 *TRUNCP_PTR is set to 1 if it is necessary to output
4441 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4443 static enum insn_code
4444 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4445 int unsignedp, int *truncp_ptr)
4448 enum insn_code icode;
4450 tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4451 icode = tab->handlers[fixmode][fltmode].insn_code;
4452 if (icode != CODE_FOR_nothing)
4458 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4459 for this to work. We need to rework the fix* and ftrunc* patterns
4460 and documentation. */
4461 tab = unsignedp ? ufix_optab : sfix_optab;
4462 icode = tab->handlers[fixmode][fltmode].insn_code;
4463 if (icode != CODE_FOR_nothing
4464 && ftrunc_optab->handlers[fltmode].insn_code != CODE_FOR_nothing)
4471 return CODE_FOR_nothing;
4474 static enum insn_code
4475 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4480 tab = unsignedp ? ufloat_optab : sfloat_optab;
4481 return tab->handlers[fltmode][fixmode].insn_code;
4484 /* Generate code to convert FROM to floating point
4485 and store in TO. FROM must be fixed point and not VOIDmode.
4486 UNSIGNEDP nonzero means regard FROM as unsigned.
4487 Normally this is done by correcting the final value
4488 if it is negative. */
4491 expand_float (rtx to, rtx from, int unsignedp)
4493 enum insn_code icode;
4495 enum machine_mode fmode, imode;
4496 bool can_do_signed = false;
4498 /* Crash now, because we won't be able to decide which mode to use. */
4499 gcc_assert (GET_MODE (from) != VOIDmode);
4501 /* Look for an insn to do the conversion. Do it in the specified
4502 modes if possible; otherwise convert either input, output or both to
4503 wider mode. If the integer mode is wider than the mode of FROM,
4504 we can do the conversion signed even if the input is unsigned. */
4506 for (fmode = GET_MODE (to); fmode != VOIDmode;
4507 fmode = GET_MODE_WIDER_MODE (fmode))
4508 for (imode = GET_MODE (from); imode != VOIDmode;
4509 imode = GET_MODE_WIDER_MODE (imode))
4511 int doing_unsigned = unsignedp;
4513 if (fmode != GET_MODE (to)
4514 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4517 icode = can_float_p (fmode, imode, unsignedp);
4518 if (icode == CODE_FOR_nothing && unsignedp)
4520 enum insn_code scode = can_float_p (fmode, imode, 0);
4521 if (scode != CODE_FOR_nothing)
4522 can_do_signed = true;
4523 if (imode != GET_MODE (from))
4524 icode = scode, doing_unsigned = 0;
4527 if (icode != CODE_FOR_nothing)
4529 if (imode != GET_MODE (from))
4530 from = convert_to_mode (imode, from, unsignedp);
4532 if (fmode != GET_MODE (to))
4533 target = gen_reg_rtx (fmode);
4535 emit_unop_insn (icode, target, from,
4536 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4539 convert_move (to, target, 0);
4544 /* Unsigned integer, and no way to convert directly. For binary
4545 floating point modes, convert as signed, then conditionally adjust
4547 if (unsignedp && can_do_signed && !DECIMAL_FLOAT_MODE_P (GET_MODE (to)))
4549 rtx label = gen_label_rtx ();
4551 REAL_VALUE_TYPE offset;
4553 /* Look for a usable floating mode FMODE wider than the source and at
4554 least as wide as the target. Using FMODE will avoid rounding woes
4555 with unsigned values greater than the signed maximum value. */
4557 for (fmode = GET_MODE (to); fmode != VOIDmode;
4558 fmode = GET_MODE_WIDER_MODE (fmode))
4559 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4560 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4563 if (fmode == VOIDmode)
4565 /* There is no such mode. Pretend the target is wide enough. */
4566 fmode = GET_MODE (to);
4568 /* Avoid double-rounding when TO is narrower than FROM. */
4569 if ((significand_size (fmode) + 1)
4570 < GET_MODE_BITSIZE (GET_MODE (from)))
4573 rtx neglabel = gen_label_rtx ();
4575 /* Don't use TARGET if it isn't a register, is a hard register,
4576 or is the wrong mode. */
4578 || REGNO (target) < FIRST_PSEUDO_REGISTER
4579 || GET_MODE (target) != fmode)
4580 target = gen_reg_rtx (fmode);
4582 imode = GET_MODE (from);
4583 do_pending_stack_adjust ();
4585 /* Test whether the sign bit is set. */
4586 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4589 /* The sign bit is not set. Convert as signed. */
4590 expand_float (target, from, 0);
4591 emit_jump_insn (gen_jump (label));
4594 /* The sign bit is set.
4595 Convert to a usable (positive signed) value by shifting right
4596 one bit, while remembering if a nonzero bit was shifted
4597 out; i.e., compute (from & 1) | (from >> 1). */
4599 emit_label (neglabel);
4600 temp = expand_binop (imode, and_optab, from, const1_rtx,
4601 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4602 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4604 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4606 expand_float (target, temp, 0);
4608 /* Multiply by 2 to undo the shift above. */
4609 temp = expand_binop (fmode, add_optab, target, target,
4610 target, 0, OPTAB_LIB_WIDEN);
4612 emit_move_insn (target, temp);
4614 do_pending_stack_adjust ();
4620 /* If we are about to do some arithmetic to correct for an
4621 unsigned operand, do it in a pseudo-register. */
4623 if (GET_MODE (to) != fmode
4624 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4625 target = gen_reg_rtx (fmode);
4627 /* Convert as signed integer to floating. */
4628 expand_float (target, from, 0);
4630 /* If FROM is negative (and therefore TO is negative),
4631 correct its value by 2**bitwidth. */
4633 do_pending_stack_adjust ();
4634 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4638 real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
4639 temp = expand_binop (fmode, add_optab, target,
4640 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4641 target, 0, OPTAB_LIB_WIDEN);
4643 emit_move_insn (target, temp);
4645 do_pending_stack_adjust ();
4650 /* No hardware instruction available; call a library routine. */
4655 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4657 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4658 from = convert_to_mode (SImode, from, unsignedp);
4660 libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4661 gcc_assert (libfunc);
4665 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4666 GET_MODE (to), 1, from,
4668 insns = get_insns ();
4671 emit_libcall_block (insns, target, value,
4672 gen_rtx_FLOAT (GET_MODE (to), from));
4677 /* Copy result to requested destination
4678 if we have been computing in a temp location. */
4682 if (GET_MODE (target) == GET_MODE (to))
4683 emit_move_insn (to, target);
4685 convert_move (to, target, 0);
4689 /* Generate code to convert FROM to fixed point and store in TO. FROM
4690 must be floating point. */
4693 expand_fix (rtx to, rtx from, int unsignedp)
4695 enum insn_code icode;
4697 enum machine_mode fmode, imode;
4700 /* We first try to find a pair of modes, one real and one integer, at
4701 least as wide as FROM and TO, respectively, in which we can open-code
4702 this conversion. If the integer mode is wider than the mode of TO,
4703 we can do the conversion either signed or unsigned. */
4705 for (fmode = GET_MODE (from); fmode != VOIDmode;
4706 fmode = GET_MODE_WIDER_MODE (fmode))
4707 for (imode = GET_MODE (to); imode != VOIDmode;
4708 imode = GET_MODE_WIDER_MODE (imode))
4710 int doing_unsigned = unsignedp;
4712 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4713 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4714 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4716 if (icode != CODE_FOR_nothing)
4718 if (fmode != GET_MODE (from))
4719 from = convert_to_mode (fmode, from, 0);
4723 rtx temp = gen_reg_rtx (GET_MODE (from));
4724 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4728 if (imode != GET_MODE (to))
4729 target = gen_reg_rtx (imode);
4731 emit_unop_insn (icode, target, from,
4732 doing_unsigned ? UNSIGNED_FIX : FIX);
4734 convert_move (to, target, unsignedp);
4739 /* For an unsigned conversion, there is one more way to do it.
4740 If we have a signed conversion, we generate code that compares
4741 the real value to the largest representable positive number. If if
4742 is smaller, the conversion is done normally. Otherwise, subtract
4743 one plus the highest signed number, convert, and add it back.
4745 We only need to check all real modes, since we know we didn't find
4746 anything with a wider integer mode.
4748 This code used to extend FP value into mode wider than the destination.
4749 This is not needed. Consider, for instance conversion from SFmode
4752 The hot path through the code is dealing with inputs smaller than 2^63
4753 and doing just the conversion, so there is no bits to lose.
4755 In the other path we know the value is positive in the range 2^63..2^64-1
4756 inclusive. (as for other imput overflow happens and result is undefined)
4757 So we know that the most important bit set in mantissa corresponds to
4758 2^63. The subtraction of 2^63 should not generate any rounding as it
4759 simply clears out that bit. The rest is trivial. */
4761 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4762 for (fmode = GET_MODE (from); fmode != VOIDmode;
4763 fmode = GET_MODE_WIDER_MODE (fmode))
4764 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4768 REAL_VALUE_TYPE offset;
4769 rtx limit, lab1, lab2, insn;
4771 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4772 real_2expN (&offset, bitsize - 1);
4773 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4774 lab1 = gen_label_rtx ();
4775 lab2 = gen_label_rtx ();
4777 if (fmode != GET_MODE (from))
4778 from = convert_to_mode (fmode, from, 0);
4780 /* See if we need to do the subtraction. */
4781 do_pending_stack_adjust ();
4782 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4785 /* If not, do the signed "fix" and branch around fixup code. */
4786 expand_fix (to, from, 0);
4787 emit_jump_insn (gen_jump (lab2));
4790 /* Otherwise, subtract 2**(N-1), convert to signed number,
4791 then add 2**(N-1). Do the addition using XOR since this
4792 will often generate better code. */
4794 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4795 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4796 expand_fix (to, target, 0);
4797 target = expand_binop (GET_MODE (to), xor_optab, to,
4799 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4801 to, 1, OPTAB_LIB_WIDEN);
4804 emit_move_insn (to, target);
4808 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4809 != CODE_FOR_nothing)
4811 /* Make a place for a REG_NOTE and add it. */
4812 insn = emit_move_insn (to, to);
4813 set_unique_reg_note (insn,
4815 gen_rtx_fmt_e (UNSIGNED_FIX,
4823 /* We can't do it with an insn, so use a library call. But first ensure
4824 that the mode of TO is at least as wide as SImode, since those are the
4825 only library calls we know about. */
4827 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4829 target = gen_reg_rtx (SImode);
4831 expand_fix (target, from, unsignedp);
4839 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
4840 libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4841 gcc_assert (libfunc);
4845 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4846 GET_MODE (to), 1, from,
4848 insns = get_insns ();
4851 emit_libcall_block (insns, target, value,
4852 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4853 GET_MODE (to), from));
4858 if (GET_MODE (to) == GET_MODE (target))
4859 emit_move_insn (to, target);
4861 convert_move (to, target, 0);
4865 /* Generate code to convert FROM to fixed point and store in TO. FROM
4866 must be floating point, TO must be signed. Use the conversion optab
4867 TAB to do the conversion. */
4870 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
4872 enum insn_code icode;
4874 enum machine_mode fmode, imode;
4876 /* We first try to find a pair of modes, one real and one integer, at
4877 least as wide as FROM and TO, respectively, in which we can open-code
4878 this conversion. If the integer mode is wider than the mode of TO,
4879 we can do the conversion either signed or unsigned. */
4881 for (fmode = GET_MODE (from); fmode != VOIDmode;
4882 fmode = GET_MODE_WIDER_MODE (fmode))
4883 for (imode = GET_MODE (to); imode != VOIDmode;
4884 imode = GET_MODE_WIDER_MODE (imode))
4886 icode = tab->handlers[imode][fmode].insn_code;
4887 if (icode != CODE_FOR_nothing)
4889 if (fmode != GET_MODE (from))
4890 from = convert_to_mode (fmode, from, 0);
4892 if (imode != GET_MODE (to))
4893 target = gen_reg_rtx (imode);
4895 emit_unop_insn (icode, target, from, UNKNOWN);
4897 convert_move (to, target, 0);
4905 /* Report whether we have an instruction to perform the operation
4906 specified by CODE on operands of mode MODE. */
4908 have_insn_for (enum rtx_code code, enum machine_mode mode)
4910 return (code_to_optab[(int) code] != 0
4911 && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
4912 != CODE_FOR_nothing));
4915 /* Create a blank optab. */
4920 optab op = ggc_alloc (sizeof (struct optab));
4921 for (i = 0; i < NUM_MACHINE_MODES; i++)
4923 op->handlers[i].insn_code = CODE_FOR_nothing;
4924 op->handlers[i].libfunc = 0;
4930 static convert_optab
4931 new_convert_optab (void)
4934 convert_optab op = ggc_alloc (sizeof (struct convert_optab));
4935 for (i = 0; i < NUM_MACHINE_MODES; i++)
4936 for (j = 0; j < NUM_MACHINE_MODES; j++)
4938 op->handlers[i][j].insn_code = CODE_FOR_nothing;
4939 op->handlers[i][j].libfunc = 0;
4944 /* Same, but fill in its code as CODE, and write it into the
4945 code_to_optab table. */
4947 init_optab (enum rtx_code code)
4949 optab op = new_optab ();
4951 code_to_optab[(int) code] = op;
4955 /* Same, but fill in its code as CODE, and do _not_ write it into
4956 the code_to_optab table. */
4958 init_optabv (enum rtx_code code)
4960 optab op = new_optab ();
4965 /* Conversion optabs never go in the code_to_optab table. */
4966 static inline convert_optab
4967 init_convert_optab (enum rtx_code code)
4969 convert_optab op = new_convert_optab ();
4974 /* Initialize the libfunc fields of an entire group of entries in some
4975 optab. Each entry is set equal to a string consisting of a leading
4976 pair of underscores followed by a generic operation name followed by
4977 a mode name (downshifted to lowercase) followed by a single character
4978 representing the number of operands for the given operation (which is
4979 usually one of the characters '2', '3', or '4').
4981 OPTABLE is the table in which libfunc fields are to be initialized.
4982 FIRST_MODE is the first machine mode index in the given optab to
4984 LAST_MODE is the last machine mode index in the given optab to
4986 OPNAME is the generic (string) name of the operation.
4987 SUFFIX is the character which specifies the number of operands for
4988 the given generic operation.
4992 init_libfuncs (optab optable, int first_mode, int last_mode,
4993 const char *opname, int suffix)
4996 unsigned opname_len = strlen (opname);
4998 for (mode = first_mode; (int) mode <= (int) last_mode;
4999 mode = (enum machine_mode) ((int) mode + 1))
5001 const char *mname = GET_MODE_NAME (mode);
5002 unsigned mname_len = strlen (mname);
5003 char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5010 for (q = opname; *q; )
5012 for (q = mname; *q; q++)
5013 *p++ = TOLOWER (*q);
5017 optable->handlers[(int) mode].libfunc
5018 = init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
5022 /* Initialize the libfunc fields of an entire group of entries in some
5023 optab which correspond to all integer mode operations. The parameters
5024 have the same meaning as similarly named ones for the `init_libfuncs'
5025 routine. (See above). */
5028 init_integral_libfuncs (optab optable, const char *opname, int suffix)
5030 int maxsize = 2*BITS_PER_WORD;
5031 if (maxsize < LONG_LONG_TYPE_SIZE)
5032 maxsize = LONG_LONG_TYPE_SIZE;
5033 init_libfuncs (optable, word_mode,
5034 mode_for_size (maxsize, MODE_INT, 0),
5038 /* Initialize the libfunc fields of an entire group of entries in some
5039 optab which correspond to all real mode operations. The parameters
5040 have the same meaning as similarly named ones for the `init_libfuncs'
5041 routine. (See above). */
5044 init_floating_libfuncs (optab optable, const char *opname, int suffix)
5046 init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
5047 init_libfuncs (optable, MIN_MODE_DECIMAL_FLOAT, MAX_MODE_DECIMAL_FLOAT,
5051 /* Initialize the libfunc fields of an entire group of entries of an
5052 inter-mode-class conversion optab. The string formation rules are
5053 similar to the ones for init_libfuncs, above, but instead of having
5054 a mode name and an operand count these functions have two mode names
5055 and no operand count. */
5057 init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
5058 enum mode_class from_class,
5059 enum mode_class to_class)
5061 enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
5062 enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
5063 size_t opname_len = strlen (opname);
5064 size_t max_mname_len = 0;
5066 enum machine_mode fmode, tmode;
5067 const char *fname, *tname;
5069 char *libfunc_name, *suffix;
5072 for (fmode = first_from_mode;
5074 fmode = GET_MODE_WIDER_MODE (fmode))
5075 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
5077 for (tmode = first_to_mode;
5079 tmode = GET_MODE_WIDER_MODE (tmode))
5080 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
5082 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5083 libfunc_name[0] = '_';
5084 libfunc_name[1] = '_';
5085 memcpy (&libfunc_name[2], opname, opname_len);
5086 suffix = libfunc_name + opname_len + 2;
5088 for (fmode = first_from_mode; fmode != VOIDmode;
5089 fmode = GET_MODE_WIDER_MODE (fmode))
5090 for (tmode = first_to_mode; tmode != VOIDmode;
5091 tmode = GET_MODE_WIDER_MODE (tmode))
5093 fname = GET_MODE_NAME (fmode);
5094 tname = GET_MODE_NAME (tmode);
5097 for (q = fname; *q; p++, q++)
5099 for (q = tname; *q; p++, q++)
5104 tab->handlers[tmode][fmode].libfunc
5105 = init_one_libfunc (ggc_alloc_string (libfunc_name,
5110 /* Initialize the libfunc fields of an entire group of entries of an
5111 intra-mode-class conversion optab. The string formation rules are
5112 similar to the ones for init_libfunc, above. WIDENING says whether
5113 the optab goes from narrow to wide modes or vice versa. These functions
5114 have two mode names _and_ an operand count. */
5116 init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
5117 enum mode_class class, bool widening)
5119 enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
5120 size_t opname_len = strlen (opname);
5121 size_t max_mname_len = 0;
5123 enum machine_mode nmode, wmode;
5124 const char *nname, *wname;
5126 char *libfunc_name, *suffix;
5129 for (nmode = first_mode; nmode != VOIDmode;
5130 nmode = GET_MODE_WIDER_MODE (nmode))
5131 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
5133 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5134 libfunc_name[0] = '_';
5135 libfunc_name[1] = '_';
5136 memcpy (&libfunc_name[2], opname, opname_len);
5137 suffix = libfunc_name + opname_len + 2;
5139 for (nmode = first_mode; nmode != VOIDmode;
5140 nmode = GET_MODE_WIDER_MODE (nmode))
5141 for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
5142 wmode = GET_MODE_WIDER_MODE (wmode))
5144 nname = GET_MODE_NAME (nmode);
5145 wname = GET_MODE_NAME (wmode);
5148 for (q = widening ? nname : wname; *q; p++, q++)
5150 for (q = widening ? wname : nname; *q; p++, q++)
5156 tab->handlers[widening ? wmode : nmode]
5157 [widening ? nmode : wmode].libfunc
5158 = init_one_libfunc (ggc_alloc_string (libfunc_name,
5165 init_one_libfunc (const char *name)
5169 /* Create a FUNCTION_DECL that can be passed to
5170 targetm.encode_section_info. */
5171 /* ??? We don't have any type information except for this is
5172 a function. Pretend this is "int foo()". */
5173 tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
5174 build_function_type (integer_type_node, NULL_TREE));
5175 DECL_ARTIFICIAL (decl) = 1;
5176 DECL_EXTERNAL (decl) = 1;
5177 TREE_PUBLIC (decl) = 1;
5179 symbol = XEXP (DECL_RTL (decl), 0);
5181 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
5182 are the flags assigned by targetm.encode_section_info. */
5183 SET_SYMBOL_REF_DECL (symbol, 0);
5188 /* Call this to reset the function entry for one optab (OPTABLE) in mode
5189 MODE to NAME, which should be either 0 or a string constant. */
5191 set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
5194 optable->handlers[mode].libfunc = init_one_libfunc (name);
5196 optable->handlers[mode].libfunc = 0;
5199 /* Call this to reset the function entry for one conversion optab
5200 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
5201 either 0 or a string constant. */
5203 set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
5204 enum machine_mode fmode, const char *name)
5207 optable->handlers[tmode][fmode].libfunc = init_one_libfunc (name);
5209 optable->handlers[tmode][fmode].libfunc = 0;
5212 /* Call this once to initialize the contents of the optabs
5213 appropriately for the current target machine. */
5220 /* Start by initializing all tables to contain CODE_FOR_nothing. */
5222 for (i = 0; i < NUM_RTX_CODE; i++)
5223 setcc_gen_code[i] = CODE_FOR_nothing;
5225 #ifdef HAVE_conditional_move
5226 for (i = 0; i < NUM_MACHINE_MODES; i++)
5227 movcc_gen_code[i] = CODE_FOR_nothing;
5230 for (i = 0; i < NUM_MACHINE_MODES; i++)
5232 vcond_gen_code[i] = CODE_FOR_nothing;
5233 vcondu_gen_code[i] = CODE_FOR_nothing;
5236 add_optab = init_optab (PLUS);
5237 addv_optab = init_optabv (PLUS);
5238 sub_optab = init_optab (MINUS);
5239 subv_optab = init_optabv (MINUS);
5240 smul_optab = init_optab (MULT);
5241 smulv_optab = init_optabv (MULT);
5242 smul_highpart_optab = init_optab (UNKNOWN);
5243 umul_highpart_optab = init_optab (UNKNOWN);
5244 smul_widen_optab = init_optab (UNKNOWN);
5245 umul_widen_optab = init_optab (UNKNOWN);
5246 usmul_widen_optab = init_optab (UNKNOWN);
5247 sdiv_optab = init_optab (DIV);
5248 sdivv_optab = init_optabv (DIV);
5249 sdivmod_optab = init_optab (UNKNOWN);
5250 udiv_optab = init_optab (UDIV);
5251 udivmod_optab = init_optab (UNKNOWN);
5252 smod_optab = init_optab (MOD);
5253 umod_optab = init_optab (UMOD);
5254 fmod_optab = init_optab (UNKNOWN);
5255 remainder_optab = init_optab (UNKNOWN);
5256 ftrunc_optab = init_optab (UNKNOWN);
5257 and_optab = init_optab (AND);
5258 ior_optab = init_optab (IOR);
5259 xor_optab = init_optab (XOR);
5260 ashl_optab = init_optab (ASHIFT);
5261 ashr_optab = init_optab (ASHIFTRT);
5262 lshr_optab = init_optab (LSHIFTRT);
5263 rotl_optab = init_optab (ROTATE);
5264 rotr_optab = init_optab (ROTATERT);
5265 smin_optab = init_optab (SMIN);
5266 smax_optab = init_optab (SMAX);
5267 umin_optab = init_optab (UMIN);
5268 umax_optab = init_optab (UMAX);
5269 pow_optab = init_optab (UNKNOWN);
5270 atan2_optab = init_optab (UNKNOWN);
5272 /* These three have codes assigned exclusively for the sake of
5274 mov_optab = init_optab (SET);
5275 movstrict_optab = init_optab (STRICT_LOW_PART);
5276 cmp_optab = init_optab (COMPARE);
5278 ucmp_optab = init_optab (UNKNOWN);
5279 tst_optab = init_optab (UNKNOWN);
5281 eq_optab = init_optab (EQ);
5282 ne_optab = init_optab (NE);
5283 gt_optab = init_optab (GT);
5284 ge_optab = init_optab (GE);
5285 lt_optab = init_optab (LT);
5286 le_optab = init_optab (LE);
5287 unord_optab = init_optab (UNORDERED);
5289 neg_optab = init_optab (NEG);
5290 negv_optab = init_optabv (NEG);
5291 abs_optab = init_optab (ABS);
5292 absv_optab = init_optabv (ABS);
5293 addcc_optab = init_optab (UNKNOWN);
5294 one_cmpl_optab = init_optab (NOT);
5295 ffs_optab = init_optab (FFS);
5296 clz_optab = init_optab (CLZ);
5297 ctz_optab = init_optab (CTZ);
5298 popcount_optab = init_optab (POPCOUNT);
5299 parity_optab = init_optab (PARITY);
5300 sqrt_optab = init_optab (SQRT);
5301 floor_optab = init_optab (UNKNOWN);
5302 ceil_optab = init_optab (UNKNOWN);
5303 round_optab = init_optab (UNKNOWN);
5304 btrunc_optab = init_optab (UNKNOWN);
5305 nearbyint_optab = init_optab (UNKNOWN);
5306 rint_optab = init_optab (UNKNOWN);
5307 sincos_optab = init_optab (UNKNOWN);
5308 sin_optab = init_optab (UNKNOWN);
5309 asin_optab = init_optab (UNKNOWN);
5310 cos_optab = init_optab (UNKNOWN);
5311 acos_optab = init_optab (UNKNOWN);
5312 exp_optab = init_optab (UNKNOWN);
5313 exp10_optab = init_optab (UNKNOWN);
5314 exp2_optab = init_optab (UNKNOWN);
5315 expm1_optab = init_optab (UNKNOWN);
5316 ldexp_optab = init_optab (UNKNOWN);
5317 logb_optab = init_optab (UNKNOWN);
5318 ilogb_optab = init_optab (UNKNOWN);
5319 log_optab = init_optab (UNKNOWN);
5320 log10_optab = init_optab (UNKNOWN);
5321 log2_optab = init_optab (UNKNOWN);
5322 log1p_optab = init_optab (UNKNOWN);
5323 tan_optab = init_optab (UNKNOWN);
5324 atan_optab = init_optab (UNKNOWN);
5325 copysign_optab = init_optab (UNKNOWN);
5327 strlen_optab = init_optab (UNKNOWN);
5328 cbranch_optab = init_optab (UNKNOWN);
5329 cmov_optab = init_optab (UNKNOWN);
5330 cstore_optab = init_optab (UNKNOWN);
5331 push_optab = init_optab (UNKNOWN);
5333 reduc_smax_optab = init_optab (UNKNOWN);
5334 reduc_umax_optab = init_optab (UNKNOWN);
5335 reduc_smin_optab = init_optab (UNKNOWN);
5336 reduc_umin_optab = init_optab (UNKNOWN);
5337 reduc_splus_optab = init_optab (UNKNOWN);
5338 reduc_uplus_optab = init_optab (UNKNOWN);
5340 ssum_widen_optab = init_optab (UNKNOWN);
5341 usum_widen_optab = init_optab (UNKNOWN);
5342 sdot_prod_optab = init_optab (UNKNOWN);
5343 udot_prod_optab = init_optab (UNKNOWN);
5345 vec_extract_optab = init_optab (UNKNOWN);
5346 vec_set_optab = init_optab (UNKNOWN);
5347 vec_init_optab = init_optab (UNKNOWN);
5348 vec_shl_optab = init_optab (UNKNOWN);
5349 vec_shr_optab = init_optab (UNKNOWN);
5350 vec_realign_load_optab = init_optab (UNKNOWN);
5351 movmisalign_optab = init_optab (UNKNOWN);
5353 powi_optab = init_optab (UNKNOWN);
5356 sext_optab = init_convert_optab (SIGN_EXTEND);
5357 zext_optab = init_convert_optab (ZERO_EXTEND);
5358 trunc_optab = init_convert_optab (TRUNCATE);
5359 sfix_optab = init_convert_optab (FIX);
5360 ufix_optab = init_convert_optab (UNSIGNED_FIX);
5361 sfixtrunc_optab = init_convert_optab (UNKNOWN);
5362 ufixtrunc_optab = init_convert_optab (UNKNOWN);
5363 sfloat_optab = init_convert_optab (FLOAT);
5364 ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
5365 lrint_optab = init_convert_optab (UNKNOWN);
5366 lround_optab = init_convert_optab (UNKNOWN);
5367 lfloor_optab = init_convert_optab (UNKNOWN);
5368 lceil_optab = init_convert_optab (UNKNOWN);
5370 for (i = 0; i < NUM_MACHINE_MODES; i++)
5372 movmem_optab[i] = CODE_FOR_nothing;
5373 cmpstr_optab[i] = CODE_FOR_nothing;
5374 cmpstrn_optab[i] = CODE_FOR_nothing;
5375 cmpmem_optab[i] = CODE_FOR_nothing;
5376 setmem_optab[i] = CODE_FOR_nothing;
5378 sync_add_optab[i] = CODE_FOR_nothing;
5379 sync_sub_optab[i] = CODE_FOR_nothing;
5380 sync_ior_optab[i] = CODE_FOR_nothing;
5381 sync_and_optab[i] = CODE_FOR_nothing;
5382 sync_xor_optab[i] = CODE_FOR_nothing;
5383 sync_nand_optab[i] = CODE_FOR_nothing;
5384 sync_old_add_optab[i] = CODE_FOR_nothing;
5385 sync_old_sub_optab[i] = CODE_FOR_nothing;
5386 sync_old_ior_optab[i] = CODE_FOR_nothing;
5387 sync_old_and_optab[i] = CODE_FOR_nothing;
5388 sync_old_xor_optab[i] = CODE_FOR_nothing;
5389 sync_old_nand_optab[i] = CODE_FOR_nothing;
5390 sync_new_add_optab[i] = CODE_FOR_nothing;
5391 sync_new_sub_optab[i] = CODE_FOR_nothing;
5392 sync_new_ior_optab[i] = CODE_FOR_nothing;
5393 sync_new_and_optab[i] = CODE_FOR_nothing;
5394 sync_new_xor_optab[i] = CODE_FOR_nothing;
5395 sync_new_nand_optab[i] = CODE_FOR_nothing;
5396 sync_compare_and_swap[i] = CODE_FOR_nothing;
5397 sync_compare_and_swap_cc[i] = CODE_FOR_nothing;
5398 sync_lock_test_and_set[i] = CODE_FOR_nothing;
5399 sync_lock_release[i] = CODE_FOR_nothing;
5401 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5404 /* Fill in the optabs with the insns we support. */
5407 /* Initialize the optabs with the names of the library functions. */
5408 init_integral_libfuncs (add_optab, "add", '3');
5409 init_floating_libfuncs (add_optab, "add", '3');
5410 init_integral_libfuncs (addv_optab, "addv", '3');
5411 init_floating_libfuncs (addv_optab, "add", '3');
5412 init_integral_libfuncs (sub_optab, "sub", '3');
5413 init_floating_libfuncs (sub_optab, "sub", '3');
5414 init_integral_libfuncs (subv_optab, "subv", '3');
5415 init_floating_libfuncs (subv_optab, "sub", '3');
5416 init_integral_libfuncs (smul_optab, "mul", '3');
5417 init_floating_libfuncs (smul_optab, "mul", '3');
5418 init_integral_libfuncs (smulv_optab, "mulv", '3');
5419 init_floating_libfuncs (smulv_optab, "mul", '3');
5420 init_integral_libfuncs (sdiv_optab, "div", '3');
5421 init_floating_libfuncs (sdiv_optab, "div", '3');
5422 init_integral_libfuncs (sdivv_optab, "divv", '3');
5423 init_integral_libfuncs (udiv_optab, "udiv", '3');
5424 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5425 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5426 init_integral_libfuncs (smod_optab, "mod", '3');
5427 init_integral_libfuncs (umod_optab, "umod", '3');
5428 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5429 init_integral_libfuncs (and_optab, "and", '3');
5430 init_integral_libfuncs (ior_optab, "ior", '3');
5431 init_integral_libfuncs (xor_optab, "xor", '3');
5432 init_integral_libfuncs (ashl_optab, "ashl", '3');
5433 init_integral_libfuncs (ashr_optab, "ashr", '3');
5434 init_integral_libfuncs (lshr_optab, "lshr", '3');
5435 init_integral_libfuncs (smin_optab, "min", '3');
5436 init_floating_libfuncs (smin_optab, "min", '3');
5437 init_integral_libfuncs (smax_optab, "max", '3');
5438 init_floating_libfuncs (smax_optab, "max", '3');
5439 init_integral_libfuncs (umin_optab, "umin", '3');
5440 init_integral_libfuncs (umax_optab, "umax", '3');
5441 init_integral_libfuncs (neg_optab, "neg", '2');
5442 init_floating_libfuncs (neg_optab, "neg", '2');
5443 init_integral_libfuncs (negv_optab, "negv", '2');
5444 init_floating_libfuncs (negv_optab, "neg", '2');
5445 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5446 init_integral_libfuncs (ffs_optab, "ffs", '2');
5447 init_integral_libfuncs (clz_optab, "clz", '2');
5448 init_integral_libfuncs (ctz_optab, "ctz", '2');
5449 init_integral_libfuncs (popcount_optab, "popcount", '2');
5450 init_integral_libfuncs (parity_optab, "parity", '2');
5452 /* Comparison libcalls for integers MUST come in pairs,
5454 init_integral_libfuncs (cmp_optab, "cmp", '2');
5455 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5456 init_floating_libfuncs (cmp_optab, "cmp", '2');
5458 /* EQ etc are floating point only. */
5459 init_floating_libfuncs (eq_optab, "eq", '2');
5460 init_floating_libfuncs (ne_optab, "ne", '2');
5461 init_floating_libfuncs (gt_optab, "gt", '2');
5462 init_floating_libfuncs (ge_optab, "ge", '2');
5463 init_floating_libfuncs (lt_optab, "lt", '2');
5464 init_floating_libfuncs (le_optab, "le", '2');
5465 init_floating_libfuncs (unord_optab, "unord", '2');
5467 init_floating_libfuncs (powi_optab, "powi", '2');
5470 init_interclass_conv_libfuncs (sfloat_optab, "float",
5471 MODE_INT, MODE_FLOAT);
5472 init_interclass_conv_libfuncs (sfloat_optab, "float",
5473 MODE_INT, MODE_DECIMAL_FLOAT);
5474 init_interclass_conv_libfuncs (ufloat_optab, "floatun",
5475 MODE_INT, MODE_FLOAT);
5476 init_interclass_conv_libfuncs (ufloat_optab, "floatun",
5477 MODE_INT, MODE_DECIMAL_FLOAT);
5478 init_interclass_conv_libfuncs (sfix_optab, "fix",
5479 MODE_FLOAT, MODE_INT);
5480 init_interclass_conv_libfuncs (sfix_optab, "fix",
5481 MODE_DECIMAL_FLOAT, MODE_INT);
5482 init_interclass_conv_libfuncs (ufix_optab, "fixuns",
5483 MODE_FLOAT, MODE_INT);
5484 init_interclass_conv_libfuncs (ufix_optab, "fixuns",
5485 MODE_DECIMAL_FLOAT, MODE_INT);
5486 init_interclass_conv_libfuncs (ufloat_optab, "floatuns",
5487 MODE_INT, MODE_DECIMAL_FLOAT);
5488 init_interclass_conv_libfuncs (lrint_optab, "lrint",
5489 MODE_INT, MODE_FLOAT);
5490 init_interclass_conv_libfuncs (lround_optab, "lround",
5491 MODE_INT, MODE_FLOAT);
5492 init_interclass_conv_libfuncs (lfloor_optab, "lfloor",
5493 MODE_INT, MODE_FLOAT);
5494 init_interclass_conv_libfuncs (lceil_optab, "lceil",
5495 MODE_INT, MODE_FLOAT);
5497 /* sext_optab is also used for FLOAT_EXTEND. */
5498 init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
5499 init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, true);
5500 init_interclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, MODE_DECIMAL_FLOAT);
5501 init_interclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, MODE_FLOAT);
5502 init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
5503 init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, false);
5504 init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, MODE_DECIMAL_FLOAT);
5505 init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, MODE_FLOAT);
5507 /* Use cabs for double complex abs, since systems generally have cabs.
5508 Don't define any libcall for float complex, so that cabs will be used. */
5509 if (complex_double_type_node)
5510 abs_optab->handlers[TYPE_MODE (complex_double_type_node)].libfunc
5511 = init_one_libfunc ("cabs");
5513 /* The ffs function operates on `int'. */
5514 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5515 = init_one_libfunc ("ffs");
5517 abort_libfunc = init_one_libfunc ("abort");
5518 memcpy_libfunc = init_one_libfunc ("memcpy");
5519 memmove_libfunc = init_one_libfunc ("memmove");
5520 memcmp_libfunc = init_one_libfunc ("memcmp");
5521 memset_libfunc = init_one_libfunc ("memset");
5522 setbits_libfunc = init_one_libfunc ("__setbits");
5524 #ifndef DONT_USE_BUILTIN_SETJMP
5525 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5526 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5528 setjmp_libfunc = init_one_libfunc ("setjmp");
5529 longjmp_libfunc = init_one_libfunc ("longjmp");
5531 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5532 unwind_sjlj_unregister_libfunc
5533 = init_one_libfunc ("_Unwind_SjLj_Unregister");
5535 /* For function entry/exit instrumentation. */
5536 profile_function_entry_libfunc
5537 = init_one_libfunc ("__cyg_profile_func_enter");
5538 profile_function_exit_libfunc
5539 = init_one_libfunc ("__cyg_profile_func_exit");
5541 gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
5543 if (HAVE_conditional_trap)
5544 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5546 /* Allow the target to add more libcalls or rename some, etc. */
5547 targetm.init_libfuncs ();
5552 /* Print information about the current contents of the optabs on
5556 debug_optab_libfuncs (void)
5562 /* Dump the arithmetic optabs. */
5563 for (i = 0; i != (int) OTI_MAX; i++)
5564 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5567 struct optab_handlers *h;
5570 h = &o->handlers[j];
5573 gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5574 fprintf (stderr, "%s\t%s:\t%s\n",
5575 GET_RTX_NAME (o->code),
5577 XSTR (h->libfunc, 0));
5581 /* Dump the conversion optabs. */
5582 for (i = 0; i < (int) COI_MAX; ++i)
5583 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5584 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5587 struct optab_handlers *h;
5589 o = &convert_optab_table[i];
5590 h = &o->handlers[j][k];
5593 gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5594 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5595 GET_RTX_NAME (o->code),
5598 XSTR (h->libfunc, 0));
5606 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5607 CODE. Return 0 on failure. */
5610 gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
5611 rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
5613 enum machine_mode mode = GET_MODE (op1);
5614 enum insn_code icode;
5617 if (!HAVE_conditional_trap)
5620 if (mode == VOIDmode)
5623 icode = cmp_optab->handlers[(int) mode].insn_code;
5624 if (icode == CODE_FOR_nothing)
5628 op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
5629 op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
5635 emit_insn (GEN_FCN (icode) (op1, op2));
5637 PUT_CODE (trap_rtx, code);
5638 gcc_assert (HAVE_conditional_trap);
5639 insn = gen_conditional_trap (trap_rtx, tcode);
5643 insn = get_insns ();
5650 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5651 or unsigned operation code. */
5653 static enum rtx_code
5654 get_rtx_code (enum tree_code tcode, bool unsignedp)
5666 code = unsignedp ? LTU : LT;
5669 code = unsignedp ? LEU : LE;
5672 code = unsignedp ? GTU : GT;
5675 code = unsignedp ? GEU : GE;
5678 case UNORDERED_EXPR:
5709 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
5710 unsigned operators. Do not generate compare instruction. */
5713 vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
5715 enum rtx_code rcode;
5717 rtx rtx_op0, rtx_op1;
5719 /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
5720 ensures that condition is a relational operation. */
5721 gcc_assert (COMPARISON_CLASS_P (cond));
5723 rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
5724 t_op0 = TREE_OPERAND (cond, 0);
5725 t_op1 = TREE_OPERAND (cond, 1);
5727 /* Expand operands. */
5728 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)), 1);
5729 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)), 1);
5731 if (!insn_data[icode].operand[4].predicate (rtx_op0, GET_MODE (rtx_op0))
5732 && GET_MODE (rtx_op0) != VOIDmode)
5733 rtx_op0 = force_reg (GET_MODE (rtx_op0), rtx_op0);
5735 if (!insn_data[icode].operand[5].predicate (rtx_op1, GET_MODE (rtx_op1))
5736 && GET_MODE (rtx_op1) != VOIDmode)
5737 rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
5739 return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1);
5742 /* Return insn code for VEC_COND_EXPR EXPR. */
5744 static inline enum insn_code
5745 get_vcond_icode (tree expr, enum machine_mode mode)
5747 enum insn_code icode = CODE_FOR_nothing;
5749 if (TYPE_UNSIGNED (TREE_TYPE (expr)))
5750 icode = vcondu_gen_code[mode];
5752 icode = vcond_gen_code[mode];
5756 /* Return TRUE iff, appropriate vector insns are available
5757 for vector cond expr expr in VMODE mode. */
5760 expand_vec_cond_expr_p (tree expr, enum machine_mode vmode)
5762 if (get_vcond_icode (expr, vmode) == CODE_FOR_nothing)
5767 /* Generate insns for VEC_COND_EXPR. */
5770 expand_vec_cond_expr (tree vec_cond_expr, rtx target)
5772 enum insn_code icode;
5773 rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1;
5774 enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_cond_expr));
5775 bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr));
5777 icode = get_vcond_icode (vec_cond_expr, mode);
5778 if (icode == CODE_FOR_nothing)
5781 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5782 target = gen_reg_rtx (mode);
5784 /* Get comparison rtx. First expand both cond expr operands. */
5785 comparison = vector_compare_rtx (TREE_OPERAND (vec_cond_expr, 0),
5787 cc_op0 = XEXP (comparison, 0);
5788 cc_op1 = XEXP (comparison, 1);
5789 /* Expand both operands and force them in reg, if required. */
5790 rtx_op1 = expand_expr (TREE_OPERAND (vec_cond_expr, 1),
5791 NULL_RTX, VOIDmode, EXPAND_NORMAL);
5792 if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
5793 && mode != VOIDmode)
5794 rtx_op1 = force_reg (mode, rtx_op1);
5796 rtx_op2 = expand_expr (TREE_OPERAND (vec_cond_expr, 2),
5797 NULL_RTX, VOIDmode, EXPAND_NORMAL);
5798 if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
5799 && mode != VOIDmode)
5800 rtx_op2 = force_reg (mode, rtx_op2);
5802 /* Emit instruction! */
5803 emit_insn (GEN_FCN (icode) (target, rtx_op1, rtx_op2,
5804 comparison, cc_op0, cc_op1));
5810 /* This is an internal subroutine of the other compare_and_swap expanders.
5811 MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
5812 operation. TARGET is an optional place to store the value result of
5813 the operation. ICODE is the particular instruction to expand. Return
5814 the result of the operation. */
5817 expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
5818 rtx target, enum insn_code icode)
5820 enum machine_mode mode = GET_MODE (mem);
5823 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5824 target = gen_reg_rtx (mode);
5826 if (GET_MODE (old_val) != VOIDmode && GET_MODE (old_val) != mode)
5827 old_val = convert_modes (mode, GET_MODE (old_val), old_val, 1);
5828 if (!insn_data[icode].operand[2].predicate (old_val, mode))
5829 old_val = force_reg (mode, old_val);
5831 if (GET_MODE (new_val) != VOIDmode && GET_MODE (new_val) != mode)
5832 new_val = convert_modes (mode, GET_MODE (new_val), new_val, 1);
5833 if (!insn_data[icode].operand[3].predicate (new_val, mode))
5834 new_val = force_reg (mode, new_val);
5836 insn = GEN_FCN (icode) (target, mem, old_val, new_val);
5837 if (insn == NULL_RTX)
5844 /* Expand a compare-and-swap operation and return its value. */
5847 expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5849 enum machine_mode mode = GET_MODE (mem);
5850 enum insn_code icode = sync_compare_and_swap[mode];
5852 if (icode == CODE_FOR_nothing)
5855 return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
5858 /* Expand a compare-and-swap operation and store true into the result if
5859 the operation was successful and false otherwise. Return the result.
5860 Unlike other routines, TARGET is not optional. */
5863 expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5865 enum machine_mode mode = GET_MODE (mem);
5866 enum insn_code icode;
5867 rtx subtarget, label0, label1;
5869 /* If the target supports a compare-and-swap pattern that simultaneously
5870 sets some flag for success, then use it. Otherwise use the regular
5871 compare-and-swap and follow that immediately with a compare insn. */
5872 icode = sync_compare_and_swap_cc[mode];
5876 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5878 if (subtarget != NULL_RTX)
5882 case CODE_FOR_nothing:
5883 icode = sync_compare_and_swap[mode];
5884 if (icode == CODE_FOR_nothing)
5887 /* Ensure that if old_val == mem, that we're not comparing
5888 against an old value. */
5889 if (MEM_P (old_val))
5890 old_val = force_reg (mode, old_val);
5892 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5894 if (subtarget == NULL_RTX)
5897 emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
5900 /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
5901 setcc instruction from the beginning. We don't work too hard here,
5902 but it's nice to not be stupid about initial code gen either. */
5903 if (STORE_FLAG_VALUE == 1)
5905 icode = setcc_gen_code[EQ];
5906 if (icode != CODE_FOR_nothing)
5908 enum machine_mode cmode = insn_data[icode].operand[0].mode;
5912 if (!insn_data[icode].operand[0].predicate (target, cmode))
5913 subtarget = gen_reg_rtx (cmode);
5915 insn = GEN_FCN (icode) (subtarget);
5919 if (GET_MODE (target) != GET_MODE (subtarget))
5921 convert_move (target, subtarget, 1);
5929 /* Without an appropriate setcc instruction, use a set of branches to
5930 get 1 and 0 stored into target. Presumably if the target has a
5931 STORE_FLAG_VALUE that isn't 1, then this will get cleaned up by ifcvt. */
5933 label0 = gen_label_rtx ();
5934 label1 = gen_label_rtx ();
5936 emit_jump_insn (bcc_gen_fctn[EQ] (label0));
5937 emit_move_insn (target, const0_rtx);
5938 emit_jump_insn (gen_jump (label1));
5940 emit_label (label0);
5941 emit_move_insn (target, const1_rtx);
5942 emit_label (label1);
5947 /* This is a helper function for the other atomic operations. This function
5948 emits a loop that contains SEQ that iterates until a compare-and-swap
5949 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5950 a set of instructions that takes a value from OLD_REG as an input and
5951 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5952 set to the current contents of MEM. After SEQ, a compare-and-swap will
5953 attempt to update MEM with NEW_REG. The function returns true when the
5954 loop was generated successfully. */
5957 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5959 enum machine_mode mode = GET_MODE (mem);
5960 enum insn_code icode;
5961 rtx label, cmp_reg, subtarget;
5963 /* The loop we want to generate looks like
5969 cmp_reg = compare-and-swap(mem, old_reg, new_reg)
5970 if (cmp_reg != old_reg)
5973 Note that we only do the plain load from memory once. Subsequent
5974 iterations use the value loaded by the compare-and-swap pattern. */
5976 label = gen_label_rtx ();
5977 cmp_reg = gen_reg_rtx (mode);
5979 emit_move_insn (cmp_reg, mem);
5981 emit_move_insn (old_reg, cmp_reg);
5985 /* If the target supports a compare-and-swap pattern that simultaneously
5986 sets some flag for success, then use it. Otherwise use the regular
5987 compare-and-swap and follow that immediately with a compare insn. */
5988 icode = sync_compare_and_swap_cc[mode];
5992 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
5994 if (subtarget != NULL_RTX)
5996 gcc_assert (subtarget == cmp_reg);
6001 case CODE_FOR_nothing:
6002 icode = sync_compare_and_swap[mode];
6003 if (icode == CODE_FOR_nothing)
6006 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
6008 if (subtarget == NULL_RTX)
6010 if (subtarget != cmp_reg)
6011 emit_move_insn (cmp_reg, subtarget);
6013 emit_cmp_insn (cmp_reg, old_reg, EQ, const0_rtx, mode, true);
6016 /* ??? Mark this jump predicted not taken? */
6017 emit_jump_insn (bcc_gen_fctn[NE] (label));
6022 /* This function generates the atomic operation MEM CODE= VAL. In this
6023 case, we do not care about any resulting value. Returns NULL if we
6024 cannot generate the operation. */
6027 expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
6029 enum machine_mode mode = GET_MODE (mem);
6030 enum insn_code icode;
6033 /* Look to see if the target supports the operation directly. */
6037 icode = sync_add_optab[mode];
6040 icode = sync_ior_optab[mode];
6043 icode = sync_xor_optab[mode];
6046 icode = sync_and_optab[mode];
6049 icode = sync_nand_optab[mode];
6053 icode = sync_sub_optab[mode];
6054 if (icode == CODE_FOR_nothing)
6056 icode = sync_add_optab[mode];
6057 if (icode != CODE_FOR_nothing)
6059 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6069 /* Generate the direct operation, if present. */
6070 if (icode != CODE_FOR_nothing)
6072 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6073 val = convert_modes (mode, GET_MODE (val), val, 1);
6074 if (!insn_data[icode].operand[1].predicate (val, mode))
6075 val = force_reg (mode, val);
6077 insn = GEN_FCN (icode) (mem, val);
6085 /* Failing that, generate a compare-and-swap loop in which we perform the
6086 operation with normal arithmetic instructions. */
6087 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6089 rtx t0 = gen_reg_rtx (mode), t1;
6096 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
6099 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6100 true, OPTAB_LIB_WIDEN);
6102 insn = get_insns ();
6105 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6112 /* This function generates the atomic operation MEM CODE= VAL. In this
6113 case, we do care about the resulting value: if AFTER is true then
6114 return the value MEM holds after the operation, if AFTER is false
6115 then return the value MEM holds before the operation. TARGET is an
6116 optional place for the result value to be stored. */
6119 expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
6120 bool after, rtx target)
6122 enum machine_mode mode = GET_MODE (mem);
6123 enum insn_code old_code, new_code, icode;
6127 /* Look to see if the target supports the operation directly. */
6131 old_code = sync_old_add_optab[mode];
6132 new_code = sync_new_add_optab[mode];
6135 old_code = sync_old_ior_optab[mode];
6136 new_code = sync_new_ior_optab[mode];
6139 old_code = sync_old_xor_optab[mode];
6140 new_code = sync_new_xor_optab[mode];
6143 old_code = sync_old_and_optab[mode];
6144 new_code = sync_new_and_optab[mode];
6147 old_code = sync_old_nand_optab[mode];
6148 new_code = sync_new_nand_optab[mode];
6152 old_code = sync_old_sub_optab[mode];
6153 new_code = sync_new_sub_optab[mode];
6154 if (old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
6156 old_code = sync_old_add_optab[mode];
6157 new_code = sync_new_add_optab[mode];
6158 if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
6160 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6170 /* If the target does supports the proper new/old operation, great. But
6171 if we only support the opposite old/new operation, check to see if we
6172 can compensate. In the case in which the old value is supported, then
6173 we can always perform the operation again with normal arithmetic. In
6174 the case in which the new value is supported, then we can only handle
6175 this in the case the operation is reversible. */
6180 if (icode == CODE_FOR_nothing)
6183 if (icode != CODE_FOR_nothing)
6190 if (icode == CODE_FOR_nothing
6191 && (code == PLUS || code == MINUS || code == XOR))
6194 if (icode != CODE_FOR_nothing)
6199 /* If we found something supported, great. */
6200 if (icode != CODE_FOR_nothing)
6202 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6203 target = gen_reg_rtx (mode);
6205 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6206 val = convert_modes (mode, GET_MODE (val), val, 1);
6207 if (!insn_data[icode].operand[2].predicate (val, mode))
6208 val = force_reg (mode, val);
6210 insn = GEN_FCN (icode) (target, mem, val);
6215 /* If we need to compensate for using an operation with the
6216 wrong return value, do so now. */
6223 else if (code == MINUS)
6228 target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
6229 target = expand_simple_binop (mode, code, target, val, NULL_RTX,
6230 true, OPTAB_LIB_WIDEN);
6237 /* Failing that, generate a compare-and-swap loop in which we perform the
6238 operation with normal arithmetic instructions. */
6239 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6241 rtx t0 = gen_reg_rtx (mode), t1;
6243 if (!target || !register_operand (target, mode))
6244 target = gen_reg_rtx (mode);
6249 emit_move_insn (target, t0);
6253 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
6256 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6257 true, OPTAB_LIB_WIDEN);
6259 emit_move_insn (target, t1);
6261 insn = get_insns ();
6264 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6271 /* This function expands a test-and-set operation. Ideally we atomically
6272 store VAL in MEM and return the previous value in MEM. Some targets
6273 may not support this operation and only support VAL with the constant 1;
6274 in this case while the return value will be 0/1, but the exact value
6275 stored in MEM is target defined. TARGET is an option place to stick
6276 the return value. */
6279 expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
6281 enum machine_mode mode = GET_MODE (mem);
6282 enum insn_code icode;
6285 /* If the target supports the test-and-set directly, great. */
6286 icode = sync_lock_test_and_set[mode];
6287 if (icode != CODE_FOR_nothing)
6289 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6290 target = gen_reg_rtx (mode);
6292 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6293 val = convert_modes (mode, GET_MODE (val), val, 1);
6294 if (!insn_data[icode].operand[2].predicate (val, mode))
6295 val = force_reg (mode, val);
6297 insn = GEN_FCN (icode) (target, mem, val);
6305 /* Otherwise, use a compare-and-swap loop for the exchange. */
6306 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6308 if (!target || !register_operand (target, mode))
6309 target = gen_reg_rtx (mode);
6310 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6311 val = convert_modes (mode, GET_MODE (val), val, 1);
6312 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6319 #include "gt-optabs.h"