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, 2007, 2008, 2009
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
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 #if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
58 __extension__
struct optab_d optab_table
[OTI_MAX
]
59 = { [0 ... OTI_MAX
- 1].handlers
[0 ... NUM_MACHINE_MODES
- 1].insn_code
62 /* init_insn_codes will do runtime initialization otherwise. */
63 struct optab_d optab_table
[OTI_MAX
];
66 rtx libfunc_table
[LTI_MAX
];
68 /* Tables of patterns for converting one mode to another. */
69 #if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
70 __extension__
struct convert_optab_d convert_optab_table
[COI_MAX
]
71 = { [0 ... COI_MAX
- 1].handlers
[0 ... NUM_MACHINE_MODES
- 1]
72 [0 ... NUM_MACHINE_MODES
- 1].insn_code
75 /* init_convert_optab will do runtime initialization otherwise. */
76 struct convert_optab_d convert_optab_table
[COI_MAX
];
79 /* Contains the optab used for each rtx code. */
80 optab code_to_optab
[NUM_RTX_CODE
+ 1];
82 #ifdef HAVE_conditional_move
83 /* Indexed by the machine mode, gives the insn code to make a conditional
84 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
85 setcc_gen_code to cut down on the number of named patterns. Consider a day
86 when a lot more rtx codes are conditional (eg: for the ARM). */
88 enum insn_code movcc_gen_code
[NUM_MACHINE_MODES
];
91 /* Indexed by the machine mode, gives the insn code for vector conditional
94 enum insn_code vcond_gen_code
[NUM_MACHINE_MODES
];
95 enum insn_code vcondu_gen_code
[NUM_MACHINE_MODES
];
97 static void prepare_float_lib_cmp (rtx
, rtx
, enum rtx_code
, rtx
*,
99 static rtx
expand_unop_direct (enum machine_mode
, optab
, rtx
, rtx
, int);
101 /* Debug facility for use in GDB. */
102 void debug_optab_libfuncs (void);
104 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
105 #if ENABLE_DECIMAL_BID_FORMAT
106 #define DECIMAL_PREFIX "bid_"
108 #define DECIMAL_PREFIX "dpd_"
112 /* Info about libfunc. We use same hashtable for normal optabs and conversion
113 optab. In the first case mode2 is unused. */
114 struct GTY(()) libfunc_entry
{
116 enum machine_mode mode1
, mode2
;
120 /* Hash table used to convert declarations into nodes. */
121 static GTY((param_is (struct libfunc_entry
))) htab_t libfunc_hash
;
123 /* Used for attribute_hash. */
126 hash_libfunc (const void *p
)
128 const struct libfunc_entry
*const e
= (const struct libfunc_entry
*) p
;
130 return (((int) e
->mode1
+ (int) e
->mode2
* NUM_MACHINE_MODES
)
134 /* Used for optab_hash. */
137 eq_libfunc (const void *p
, const void *q
)
139 const struct libfunc_entry
*const e1
= (const struct libfunc_entry
*) p
;
140 const struct libfunc_entry
*const e2
= (const struct libfunc_entry
*) q
;
142 return (e1
->optab
== e2
->optab
143 && e1
->mode1
== e2
->mode1
144 && e1
->mode2
== e2
->mode2
);
147 /* Return libfunc corresponding operation defined by OPTAB converting
148 from MODE2 to MODE1. Trigger lazy initialization if needed, return NULL
149 if no libfunc is available. */
151 convert_optab_libfunc (convert_optab optab
, enum machine_mode mode1
,
152 enum machine_mode mode2
)
154 struct libfunc_entry e
;
155 struct libfunc_entry
**slot
;
157 e
.optab
= (size_t) (optab
- &convert_optab_table
[0]);
160 slot
= (struct libfunc_entry
**) htab_find_slot (libfunc_hash
, &e
, NO_INSERT
);
163 if (optab
->libcall_gen
)
165 optab
->libcall_gen (optab
, optab
->libcall_basename
, mode1
, mode2
);
166 slot
= (struct libfunc_entry
**) htab_find_slot (libfunc_hash
, &e
, NO_INSERT
);
168 return (*slot
)->libfunc
;
174 return (*slot
)->libfunc
;
177 /* Return libfunc corresponding operation defined by OPTAB in MODE.
178 Trigger lazy initialization if needed, return NULL if no libfunc is
181 optab_libfunc (optab optab
, enum machine_mode mode
)
183 struct libfunc_entry e
;
184 struct libfunc_entry
**slot
;
186 e
.optab
= (size_t) (optab
- &optab_table
[0]);
189 slot
= (struct libfunc_entry
**) htab_find_slot (libfunc_hash
, &e
, NO_INSERT
);
192 if (optab
->libcall_gen
)
194 optab
->libcall_gen (optab
, optab
->libcall_basename
,
195 optab
->libcall_suffix
, mode
);
196 slot
= (struct libfunc_entry
**) htab_find_slot (libfunc_hash
,
199 return (*slot
)->libfunc
;
205 return (*slot
)->libfunc
;
209 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
210 the result of operation CODE applied to OP0 (and OP1 if it is a binary
213 If the last insn does not set TARGET, don't do anything, but return 1.
215 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
216 don't add the REG_EQUAL note but return 0. Our caller can then try
217 again, ensuring that TARGET is not one of the operands. */
220 add_equal_note (rtx insns
, rtx target
, enum rtx_code code
, rtx op0
, rtx op1
)
222 rtx last_insn
, insn
, set
;
225 gcc_assert (insns
&& INSN_P (insns
) && NEXT_INSN (insns
));
227 if (GET_RTX_CLASS (code
) != RTX_COMM_ARITH
228 && GET_RTX_CLASS (code
) != RTX_BIN_ARITH
229 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
230 && GET_RTX_CLASS (code
) != RTX_COMPARE
231 && GET_RTX_CLASS (code
) != RTX_UNARY
)
234 if (GET_CODE (target
) == ZERO_EXTRACT
)
237 for (last_insn
= insns
;
238 NEXT_INSN (last_insn
) != NULL_RTX
;
239 last_insn
= NEXT_INSN (last_insn
))
242 set
= single_set (last_insn
);
246 if (! rtx_equal_p (SET_DEST (set
), target
)
247 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
248 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
249 || ! rtx_equal_p (XEXP (SET_DEST (set
), 0), target
)))
252 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
253 besides the last insn. */
254 if (reg_overlap_mentioned_p (target
, op0
)
255 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
257 insn
= PREV_INSN (last_insn
);
258 while (insn
!= NULL_RTX
)
260 if (reg_set_p (target
, insn
))
263 insn
= PREV_INSN (insn
);
267 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
268 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
270 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
272 set_unique_reg_note (last_insn
, REG_EQUAL
, note
);
277 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
278 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
279 not actually do a sign-extend or zero-extend, but can leave the
280 higher-order bits of the result rtx undefined, for example, in the case
281 of logical operations, but not right shifts. */
284 widen_operand (rtx op
, enum machine_mode mode
, enum machine_mode oldmode
,
285 int unsignedp
, int no_extend
)
289 /* If we don't have to extend and this is a constant, return it. */
290 if (no_extend
&& GET_MODE (op
) == VOIDmode
)
293 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
294 extend since it will be more efficient to do so unless the signedness of
295 a promoted object differs from our extension. */
297 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)
298 && SUBREG_PROMOTED_UNSIGNED_P (op
) == unsignedp
))
299 return convert_modes (mode
, oldmode
, op
, unsignedp
);
301 /* If MODE is no wider than a single word, we return a paradoxical
303 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
304 return gen_rtx_SUBREG (mode
, force_reg (GET_MODE (op
), op
), 0);
306 /* Otherwise, get an object of MODE, clobber it, and set the low-order
309 result
= gen_reg_rtx (mode
);
310 emit_clobber (result
);
311 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
315 /* Return the optab used for computing the operation given by the tree code,
316 CODE and the tree EXP. This function is not always usable (for example, it
317 cannot give complete results for multiplication or division) but probably
318 ought to be relied on more widely throughout the expander. */
320 optab_for_tree_code (enum tree_code code
, const_tree type
,
321 enum optab_subtype subtype
)
333 return one_cmpl_optab
;
342 return TYPE_UNSIGNED (type
) ? umod_optab
: smod_optab
;
350 if (TYPE_SATURATING(type
))
351 return TYPE_UNSIGNED(type
) ? usdiv_optab
: ssdiv_optab
;
352 return TYPE_UNSIGNED (type
) ? udiv_optab
: sdiv_optab
;
355 if (VECTOR_MODE_P (TYPE_MODE (type
)))
357 if (subtype
== optab_vector
)
358 return TYPE_SATURATING (type
) ? NULL
: vashl_optab
;
360 gcc_assert (subtype
== optab_scalar
);
362 if (TYPE_SATURATING(type
))
363 return TYPE_UNSIGNED(type
) ? usashl_optab
: ssashl_optab
;
367 if (VECTOR_MODE_P (TYPE_MODE (type
)))
369 if (subtype
== optab_vector
)
370 return TYPE_UNSIGNED (type
) ? vlshr_optab
: vashr_optab
;
372 gcc_assert (subtype
== optab_scalar
);
374 return TYPE_UNSIGNED (type
) ? lshr_optab
: ashr_optab
;
377 if (VECTOR_MODE_P (TYPE_MODE (type
)))
379 if (subtype
== optab_vector
)
382 gcc_assert (subtype
== optab_scalar
);
387 if (VECTOR_MODE_P (TYPE_MODE (type
)))
389 if (subtype
== optab_vector
)
392 gcc_assert (subtype
== optab_scalar
);
397 return TYPE_UNSIGNED (type
) ? umax_optab
: smax_optab
;
400 return TYPE_UNSIGNED (type
) ? umin_optab
: smin_optab
;
402 case REALIGN_LOAD_EXPR
:
403 return vec_realign_load_optab
;
406 return TYPE_UNSIGNED (type
) ? usum_widen_optab
: ssum_widen_optab
;
409 return TYPE_UNSIGNED (type
) ? udot_prod_optab
: sdot_prod_optab
;
412 return TYPE_UNSIGNED (type
) ? reduc_umax_optab
: reduc_smax_optab
;
415 return TYPE_UNSIGNED (type
) ? reduc_umin_optab
: reduc_smin_optab
;
417 case REDUC_PLUS_EXPR
:
418 return TYPE_UNSIGNED (type
) ? reduc_uplus_optab
: reduc_splus_optab
;
420 case VEC_LSHIFT_EXPR
:
421 return vec_shl_optab
;
423 case VEC_RSHIFT_EXPR
:
424 return vec_shr_optab
;
426 case VEC_WIDEN_MULT_HI_EXPR
:
427 return TYPE_UNSIGNED (type
) ?
428 vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
430 case VEC_WIDEN_MULT_LO_EXPR
:
431 return TYPE_UNSIGNED (type
) ?
432 vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
434 case VEC_UNPACK_HI_EXPR
:
435 return TYPE_UNSIGNED (type
) ?
436 vec_unpacku_hi_optab
: vec_unpacks_hi_optab
;
438 case VEC_UNPACK_LO_EXPR
:
439 return TYPE_UNSIGNED (type
) ?
440 vec_unpacku_lo_optab
: vec_unpacks_lo_optab
;
442 case VEC_UNPACK_FLOAT_HI_EXPR
:
443 /* The signedness is determined from input operand. */
444 return TYPE_UNSIGNED (type
) ?
445 vec_unpacku_float_hi_optab
: vec_unpacks_float_hi_optab
;
447 case VEC_UNPACK_FLOAT_LO_EXPR
:
448 /* The signedness is determined from input operand. */
449 return TYPE_UNSIGNED (type
) ?
450 vec_unpacku_float_lo_optab
: vec_unpacks_float_lo_optab
;
452 case VEC_PACK_TRUNC_EXPR
:
453 return vec_pack_trunc_optab
;
455 case VEC_PACK_SAT_EXPR
:
456 return TYPE_UNSIGNED (type
) ? vec_pack_usat_optab
: vec_pack_ssat_optab
;
458 case VEC_PACK_FIX_TRUNC_EXPR
:
459 /* The signedness is determined from output operand. */
460 return TYPE_UNSIGNED (type
) ?
461 vec_pack_ufix_trunc_optab
: vec_pack_sfix_trunc_optab
;
467 trapv
= INTEGRAL_TYPE_P (type
) && TYPE_OVERFLOW_TRAPS (type
);
470 case POINTER_PLUS_EXPR
:
472 if (TYPE_SATURATING(type
))
473 return TYPE_UNSIGNED(type
) ? usadd_optab
: ssadd_optab
;
474 return trapv
? addv_optab
: add_optab
;
477 if (TYPE_SATURATING(type
))
478 return TYPE_UNSIGNED(type
) ? ussub_optab
: sssub_optab
;
479 return trapv
? subv_optab
: sub_optab
;
482 if (TYPE_SATURATING(type
))
483 return TYPE_UNSIGNED(type
) ? usmul_optab
: ssmul_optab
;
484 return trapv
? smulv_optab
: smul_optab
;
487 if (TYPE_SATURATING(type
))
488 return TYPE_UNSIGNED(type
) ? usneg_optab
: ssneg_optab
;
489 return trapv
? negv_optab
: neg_optab
;
492 return trapv
? absv_optab
: abs_optab
;
494 case VEC_EXTRACT_EVEN_EXPR
:
495 return vec_extract_even_optab
;
497 case VEC_EXTRACT_ODD_EXPR
:
498 return vec_extract_odd_optab
;
500 case VEC_INTERLEAVE_HIGH_EXPR
:
501 return vec_interleave_high_optab
;
503 case VEC_INTERLEAVE_LOW_EXPR
:
504 return vec_interleave_low_optab
;
512 /* Expand vector widening operations.
514 There are two different classes of operations handled here:
515 1) Operations whose result is wider than all the arguments to the operation.
516 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
517 In this case OP0 and optionally OP1 would be initialized,
518 but WIDE_OP wouldn't (not relevant for this case).
519 2) Operations whose result is of the same size as the last argument to the
520 operation, but wider than all the other arguments to the operation.
521 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
522 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
524 E.g, when called to expand the following operations, this is how
525 the arguments will be initialized:
527 widening-sum 2 oprnd0 - oprnd1
528 widening-dot-product 3 oprnd0 oprnd1 oprnd2
529 widening-mult 2 oprnd0 oprnd1 -
530 type-promotion (vec-unpack) 1 oprnd0 - - */
533 expand_widen_pattern_expr (sepops ops
, rtx op0
, rtx op1
, rtx wide_op
,
534 rtx target
, int unsignedp
)
536 tree oprnd0
, oprnd1
, oprnd2
;
537 enum machine_mode wmode
= VOIDmode
, tmode0
, tmode1
= VOIDmode
;
538 optab widen_pattern_optab
;
540 enum machine_mode xmode0
, xmode1
= VOIDmode
, wxmode
= VOIDmode
;
543 rtx xop0
, xop1
, wxop
;
544 int nops
= TREE_CODE_LENGTH (ops
->code
);
547 tmode0
= TYPE_MODE (TREE_TYPE (oprnd0
));
548 widen_pattern_optab
=
549 optab_for_tree_code (ops
->code
, TREE_TYPE (oprnd0
), optab_default
);
550 icode
= (int) optab_handler (widen_pattern_optab
, tmode0
)->insn_code
;
551 gcc_assert (icode
!= CODE_FOR_nothing
);
552 xmode0
= insn_data
[icode
].operand
[1].mode
;
557 tmode1
= TYPE_MODE (TREE_TYPE (oprnd1
));
558 xmode1
= insn_data
[icode
].operand
[2].mode
;
561 /* The last operand is of a wider mode than the rest of the operands. */
569 gcc_assert (tmode1
== tmode0
);
572 wmode
= TYPE_MODE (TREE_TYPE (oprnd2
));
573 wxmode
= insn_data
[icode
].operand
[3].mode
;
577 wmode
= wxmode
= insn_data
[icode
].operand
[0].mode
;
580 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, wmode
))
581 temp
= gen_reg_rtx (wmode
);
589 /* In case the insn wants input operands in modes different from
590 those of the actual operands, convert the operands. It would
591 seem that we don't need to convert CONST_INTs, but we do, so
592 that they're properly zero-extended, sign-extended or truncated
595 if (GET_MODE (op0
) != xmode0
&& xmode0
!= VOIDmode
)
596 xop0
= convert_modes (xmode0
,
597 GET_MODE (op0
) != VOIDmode
603 if (GET_MODE (op1
) != xmode1
&& xmode1
!= VOIDmode
)
604 xop1
= convert_modes (xmode1
,
605 GET_MODE (op1
) != VOIDmode
611 if (GET_MODE (wide_op
) != wxmode
&& wxmode
!= VOIDmode
)
612 wxop
= convert_modes (wxmode
,
613 GET_MODE (wide_op
) != VOIDmode
618 /* Now, if insn's predicates don't allow our operands, put them into
621 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, xmode0
)
622 && xmode0
!= VOIDmode
)
623 xop0
= copy_to_mode_reg (xmode0
, xop0
);
627 if (! (*insn_data
[icode
].operand
[2].predicate
) (xop1
, xmode1
)
628 && xmode1
!= VOIDmode
)
629 xop1
= copy_to_mode_reg (xmode1
, xop1
);
633 if (! (*insn_data
[icode
].operand
[3].predicate
) (wxop
, wxmode
)
634 && wxmode
!= VOIDmode
)
635 wxop
= copy_to_mode_reg (wxmode
, wxop
);
637 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
, wxop
);
640 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
646 if (! (*insn_data
[icode
].operand
[2].predicate
) (wxop
, wxmode
)
647 && wxmode
!= VOIDmode
)
648 wxop
= copy_to_mode_reg (wxmode
, wxop
);
650 pat
= GEN_FCN (icode
) (temp
, xop0
, wxop
);
653 pat
= GEN_FCN (icode
) (temp
, xop0
);
660 /* Generate code to perform an operation specified by TERNARY_OPTAB
661 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
663 UNSIGNEDP is for the case where we have to widen the operands
664 to perform the operation. It says to use zero-extension.
666 If TARGET is nonzero, the value
667 is generated there, if it is convenient to do so.
668 In all cases an rtx is returned for the locus of the value;
669 this may or may not be TARGET. */
672 expand_ternary_op (enum machine_mode mode
, optab ternary_optab
, rtx op0
,
673 rtx op1
, rtx op2
, rtx target
, int unsignedp
)
675 int icode
= (int) optab_handler (ternary_optab
, mode
)->insn_code
;
676 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
677 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
678 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
681 rtx xop0
= op0
, xop1
= op1
, xop2
= op2
;
683 gcc_assert (optab_handler (ternary_optab
, mode
)->insn_code
684 != CODE_FOR_nothing
);
686 if (!target
|| !insn_data
[icode
].operand
[0].predicate (target
, mode
))
687 temp
= gen_reg_rtx (mode
);
691 /* In case the insn wants input operands in modes different from
692 those of the actual operands, convert the operands. It would
693 seem that we don't need to convert CONST_INTs, but we do, so
694 that they're properly zero-extended, sign-extended or truncated
697 if (GET_MODE (op0
) != mode0
&& mode0
!= VOIDmode
)
698 xop0
= convert_modes (mode0
,
699 GET_MODE (op0
) != VOIDmode
704 if (GET_MODE (op1
) != mode1
&& mode1
!= VOIDmode
)
705 xop1
= convert_modes (mode1
,
706 GET_MODE (op1
) != VOIDmode
711 if (GET_MODE (op2
) != mode2
&& mode2
!= VOIDmode
)
712 xop2
= convert_modes (mode2
,
713 GET_MODE (op2
) != VOIDmode
718 /* Now, if insn's predicates don't allow our operands, put them into
721 if (!insn_data
[icode
].operand
[1].predicate (xop0
, mode0
)
722 && mode0
!= VOIDmode
)
723 xop0
= copy_to_mode_reg (mode0
, xop0
);
725 if (!insn_data
[icode
].operand
[2].predicate (xop1
, mode1
)
726 && mode1
!= VOIDmode
)
727 xop1
= copy_to_mode_reg (mode1
, xop1
);
729 if (!insn_data
[icode
].operand
[3].predicate (xop2
, mode2
)
730 && mode2
!= VOIDmode
)
731 xop2
= copy_to_mode_reg (mode2
, xop2
);
733 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
, xop2
);
740 /* Like expand_binop, but return a constant rtx if the result can be
741 calculated at compile time. The arguments and return value are
742 otherwise the same as for expand_binop. */
745 simplify_expand_binop (enum machine_mode mode
, optab binoptab
,
746 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
747 enum optab_methods methods
)
749 if (CONSTANT_P (op0
) && CONSTANT_P (op1
))
751 rtx x
= simplify_binary_operation (binoptab
->code
, mode
, op0
, op1
);
757 return expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
);
760 /* Like simplify_expand_binop, but always put the result in TARGET.
761 Return true if the expansion succeeded. */
764 force_expand_binop (enum machine_mode mode
, optab binoptab
,
765 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
766 enum optab_methods methods
)
768 rtx x
= simplify_expand_binop (mode
, binoptab
, op0
, op1
,
769 target
, unsignedp
, methods
);
773 emit_move_insn (target
, x
);
777 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */
780 expand_vec_shift_expr (sepops ops
, rtx target
)
782 enum insn_code icode
;
783 rtx rtx_op1
, rtx_op2
;
784 enum machine_mode mode1
;
785 enum machine_mode mode2
;
786 enum machine_mode mode
= TYPE_MODE (ops
->type
);
787 tree vec_oprnd
= ops
->op0
;
788 tree shift_oprnd
= ops
->op1
;
794 case VEC_RSHIFT_EXPR
:
795 shift_optab
= vec_shr_optab
;
797 case VEC_LSHIFT_EXPR
:
798 shift_optab
= vec_shl_optab
;
804 icode
= optab_handler (shift_optab
, mode
)->insn_code
;
805 gcc_assert (icode
!= CODE_FOR_nothing
);
807 mode1
= insn_data
[icode
].operand
[1].mode
;
808 mode2
= insn_data
[icode
].operand
[2].mode
;
810 rtx_op1
= expand_normal (vec_oprnd
);
811 if (!(*insn_data
[icode
].operand
[1].predicate
) (rtx_op1
, mode1
)
812 && mode1
!= VOIDmode
)
813 rtx_op1
= force_reg (mode1
, rtx_op1
);
815 rtx_op2
= expand_normal (shift_oprnd
);
816 if (!(*insn_data
[icode
].operand
[2].predicate
) (rtx_op2
, mode2
)
817 && mode2
!= VOIDmode
)
818 rtx_op2
= force_reg (mode2
, rtx_op2
);
821 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode
))
822 target
= gen_reg_rtx (mode
);
824 /* Emit instruction */
825 pat
= GEN_FCN (icode
) (target
, rtx_op1
, rtx_op2
);
832 /* This subroutine of expand_doubleword_shift handles the cases in which
833 the effective shift value is >= BITS_PER_WORD. The arguments and return
834 value are the same as for the parent routine, except that SUPERWORD_OP1
835 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
836 INTO_TARGET may be null if the caller has decided to calculate it. */
839 expand_superword_shift (optab binoptab
, rtx outof_input
, rtx superword_op1
,
840 rtx outof_target
, rtx into_target
,
841 int unsignedp
, enum optab_methods methods
)
843 if (into_target
!= 0)
844 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, superword_op1
,
845 into_target
, unsignedp
, methods
))
848 if (outof_target
!= 0)
850 /* For a signed right shift, we must fill OUTOF_TARGET with copies
851 of the sign bit, otherwise we must fill it with zeros. */
852 if (binoptab
!= ashr_optab
)
853 emit_move_insn (outof_target
, CONST0_RTX (word_mode
));
855 if (!force_expand_binop (word_mode
, binoptab
,
856 outof_input
, GEN_INT (BITS_PER_WORD
- 1),
857 outof_target
, unsignedp
, methods
))
863 /* This subroutine of expand_doubleword_shift handles the cases in which
864 the effective shift value is < BITS_PER_WORD. The arguments and return
865 value are the same as for the parent routine. */
868 expand_subword_shift (enum machine_mode op1_mode
, optab binoptab
,
869 rtx outof_input
, rtx into_input
, rtx op1
,
870 rtx outof_target
, rtx into_target
,
871 int unsignedp
, enum optab_methods methods
,
872 unsigned HOST_WIDE_INT shift_mask
)
874 optab reverse_unsigned_shift
, unsigned_shift
;
877 reverse_unsigned_shift
= (binoptab
== ashl_optab
? lshr_optab
: ashl_optab
);
878 unsigned_shift
= (binoptab
== ashl_optab
? ashl_optab
: lshr_optab
);
880 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
881 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
882 the opposite direction to BINOPTAB. */
883 if (CONSTANT_P (op1
) || shift_mask
>= BITS_PER_WORD
)
885 carries
= outof_input
;
886 tmp
= immed_double_const (BITS_PER_WORD
, 0, op1_mode
);
887 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
892 /* We must avoid shifting by BITS_PER_WORD bits since that is either
893 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
894 has unknown behavior. Do a single shift first, then shift by the
895 remainder. It's OK to use ~OP1 as the remainder if shift counts
896 are truncated to the mode size. */
897 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
898 outof_input
, const1_rtx
, 0, unsignedp
, methods
);
899 if (shift_mask
== BITS_PER_WORD
- 1)
901 tmp
= immed_double_const (-1, -1, op1_mode
);
902 tmp
= simplify_expand_binop (op1_mode
, xor_optab
, op1
, tmp
,
907 tmp
= immed_double_const (BITS_PER_WORD
- 1, 0, op1_mode
);
908 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
912 if (tmp
== 0 || carries
== 0)
914 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
915 carries
, tmp
, 0, unsignedp
, methods
);
919 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
920 so the result can go directly into INTO_TARGET if convenient. */
921 tmp
= expand_binop (word_mode
, unsigned_shift
, into_input
, op1
,
922 into_target
, unsignedp
, methods
);
926 /* Now OR in the bits carried over from OUTOF_INPUT. */
927 if (!force_expand_binop (word_mode
, ior_optab
, tmp
, carries
,
928 into_target
, unsignedp
, methods
))
931 /* Use a standard word_mode shift for the out-of half. */
932 if (outof_target
!= 0)
933 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
934 outof_target
, unsignedp
, methods
))
941 #ifdef HAVE_conditional_move
942 /* Try implementing expand_doubleword_shift using conditional moves.
943 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
944 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
945 are the shift counts to use in the former and latter case. All other
946 arguments are the same as the parent routine. */
949 expand_doubleword_shift_condmove (enum machine_mode op1_mode
, optab binoptab
,
950 enum rtx_code cmp_code
, rtx cmp1
, rtx cmp2
,
951 rtx outof_input
, rtx into_input
,
952 rtx subword_op1
, rtx superword_op1
,
953 rtx outof_target
, rtx into_target
,
954 int unsignedp
, enum optab_methods methods
,
955 unsigned HOST_WIDE_INT shift_mask
)
957 rtx outof_superword
, into_superword
;
959 /* Put the superword version of the output into OUTOF_SUPERWORD and
961 outof_superword
= outof_target
!= 0 ? gen_reg_rtx (word_mode
) : 0;
962 if (outof_target
!= 0 && subword_op1
== superword_op1
)
964 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
965 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
966 into_superword
= outof_target
;
967 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
968 outof_superword
, 0, unsignedp
, methods
))
973 into_superword
= gen_reg_rtx (word_mode
);
974 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
975 outof_superword
, into_superword
,
980 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
981 if (!expand_subword_shift (op1_mode
, binoptab
,
982 outof_input
, into_input
, subword_op1
,
983 outof_target
, into_target
,
984 unsignedp
, methods
, shift_mask
))
987 /* Select between them. Do the INTO half first because INTO_SUPERWORD
988 might be the current value of OUTOF_TARGET. */
989 if (!emit_conditional_move (into_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
990 into_target
, into_superword
, word_mode
, false))
993 if (outof_target
!= 0)
994 if (!emit_conditional_move (outof_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
995 outof_target
, outof_superword
,
1003 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
1004 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
1005 input operand; the shift moves bits in the direction OUTOF_INPUT->
1006 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
1007 of the target. OP1 is the shift count and OP1_MODE is its mode.
1008 If OP1 is constant, it will have been truncated as appropriate
1009 and is known to be nonzero.
1011 If SHIFT_MASK is zero, the result of word shifts is undefined when the
1012 shift count is outside the range [0, BITS_PER_WORD). This routine must
1013 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
1015 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
1016 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
1017 fill with zeros or sign bits as appropriate.
1019 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
1020 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
1021 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
1022 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
1025 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
1026 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
1027 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
1028 function wants to calculate it itself.
1030 Return true if the shift could be successfully synthesized. */
1033 expand_doubleword_shift (enum machine_mode op1_mode
, optab binoptab
,
1034 rtx outof_input
, rtx into_input
, rtx op1
,
1035 rtx outof_target
, rtx into_target
,
1036 int unsignedp
, enum optab_methods methods
,
1037 unsigned HOST_WIDE_INT shift_mask
)
1039 rtx superword_op1
, tmp
, cmp1
, cmp2
;
1040 rtx subword_label
, done_label
;
1041 enum rtx_code cmp_code
;
1043 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
1044 fill the result with sign or zero bits as appropriate. If so, the value
1045 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
1046 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
1047 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
1049 This isn't worthwhile for constant shifts since the optimizers will
1050 cope better with in-range shift counts. */
1051 if (shift_mask
>= BITS_PER_WORD
1052 && outof_target
!= 0
1053 && !CONSTANT_P (op1
))
1055 if (!expand_doubleword_shift (op1_mode
, binoptab
,
1056 outof_input
, into_input
, op1
,
1058 unsignedp
, methods
, shift_mask
))
1060 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
1061 outof_target
, unsignedp
, methods
))
1066 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
1067 is true when the effective shift value is less than BITS_PER_WORD.
1068 Set SUPERWORD_OP1 to the shift count that should be used to shift
1069 OUTOF_INPUT into INTO_TARGET when the condition is false. */
1070 tmp
= immed_double_const (BITS_PER_WORD
, 0, op1_mode
);
1071 if (!CONSTANT_P (op1
) && shift_mask
== BITS_PER_WORD
- 1)
1073 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
1074 is a subword shift count. */
1075 cmp1
= simplify_expand_binop (op1_mode
, and_optab
, op1
, tmp
,
1077 cmp2
= CONST0_RTX (op1_mode
);
1079 superword_op1
= op1
;
1083 /* Set CMP1 to OP1 - BITS_PER_WORD. */
1084 cmp1
= simplify_expand_binop (op1_mode
, sub_optab
, op1
, tmp
,
1086 cmp2
= CONST0_RTX (op1_mode
);
1088 superword_op1
= cmp1
;
1093 /* If we can compute the condition at compile time, pick the
1094 appropriate subroutine. */
1095 tmp
= simplify_relational_operation (cmp_code
, SImode
, op1_mode
, cmp1
, cmp2
);
1096 if (tmp
!= 0 && CONST_INT_P (tmp
))
1098 if (tmp
== const0_rtx
)
1099 return expand_superword_shift (binoptab
, outof_input
, superword_op1
,
1100 outof_target
, into_target
,
1101 unsignedp
, methods
);
1103 return expand_subword_shift (op1_mode
, binoptab
,
1104 outof_input
, into_input
, op1
,
1105 outof_target
, into_target
,
1106 unsignedp
, methods
, shift_mask
);
1109 #ifdef HAVE_conditional_move
1110 /* Try using conditional moves to generate straight-line code. */
1112 rtx start
= get_last_insn ();
1113 if (expand_doubleword_shift_condmove (op1_mode
, binoptab
,
1114 cmp_code
, cmp1
, cmp2
,
1115 outof_input
, into_input
,
1117 outof_target
, into_target
,
1118 unsignedp
, methods
, shift_mask
))
1120 delete_insns_since (start
);
1124 /* As a last resort, use branches to select the correct alternative. */
1125 subword_label
= gen_label_rtx ();
1126 done_label
= gen_label_rtx ();
1129 do_compare_rtx_and_jump (cmp1
, cmp2
, cmp_code
, false, op1_mode
,
1130 0, 0, subword_label
);
1133 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
1134 outof_target
, into_target
,
1135 unsignedp
, methods
))
1138 emit_jump_insn (gen_jump (done_label
));
1140 emit_label (subword_label
);
1142 if (!expand_subword_shift (op1_mode
, binoptab
,
1143 outof_input
, into_input
, op1
,
1144 outof_target
, into_target
,
1145 unsignedp
, methods
, shift_mask
))
1148 emit_label (done_label
);
1152 /* Subroutine of expand_binop. Perform a double word multiplication of
1153 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1154 as the target's word_mode. This function return NULL_RTX if anything
1155 goes wrong, in which case it may have already emitted instructions
1156 which need to be deleted.
1158 If we want to multiply two two-word values and have normal and widening
1159 multiplies of single-word values, we can do this with three smaller
1162 The multiplication proceeds as follows:
1163 _______________________
1164 [__op0_high_|__op0_low__]
1165 _______________________
1166 * [__op1_high_|__op1_low__]
1167 _______________________________________________
1168 _______________________
1169 (1) [__op0_low__*__op1_low__]
1170 _______________________
1171 (2a) [__op0_low__*__op1_high_]
1172 _______________________
1173 (2b) [__op0_high_*__op1_low__]
1174 _______________________
1175 (3) [__op0_high_*__op1_high_]
1178 This gives a 4-word result. Since we are only interested in the
1179 lower 2 words, partial result (3) and the upper words of (2a) and
1180 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1181 calculated using non-widening multiplication.
1183 (1), however, needs to be calculated with an unsigned widening
1184 multiplication. If this operation is not directly supported we
1185 try using a signed widening multiplication and adjust the result.
1186 This adjustment works as follows:
1188 If both operands are positive then no adjustment is needed.
1190 If the operands have different signs, for example op0_low < 0 and
1191 op1_low >= 0, the instruction treats the most significant bit of
1192 op0_low as a sign bit instead of a bit with significance
1193 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1194 with 2**BITS_PER_WORD - op0_low, and two's complements the
1195 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1198 Similarly, if both operands are negative, we need to add
1199 (op0_low + op1_low) * 2**BITS_PER_WORD.
1201 We use a trick to adjust quickly. We logically shift op0_low right
1202 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1203 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1204 logical shift exists, we do an arithmetic right shift and subtract
1208 expand_doubleword_mult (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
1209 bool umulp
, enum optab_methods methods
)
1211 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1212 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1213 rtx wordm1
= umulp
? NULL_RTX
: GEN_INT (BITS_PER_WORD
- 1);
1214 rtx product
, adjust
, product_high
, temp
;
1216 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1217 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1218 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1219 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1221 /* If we're using an unsigned multiply to directly compute the product
1222 of the low-order words of the operands and perform any required
1223 adjustments of the operands, we begin by trying two more multiplications
1224 and then computing the appropriate sum.
1226 We have checked above that the required addition is provided.
1227 Full-word addition will normally always succeed, especially if
1228 it is provided at all, so we don't worry about its failure. The
1229 multiplication may well fail, however, so we do handle that. */
1233 /* ??? This could be done with emit_store_flag where available. */
1234 temp
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1235 NULL_RTX
, 1, methods
);
1237 op0_high
= expand_binop (word_mode
, add_optab
, op0_high
, temp
,
1238 NULL_RTX
, 0, OPTAB_DIRECT
);
1241 temp
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1242 NULL_RTX
, 0, methods
);
1245 op0_high
= expand_binop (word_mode
, sub_optab
, op0_high
, temp
,
1246 NULL_RTX
, 0, OPTAB_DIRECT
);
1253 adjust
= expand_binop (word_mode
, smul_optab
, op0_high
, op1_low
,
1254 NULL_RTX
, 0, OPTAB_DIRECT
);
1258 /* OP0_HIGH should now be dead. */
1262 /* ??? This could be done with emit_store_flag where available. */
1263 temp
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1264 NULL_RTX
, 1, methods
);
1266 op1_high
= expand_binop (word_mode
, add_optab
, op1_high
, temp
,
1267 NULL_RTX
, 0, OPTAB_DIRECT
);
1270 temp
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1271 NULL_RTX
, 0, methods
);
1274 op1_high
= expand_binop (word_mode
, sub_optab
, op1_high
, temp
,
1275 NULL_RTX
, 0, OPTAB_DIRECT
);
1282 temp
= expand_binop (word_mode
, smul_optab
, op1_high
, op0_low
,
1283 NULL_RTX
, 0, OPTAB_DIRECT
);
1287 /* OP1_HIGH should now be dead. */
1289 adjust
= expand_binop (word_mode
, add_optab
, adjust
, temp
,
1290 adjust
, 0, OPTAB_DIRECT
);
1292 if (target
&& !REG_P (target
))
1296 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1297 target
, 1, OPTAB_DIRECT
);
1299 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1300 target
, 1, OPTAB_DIRECT
);
1305 product_high
= operand_subword (product
, high
, 1, mode
);
1306 adjust
= expand_binop (word_mode
, add_optab
, product_high
, adjust
,
1307 REG_P (product_high
) ? product_high
: adjust
,
1309 emit_move_insn (product_high
, adjust
);
1313 /* Wrapper around expand_binop which takes an rtx code to specify
1314 the operation to perform, not an optab pointer. All other
1315 arguments are the same. */
1317 expand_simple_binop (enum machine_mode mode
, enum rtx_code code
, rtx op0
,
1318 rtx op1
, rtx target
, int unsignedp
,
1319 enum optab_methods methods
)
1321 optab binop
= code_to_optab
[(int) code
];
1324 return expand_binop (mode
, binop
, op0
, op1
, target
, unsignedp
, methods
);
1327 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1328 binop. Order them according to commutative_operand_precedence and, if
1329 possible, try to put TARGET or a pseudo first. */
1331 swap_commutative_operands_with_target (rtx target
, rtx op0
, rtx op1
)
1333 int op0_prec
= commutative_operand_precedence (op0
);
1334 int op1_prec
= commutative_operand_precedence (op1
);
1336 if (op0_prec
< op1_prec
)
1339 if (op0_prec
> op1_prec
)
1342 /* With equal precedence, both orders are ok, but it is better if the
1343 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1344 if (target
== 0 || REG_P (target
))
1345 return (REG_P (op1
) && !REG_P (op0
)) || target
== op1
;
1347 return rtx_equal_p (op1
, target
);
1350 /* Return true if BINOPTAB implements a shift operation. */
1353 shift_optab_p (optab binoptab
)
1355 switch (binoptab
->code
)
1371 /* Return true if BINOPTAB implements a commutative binary operation. */
1374 commutative_optab_p (optab binoptab
)
1376 return (GET_RTX_CLASS (binoptab
->code
) == RTX_COMM_ARITH
1377 || binoptab
== smul_widen_optab
1378 || binoptab
== umul_widen_optab
1379 || binoptab
== smul_highpart_optab
1380 || binoptab
== umul_highpart_optab
);
1383 /* X is to be used in mode MODE as an operand to BINOPTAB. If we're
1384 optimizing, and if the operand is a constant that costs more than
1385 1 instruction, force the constant into a register and return that
1386 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1389 avoid_expensive_constant (enum machine_mode mode
, optab binoptab
,
1390 rtx x
, bool unsignedp
)
1392 if (mode
!= VOIDmode
1395 && rtx_cost (x
, binoptab
->code
, optimize_insn_for_speed_p ())
1396 > COSTS_N_INSNS (1))
1398 if (CONST_INT_P (x
))
1400 HOST_WIDE_INT intval
= trunc_int_for_mode (INTVAL (x
), mode
);
1401 if (intval
!= INTVAL (x
))
1402 x
= GEN_INT (intval
);
1405 x
= convert_modes (mode
, VOIDmode
, x
, unsignedp
);
1406 x
= force_reg (mode
, x
);
1411 /* Helper function for expand_binop: handle the case where there
1412 is an insn that directly implements the indicated operation.
1413 Returns null if this is not possible. */
1415 expand_binop_directly (enum machine_mode mode
, optab binoptab
,
1417 rtx target
, int unsignedp
, enum optab_methods methods
,
1420 int icode
= (int) optab_handler (binoptab
, mode
)->insn_code
;
1421 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
1422 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
1423 enum machine_mode tmp_mode
;
1426 rtx xop0
= op0
, xop1
= op1
;
1433 temp
= gen_reg_rtx (mode
);
1435 /* If it is a commutative operator and the modes would match
1436 if we would swap the operands, we can save the conversions. */
1437 commutative_p
= commutative_optab_p (binoptab
);
1439 && GET_MODE (xop0
) != mode0
&& GET_MODE (xop1
) != mode1
1440 && GET_MODE (xop0
) == mode1
&& GET_MODE (xop1
) == mode1
)
1447 /* If we are optimizing, force expensive constants into a register. */
1448 xop0
= avoid_expensive_constant (mode0
, binoptab
, xop0
, unsignedp
);
1449 if (!shift_optab_p (binoptab
))
1450 xop1
= avoid_expensive_constant (mode1
, binoptab
, xop1
, unsignedp
);
1452 /* In case the insn wants input operands in modes different from
1453 those of the actual operands, convert the operands. It would
1454 seem that we don't need to convert CONST_INTs, but we do, so
1455 that they're properly zero-extended, sign-extended or truncated
1458 if (GET_MODE (xop0
) != mode0
&& mode0
!= VOIDmode
)
1459 xop0
= convert_modes (mode0
,
1460 GET_MODE (xop0
) != VOIDmode
1465 if (GET_MODE (xop1
) != mode1
&& mode1
!= VOIDmode
)
1466 xop1
= convert_modes (mode1
,
1467 GET_MODE (xop1
) != VOIDmode
1472 /* If operation is commutative,
1473 try to make the first operand a register.
1474 Even better, try to make it the same as the target.
1475 Also try to make the last operand a constant. */
1477 && swap_commutative_operands_with_target (target
, xop0
, xop1
))
1484 /* Now, if insn's predicates don't allow our operands, put them into
1487 if (!insn_data
[icode
].operand
[1].predicate (xop0
, mode0
)
1488 && mode0
!= VOIDmode
)
1489 xop0
= copy_to_mode_reg (mode0
, xop0
);
1491 if (!insn_data
[icode
].operand
[2].predicate (xop1
, mode1
)
1492 && mode1
!= VOIDmode
)
1493 xop1
= copy_to_mode_reg (mode1
, xop1
);
1495 if (binoptab
== vec_pack_trunc_optab
1496 || binoptab
== vec_pack_usat_optab
1497 || binoptab
== vec_pack_ssat_optab
1498 || binoptab
== vec_pack_ufix_trunc_optab
1499 || binoptab
== vec_pack_sfix_trunc_optab
)
1501 /* The mode of the result is different then the mode of the
1503 tmp_mode
= insn_data
[icode
].operand
[0].mode
;
1504 if (GET_MODE_NUNITS (tmp_mode
) != 2 * GET_MODE_NUNITS (mode
))
1510 if (!insn_data
[icode
].operand
[0].predicate (temp
, tmp_mode
))
1511 temp
= gen_reg_rtx (tmp_mode
);
1513 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
1516 /* If PAT is composed of more than one insn, try to add an appropriate
1517 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1518 operand, call expand_binop again, this time without a target. */
1519 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
1520 && ! add_equal_note (pat
, temp
, binoptab
->code
, xop0
, xop1
))
1522 delete_insns_since (last
);
1523 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
1524 unsignedp
, methods
);
1531 delete_insns_since (last
);
1535 /* Generate code to perform an operation specified by BINOPTAB
1536 on operands OP0 and OP1, with result having machine-mode MODE.
1538 UNSIGNEDP is for the case where we have to widen the operands
1539 to perform the operation. It says to use zero-extension.
1541 If TARGET is nonzero, the value
1542 is generated there, if it is convenient to do so.
1543 In all cases an rtx is returned for the locus of the value;
1544 this may or may not be TARGET. */
1547 expand_binop (enum machine_mode mode
, optab binoptab
, rtx op0
, rtx op1
,
1548 rtx target
, int unsignedp
, enum optab_methods methods
)
1550 enum optab_methods next_methods
1551 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
1552 ? OPTAB_WIDEN
: methods
);
1553 enum mode_class mclass
;
1554 enum machine_mode wider_mode
;
1557 rtx entry_last
= get_last_insn ();
1560 mclass
= GET_MODE_CLASS (mode
);
1562 /* If subtracting an integer constant, convert this into an addition of
1563 the negated constant. */
1565 if (binoptab
== sub_optab
&& CONST_INT_P (op1
))
1567 op1
= negate_rtx (mode
, op1
);
1568 binoptab
= add_optab
;
1571 /* Record where to delete back to if we backtrack. */
1572 last
= get_last_insn ();
1574 /* If we can do it with a three-operand insn, do so. */
1576 if (methods
!= OPTAB_MUST_WIDEN
1577 && optab_handler (binoptab
, mode
)->insn_code
!= CODE_FOR_nothing
)
1579 temp
= expand_binop_directly (mode
, binoptab
, op0
, op1
, target
,
1580 unsignedp
, methods
, last
);
1585 /* If we were trying to rotate, and that didn't work, try rotating
1586 the other direction before falling back to shifts and bitwise-or. */
1587 if (((binoptab
== rotl_optab
1588 && optab_handler (rotr_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
1589 || (binoptab
== rotr_optab
1590 && optab_handler (rotl_optab
, mode
)->insn_code
!= CODE_FOR_nothing
))
1591 && mclass
== MODE_INT
)
1593 optab otheroptab
= (binoptab
== rotl_optab
? rotr_optab
: rotl_optab
);
1595 unsigned int bits
= GET_MODE_BITSIZE (mode
);
1597 if (CONST_INT_P (op1
))
1598 newop1
= GEN_INT (bits
- INTVAL (op1
));
1599 else if (targetm
.shift_truncation_mask (mode
) == bits
- 1)
1600 newop1
= negate_rtx (GET_MODE (op1
), op1
);
1602 newop1
= expand_binop (GET_MODE (op1
), sub_optab
,
1603 GEN_INT (bits
), op1
,
1604 NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1606 temp
= expand_binop_directly (mode
, otheroptab
, op0
, newop1
,
1607 target
, unsignedp
, methods
, last
);
1612 /* If this is a multiply, see if we can do a widening operation that
1613 takes operands of this mode and makes a wider mode. */
1615 if (binoptab
== smul_optab
1616 && GET_MODE_WIDER_MODE (mode
) != VOIDmode
1617 && ((optab_handler ((unsignedp
? umul_widen_optab
: smul_widen_optab
),
1618 GET_MODE_WIDER_MODE (mode
))->insn_code
)
1619 != CODE_FOR_nothing
))
1621 temp
= expand_binop (GET_MODE_WIDER_MODE (mode
),
1622 unsignedp
? umul_widen_optab
: smul_widen_optab
,
1623 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1627 if (GET_MODE_CLASS (mode
) == MODE_INT
1628 && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode
),
1629 GET_MODE_BITSIZE (GET_MODE (temp
))))
1630 return gen_lowpart (mode
, temp
);
1632 return convert_to_mode (mode
, temp
, unsignedp
);
1636 /* Look for a wider mode of the same class for which we think we
1637 can open-code the operation. Check for a widening multiply at the
1638 wider mode as well. */
1640 if (CLASS_HAS_WIDER_MODES_P (mclass
)
1641 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
1642 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
1643 wider_mode
!= VOIDmode
;
1644 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1646 if (optab_handler (binoptab
, wider_mode
)->insn_code
!= CODE_FOR_nothing
1647 || (binoptab
== smul_optab
1648 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
1649 && ((optab_handler ((unsignedp
? umul_widen_optab
1650 : smul_widen_optab
),
1651 GET_MODE_WIDER_MODE (wider_mode
))->insn_code
)
1652 != CODE_FOR_nothing
)))
1654 rtx xop0
= op0
, xop1
= op1
;
1657 /* For certain integer operations, we need not actually extend
1658 the narrow operands, as long as we will truncate
1659 the results to the same narrowness. */
1661 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1662 || binoptab
== xor_optab
1663 || binoptab
== add_optab
|| binoptab
== sub_optab
1664 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1665 && mclass
== MODE_INT
)
1668 xop0
= avoid_expensive_constant (mode
, binoptab
,
1670 if (binoptab
!= ashl_optab
)
1671 xop1
= avoid_expensive_constant (mode
, binoptab
,
1675 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
1677 /* The second operand of a shift must always be extended. */
1678 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1679 no_extend
&& binoptab
!= ashl_optab
);
1681 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1682 unsignedp
, OPTAB_DIRECT
);
1685 if (mclass
!= MODE_INT
1686 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode
),
1687 GET_MODE_BITSIZE (wider_mode
)))
1690 target
= gen_reg_rtx (mode
);
1691 convert_move (target
, temp
, 0);
1695 return gen_lowpart (mode
, temp
);
1698 delete_insns_since (last
);
1702 /* If operation is commutative,
1703 try to make the first operand a register.
1704 Even better, try to make it the same as the target.
1705 Also try to make the last operand a constant. */
1706 if (commutative_optab_p (binoptab
)
1707 && swap_commutative_operands_with_target (target
, op0
, op1
))
1714 /* These can be done a word at a time. */
1715 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
1716 && mclass
== MODE_INT
1717 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1718 && optab_handler (binoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
1723 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1724 won't be accurate, so use a new target. */
1725 if (target
== 0 || target
== op0
|| target
== op1
)
1726 target
= gen_reg_rtx (mode
);
1730 /* Do the actual arithmetic. */
1731 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1733 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1734 rtx x
= expand_binop (word_mode
, binoptab
,
1735 operand_subword_force (op0
, i
, mode
),
1736 operand_subword_force (op1
, i
, mode
),
1737 target_piece
, unsignedp
, next_methods
);
1742 if (target_piece
!= x
)
1743 emit_move_insn (target_piece
, x
);
1746 insns
= get_insns ();
1749 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
1756 /* Synthesize double word shifts from single word shifts. */
1757 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
1758 || binoptab
== ashr_optab
)
1759 && mclass
== MODE_INT
1760 && (CONST_INT_P (op1
) || optimize_insn_for_speed_p ())
1761 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1762 && optab_handler (binoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
1763 && optab_handler (ashl_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
1764 && optab_handler (lshr_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
1766 unsigned HOST_WIDE_INT shift_mask
, double_shift_mask
;
1767 enum machine_mode op1_mode
;
1769 double_shift_mask
= targetm
.shift_truncation_mask (mode
);
1770 shift_mask
= targetm
.shift_truncation_mask (word_mode
);
1771 op1_mode
= GET_MODE (op1
) != VOIDmode
? GET_MODE (op1
) : word_mode
;
1773 /* Apply the truncation to constant shifts. */
1774 if (double_shift_mask
> 0 && CONST_INT_P (op1
))
1775 op1
= GEN_INT (INTVAL (op1
) & double_shift_mask
);
1777 if (op1
== CONST0_RTX (op1_mode
))
1780 /* Make sure that this is a combination that expand_doubleword_shift
1781 can handle. See the comments there for details. */
1782 if (double_shift_mask
== 0
1783 || (shift_mask
== BITS_PER_WORD
- 1
1784 && double_shift_mask
== BITS_PER_WORD
* 2 - 1))
1787 rtx into_target
, outof_target
;
1788 rtx into_input
, outof_input
;
1789 int left_shift
, outof_word
;
1791 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1792 won't be accurate, so use a new target. */
1793 if (target
== 0 || target
== op0
|| target
== op1
)
1794 target
= gen_reg_rtx (mode
);
1798 /* OUTOF_* is the word we are shifting bits away from, and
1799 INTO_* is the word that we are shifting bits towards, thus
1800 they differ depending on the direction of the shift and
1801 WORDS_BIG_ENDIAN. */
1803 left_shift
= binoptab
== ashl_optab
;
1804 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1806 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1807 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1809 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1810 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1812 if (expand_doubleword_shift (op1_mode
, binoptab
,
1813 outof_input
, into_input
, op1
,
1814 outof_target
, into_target
,
1815 unsignedp
, next_methods
, shift_mask
))
1817 insns
= get_insns ();
1827 /* Synthesize double word rotates from single word shifts. */
1828 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
1829 && mclass
== MODE_INT
1830 && CONST_INT_P (op1
)
1831 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1832 && optab_handler (ashl_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
1833 && optab_handler (lshr_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
1836 rtx into_target
, outof_target
;
1837 rtx into_input
, outof_input
;
1839 int shift_count
, left_shift
, outof_word
;
1841 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1842 won't be accurate, so use a new target. Do this also if target is not
1843 a REG, first because having a register instead may open optimization
1844 opportunities, and second because if target and op0 happen to be MEMs
1845 designating the same location, we would risk clobbering it too early
1846 in the code sequence we generate below. */
1847 if (target
== 0 || target
== op0
|| target
== op1
|| ! REG_P (target
))
1848 target
= gen_reg_rtx (mode
);
1852 shift_count
= INTVAL (op1
);
1854 /* OUTOF_* is the word we are shifting bits away from, and
1855 INTO_* is the word that we are shifting bits towards, thus
1856 they differ depending on the direction of the shift and
1857 WORDS_BIG_ENDIAN. */
1859 left_shift
= (binoptab
== rotl_optab
);
1860 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1862 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1863 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1865 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1866 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1868 if (shift_count
== BITS_PER_WORD
)
1870 /* This is just a word swap. */
1871 emit_move_insn (outof_target
, into_input
);
1872 emit_move_insn (into_target
, outof_input
);
1877 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1878 rtx first_shift_count
, second_shift_count
;
1879 optab reverse_unsigned_shift
, unsigned_shift
;
1881 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1882 ? lshr_optab
: ashl_optab
);
1884 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1885 ? ashl_optab
: lshr_optab
);
1887 if (shift_count
> BITS_PER_WORD
)
1889 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
1890 second_shift_count
= GEN_INT (2 * BITS_PER_WORD
- shift_count
);
1894 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
1895 second_shift_count
= GEN_INT (shift_count
);
1898 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1899 outof_input
, first_shift_count
,
1900 NULL_RTX
, unsignedp
, next_methods
);
1901 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1902 into_input
, second_shift_count
,
1903 NULL_RTX
, unsignedp
, next_methods
);
1905 if (into_temp1
!= 0 && into_temp2
!= 0)
1906 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1907 into_target
, unsignedp
, next_methods
);
1911 if (inter
!= 0 && inter
!= into_target
)
1912 emit_move_insn (into_target
, inter
);
1914 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1915 into_input
, first_shift_count
,
1916 NULL_RTX
, unsignedp
, next_methods
);
1917 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1918 outof_input
, second_shift_count
,
1919 NULL_RTX
, unsignedp
, next_methods
);
1921 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1922 inter
= expand_binop (word_mode
, ior_optab
,
1923 outof_temp1
, outof_temp2
,
1924 outof_target
, unsignedp
, next_methods
);
1926 if (inter
!= 0 && inter
!= outof_target
)
1927 emit_move_insn (outof_target
, inter
);
1930 insns
= get_insns ();
1940 /* These can be done a word at a time by propagating carries. */
1941 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1942 && mclass
== MODE_INT
1943 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
1944 && optab_handler (binoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
1947 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1948 const unsigned int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
1949 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1950 rtx xop0
, xop1
, xtarget
;
1952 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1953 value is one of those, use it. Otherwise, use 1 since it is the
1954 one easiest to get. */
1955 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1956 int normalizep
= STORE_FLAG_VALUE
;
1961 /* Prepare the operands. */
1962 xop0
= force_reg (mode
, op0
);
1963 xop1
= force_reg (mode
, op1
);
1965 xtarget
= gen_reg_rtx (mode
);
1967 if (target
== 0 || !REG_P (target
))
1970 /* Indicate for flow that the entire target reg is being set. */
1972 emit_clobber (xtarget
);
1974 /* Do the actual arithmetic. */
1975 for (i
= 0; i
< nwords
; i
++)
1977 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
1978 rtx target_piece
= operand_subword (xtarget
, index
, 1, mode
);
1979 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
1980 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
1983 /* Main add/subtract of the input operands. */
1984 x
= expand_binop (word_mode
, binoptab
,
1985 op0_piece
, op1_piece
,
1986 target_piece
, unsignedp
, next_methods
);
1992 /* Store carry from main add/subtract. */
1993 carry_out
= gen_reg_rtx (word_mode
);
1994 carry_out
= emit_store_flag_force (carry_out
,
1995 (binoptab
== add_optab
1998 word_mode
, 1, normalizep
);
2005 /* Add/subtract previous carry to main result. */
2006 newx
= expand_binop (word_mode
,
2007 normalizep
== 1 ? binoptab
: otheroptab
,
2009 NULL_RTX
, 1, next_methods
);
2013 /* Get out carry from adding/subtracting carry in. */
2014 rtx carry_tmp
= gen_reg_rtx (word_mode
);
2015 carry_tmp
= emit_store_flag_force (carry_tmp
,
2016 (binoptab
== add_optab
2019 word_mode
, 1, normalizep
);
2021 /* Logical-ior the two poss. carry together. */
2022 carry_out
= expand_binop (word_mode
, ior_optab
,
2023 carry_out
, carry_tmp
,
2024 carry_out
, 0, next_methods
);
2028 emit_move_insn (target_piece
, newx
);
2032 if (x
!= target_piece
)
2033 emit_move_insn (target_piece
, x
);
2036 carry_in
= carry_out
;
2039 if (i
== GET_MODE_BITSIZE (mode
) / (unsigned) BITS_PER_WORD
)
2041 if (optab_handler (mov_optab
, mode
)->insn_code
!= CODE_FOR_nothing
2042 || ! rtx_equal_p (target
, xtarget
))
2044 rtx temp
= emit_move_insn (target
, xtarget
);
2046 set_unique_reg_note (temp
,
2048 gen_rtx_fmt_ee (binoptab
->code
, mode
,
2059 delete_insns_since (last
);
2062 /* Attempt to synthesize double word multiplies using a sequence of word
2063 mode multiplications. We first attempt to generate a sequence using a
2064 more efficient unsigned widening multiply, and if that fails we then
2065 try using a signed widening multiply. */
2067 if (binoptab
== smul_optab
2068 && mclass
== MODE_INT
2069 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
2070 && optab_handler (smul_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
2071 && optab_handler (add_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
2073 rtx product
= NULL_RTX
;
2075 if (optab_handler (umul_widen_optab
, mode
)->insn_code
2076 != CODE_FOR_nothing
)
2078 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
2081 delete_insns_since (last
);
2084 if (product
== NULL_RTX
2085 && optab_handler (smul_widen_optab
, mode
)->insn_code
2086 != CODE_FOR_nothing
)
2088 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
2091 delete_insns_since (last
);
2094 if (product
!= NULL_RTX
)
2096 if (optab_handler (mov_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
2098 temp
= emit_move_insn (target
? target
: product
, product
);
2099 set_unique_reg_note (temp
,
2101 gen_rtx_fmt_ee (MULT
, mode
,
2109 /* It can't be open-coded in this mode.
2110 Use a library call if one is available and caller says that's ok. */
2112 libfunc
= optab_libfunc (binoptab
, mode
);
2114 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
2118 enum machine_mode op1_mode
= mode
;
2123 if (shift_optab_p (binoptab
))
2125 op1_mode
= targetm
.libgcc_shift_count_mode ();
2126 /* Specify unsigned here,
2127 since negative shift counts are meaningless. */
2128 op1x
= convert_to_mode (op1_mode
, op1
, 1);
2131 if (GET_MODE (op0
) != VOIDmode
2132 && GET_MODE (op0
) != mode
)
2133 op0
= convert_to_mode (mode
, op0
, unsignedp
);
2135 /* Pass 1 for NO_QUEUE so we don't lose any increments
2136 if the libcall is cse'd or moved. */
2137 value
= emit_library_call_value (libfunc
,
2138 NULL_RTX
, LCT_CONST
, mode
, 2,
2139 op0
, mode
, op1x
, op1_mode
);
2141 insns
= get_insns ();
2144 target
= gen_reg_rtx (mode
);
2145 emit_libcall_block (insns
, target
, value
,
2146 gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
));
2151 delete_insns_since (last
);
2153 /* It can't be done in this mode. Can we do it in a wider mode? */
2155 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
2156 || methods
== OPTAB_MUST_WIDEN
))
2158 /* Caller says, don't even try. */
2159 delete_insns_since (entry_last
);
2163 /* Compute the value of METHODS to pass to recursive calls.
2164 Don't allow widening to be tried recursively. */
2166 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
2168 /* Look for a wider mode of the same class for which it appears we can do
2171 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2173 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2174 wider_mode
!= VOIDmode
;
2175 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2177 if ((optab_handler (binoptab
, wider_mode
)->insn_code
2178 != CODE_FOR_nothing
)
2179 || (methods
== OPTAB_LIB
2180 && optab_libfunc (binoptab
, wider_mode
)))
2182 rtx xop0
= op0
, xop1
= op1
;
2185 /* For certain integer operations, we need not actually extend
2186 the narrow operands, as long as we will truncate
2187 the results to the same narrowness. */
2189 if ((binoptab
== ior_optab
|| binoptab
== and_optab
2190 || binoptab
== xor_optab
2191 || binoptab
== add_optab
|| binoptab
== sub_optab
2192 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
2193 && mclass
== MODE_INT
)
2196 xop0
= widen_operand (xop0
, wider_mode
, mode
,
2197 unsignedp
, no_extend
);
2199 /* The second operand of a shift must always be extended. */
2200 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
2201 no_extend
&& binoptab
!= ashl_optab
);
2203 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
2204 unsignedp
, methods
);
2207 if (mclass
!= MODE_INT
2208 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode
),
2209 GET_MODE_BITSIZE (wider_mode
)))
2212 target
= gen_reg_rtx (mode
);
2213 convert_move (target
, temp
, 0);
2217 return gen_lowpart (mode
, temp
);
2220 delete_insns_since (last
);
2225 delete_insns_since (entry_last
);
2229 /* Expand a binary operator which has both signed and unsigned forms.
2230 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2233 If we widen unsigned operands, we may use a signed wider operation instead
2234 of an unsigned wider operation, since the result would be the same. */
2237 sign_expand_binop (enum machine_mode mode
, optab uoptab
, optab soptab
,
2238 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
2239 enum optab_methods methods
)
2242 optab direct_optab
= unsignedp
? uoptab
: soptab
;
2243 struct optab_d wide_soptab
;
2245 /* Do it without widening, if possible. */
2246 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
2247 unsignedp
, OPTAB_DIRECT
);
2248 if (temp
|| methods
== OPTAB_DIRECT
)
2251 /* Try widening to a signed int. Make a fake signed optab that
2252 hides any signed insn for direct use. */
2253 wide_soptab
= *soptab
;
2254 optab_handler (&wide_soptab
, mode
)->insn_code
= CODE_FOR_nothing
;
2255 /* We don't want to generate new hash table entries from this fake
2257 wide_soptab
.libcall_gen
= NULL
;
2259 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
2260 unsignedp
, OPTAB_WIDEN
);
2262 /* For unsigned operands, try widening to an unsigned int. */
2263 if (temp
== 0 && unsignedp
)
2264 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
2265 unsignedp
, OPTAB_WIDEN
);
2266 if (temp
|| methods
== OPTAB_WIDEN
)
2269 /* Use the right width libcall if that exists. */
2270 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
, unsignedp
, OPTAB_LIB
);
2271 if (temp
|| methods
== OPTAB_LIB
)
2274 /* Must widen and use a libcall, use either signed or unsigned. */
2275 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
2276 unsignedp
, methods
);
2280 return expand_binop (mode
, uoptab
, op0
, op1
, target
,
2281 unsignedp
, methods
);
2285 /* Generate code to perform an operation specified by UNOPPTAB
2286 on operand OP0, with two results to TARG0 and TARG1.
2287 We assume that the order of the operands for the instruction
2288 is TARG0, TARG1, OP0.
2290 Either TARG0 or TARG1 may be zero, but what that means is that
2291 the result is not actually wanted. We will generate it into
2292 a dummy pseudo-reg and discard it. They may not both be zero.
2294 Returns 1 if this operation can be performed; 0 if not. */
2297 expand_twoval_unop (optab unoptab
, rtx op0
, rtx targ0
, rtx targ1
,
2300 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2301 enum mode_class mclass
;
2302 enum machine_mode wider_mode
;
2303 rtx entry_last
= get_last_insn ();
2306 mclass
= GET_MODE_CLASS (mode
);
2309 targ0
= gen_reg_rtx (mode
);
2311 targ1
= gen_reg_rtx (mode
);
2313 /* Record where to go back to if we fail. */
2314 last
= get_last_insn ();
2316 if (optab_handler (unoptab
, mode
)->insn_code
!= CODE_FOR_nothing
)
2318 int icode
= (int) optab_handler (unoptab
, mode
)->insn_code
;
2319 enum machine_mode mode0
= insn_data
[icode
].operand
[2].mode
;
2323 if (GET_MODE (xop0
) != VOIDmode
2324 && GET_MODE (xop0
) != mode0
)
2325 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2327 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2328 if (!insn_data
[icode
].operand
[2].predicate (xop0
, mode0
))
2329 xop0
= copy_to_mode_reg (mode0
, xop0
);
2331 /* We could handle this, but we should always be called with a pseudo
2332 for our targets and all insns should take them as outputs. */
2333 gcc_assert (insn_data
[icode
].operand
[0].predicate (targ0
, mode
));
2334 gcc_assert (insn_data
[icode
].operand
[1].predicate (targ1
, mode
));
2336 pat
= GEN_FCN (icode
) (targ0
, targ1
, xop0
);
2343 delete_insns_since (last
);
2346 /* It can't be done in this mode. Can we do it in a wider mode? */
2348 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2350 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2351 wider_mode
!= VOIDmode
;
2352 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2354 if (optab_handler (unoptab
, wider_mode
)->insn_code
2355 != CODE_FOR_nothing
)
2357 rtx t0
= gen_reg_rtx (wider_mode
);
2358 rtx t1
= gen_reg_rtx (wider_mode
);
2359 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2361 if (expand_twoval_unop (unoptab
, cop0
, t0
, t1
, unsignedp
))
2363 convert_move (targ0
, t0
, unsignedp
);
2364 convert_move (targ1
, t1
, unsignedp
);
2368 delete_insns_since (last
);
2373 delete_insns_since (entry_last
);
2377 /* Generate code to perform an operation specified by BINOPTAB
2378 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2379 We assume that the order of the operands for the instruction
2380 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2381 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2383 Either TARG0 or TARG1 may be zero, but what that means is that
2384 the result is not actually wanted. We will generate it into
2385 a dummy pseudo-reg and discard it. They may not both be zero.
2387 Returns 1 if this operation can be performed; 0 if not. */
2390 expand_twoval_binop (optab binoptab
, rtx op0
, rtx op1
, rtx targ0
, rtx targ1
,
2393 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2394 enum mode_class mclass
;
2395 enum machine_mode wider_mode
;
2396 rtx entry_last
= get_last_insn ();
2399 mclass
= GET_MODE_CLASS (mode
);
2402 targ0
= gen_reg_rtx (mode
);
2404 targ1
= gen_reg_rtx (mode
);
2406 /* Record where to go back to if we fail. */
2407 last
= get_last_insn ();
2409 if (optab_handler (binoptab
, mode
)->insn_code
!= CODE_FOR_nothing
)
2411 int icode
= (int) optab_handler (binoptab
, mode
)->insn_code
;
2412 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2413 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2415 rtx xop0
= op0
, xop1
= op1
;
2417 /* If we are optimizing, force expensive constants into a register. */
2418 xop0
= avoid_expensive_constant (mode0
, binoptab
, xop0
, unsignedp
);
2419 xop1
= avoid_expensive_constant (mode1
, binoptab
, xop1
, unsignedp
);
2421 /* In case the insn wants input operands in modes different from
2422 those of the actual operands, convert the operands. It would
2423 seem that we don't need to convert CONST_INTs, but we do, so
2424 that they're properly zero-extended, sign-extended or truncated
2427 if (GET_MODE (op0
) != mode0
&& mode0
!= VOIDmode
)
2428 xop0
= convert_modes (mode0
,
2429 GET_MODE (op0
) != VOIDmode
2434 if (GET_MODE (op1
) != mode1
&& mode1
!= VOIDmode
)
2435 xop1
= convert_modes (mode1
,
2436 GET_MODE (op1
) != VOIDmode
2441 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2442 if (!insn_data
[icode
].operand
[1].predicate (xop0
, mode0
))
2443 xop0
= copy_to_mode_reg (mode0
, xop0
);
2445 if (!insn_data
[icode
].operand
[2].predicate (xop1
, mode1
))
2446 xop1
= copy_to_mode_reg (mode1
, xop1
);
2448 /* We could handle this, but we should always be called with a pseudo
2449 for our targets and all insns should take them as outputs. */
2450 gcc_assert (insn_data
[icode
].operand
[0].predicate (targ0
, mode
));
2451 gcc_assert (insn_data
[icode
].operand
[3].predicate (targ1
, mode
));
2453 pat
= GEN_FCN (icode
) (targ0
, xop0
, xop1
, targ1
);
2460 delete_insns_since (last
);
2463 /* It can't be done in this mode. Can we do it in a wider mode? */
2465 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2467 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2468 wider_mode
!= VOIDmode
;
2469 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2471 if (optab_handler (binoptab
, wider_mode
)->insn_code
2472 != CODE_FOR_nothing
)
2474 rtx t0
= gen_reg_rtx (wider_mode
);
2475 rtx t1
= gen_reg_rtx (wider_mode
);
2476 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2477 rtx cop1
= convert_modes (wider_mode
, mode
, op1
, unsignedp
);
2479 if (expand_twoval_binop (binoptab
, cop0
, cop1
,
2482 convert_move (targ0
, t0
, unsignedp
);
2483 convert_move (targ1
, t1
, unsignedp
);
2487 delete_insns_since (last
);
2492 delete_insns_since (entry_last
);
2496 /* Expand the two-valued library call indicated by BINOPTAB, but
2497 preserve only one of the values. If TARG0 is non-NULL, the first
2498 value is placed into TARG0; otherwise the second value is placed
2499 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2500 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2501 This routine assumes that the value returned by the library call is
2502 as if the return value was of an integral mode twice as wide as the
2503 mode of OP0. Returns 1 if the call was successful. */
2506 expand_twoval_binop_libfunc (optab binoptab
, rtx op0
, rtx op1
,
2507 rtx targ0
, rtx targ1
, enum rtx_code code
)
2509 enum machine_mode mode
;
2510 enum machine_mode libval_mode
;
2515 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2516 gcc_assert (!targ0
!= !targ1
);
2518 mode
= GET_MODE (op0
);
2519 libfunc
= optab_libfunc (binoptab
, mode
);
2523 /* The value returned by the library function will have twice as
2524 many bits as the nominal MODE. */
2525 libval_mode
= smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode
),
2528 libval
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
2532 /* Get the part of VAL containing the value that we want. */
2533 libval
= simplify_gen_subreg (mode
, libval
, libval_mode
,
2534 targ0
? 0 : GET_MODE_SIZE (mode
));
2535 insns
= get_insns ();
2537 /* Move the into the desired location. */
2538 emit_libcall_block (insns
, targ0
? targ0
: targ1
, libval
,
2539 gen_rtx_fmt_ee (code
, mode
, op0
, op1
));
2545 /* Wrapper around expand_unop which takes an rtx code to specify
2546 the operation to perform, not an optab pointer. All other
2547 arguments are the same. */
2549 expand_simple_unop (enum machine_mode mode
, enum rtx_code code
, rtx op0
,
2550 rtx target
, int unsignedp
)
2552 optab unop
= code_to_optab
[(int) code
];
2555 return expand_unop (mode
, unop
, op0
, target
, unsignedp
);
2561 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)). */
2563 widen_clz (enum machine_mode mode
, rtx op0
, rtx target
)
2565 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2566 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2568 enum machine_mode wider_mode
;
2569 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2570 wider_mode
!= VOIDmode
;
2571 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2573 if (optab_handler (clz_optab
, wider_mode
)->insn_code
2574 != CODE_FOR_nothing
)
2576 rtx xop0
, temp
, last
;
2578 last
= get_last_insn ();
2581 target
= gen_reg_rtx (mode
);
2582 xop0
= widen_operand (op0
, wider_mode
, mode
, true, false);
2583 temp
= expand_unop (wider_mode
, clz_optab
, xop0
, NULL_RTX
, true);
2585 temp
= expand_binop (wider_mode
, sub_optab
, temp
,
2586 GEN_INT (GET_MODE_BITSIZE (wider_mode
)
2587 - GET_MODE_BITSIZE (mode
)),
2588 target
, true, OPTAB_DIRECT
);
2590 delete_insns_since (last
);
2599 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2600 quantities, choosing which based on whether the high word is nonzero. */
2602 expand_doubleword_clz (enum machine_mode mode
, rtx op0
, rtx target
)
2604 rtx xop0
= force_reg (mode
, op0
);
2605 rtx subhi
= gen_highpart (word_mode
, xop0
);
2606 rtx sublo
= gen_lowpart (word_mode
, xop0
);
2607 rtx hi0_label
= gen_label_rtx ();
2608 rtx after_label
= gen_label_rtx ();
2609 rtx seq
, temp
, result
;
2611 /* If we were not given a target, use a word_mode register, not a
2612 'mode' register. The result will fit, and nobody is expecting
2613 anything bigger (the return type of __builtin_clz* is int). */
2615 target
= gen_reg_rtx (word_mode
);
2617 /* In any case, write to a word_mode scratch in both branches of the
2618 conditional, so we can ensure there is a single move insn setting
2619 'target' to tag a REG_EQUAL note on. */
2620 result
= gen_reg_rtx (word_mode
);
2624 /* If the high word is not equal to zero,
2625 then clz of the full value is clz of the high word. */
2626 emit_cmp_and_jump_insns (subhi
, CONST0_RTX (word_mode
), EQ
, 0,
2627 word_mode
, true, hi0_label
);
2629 temp
= expand_unop_direct (word_mode
, clz_optab
, subhi
, result
, true);
2634 convert_move (result
, temp
, true);
2636 emit_jump_insn (gen_jump (after_label
));
2639 /* Else clz of the full value is clz of the low word plus the number
2640 of bits in the high word. */
2641 emit_label (hi0_label
);
2643 temp
= expand_unop_direct (word_mode
, clz_optab
, sublo
, 0, true);
2646 temp
= expand_binop (word_mode
, add_optab
, temp
,
2647 GEN_INT (GET_MODE_BITSIZE (word_mode
)),
2648 result
, true, OPTAB_DIRECT
);
2652 convert_move (result
, temp
, true);
2654 emit_label (after_label
);
2655 convert_move (target
, result
, true);
2660 add_equal_note (seq
, target
, CLZ
, xop0
, 0);
2672 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2674 widen_bswap (enum machine_mode mode
, rtx op0
, rtx target
)
2676 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2677 enum machine_mode wider_mode
;
2680 if (!CLASS_HAS_WIDER_MODES_P (mclass
))
2683 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2684 wider_mode
!= VOIDmode
;
2685 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2686 if (optab_handler (bswap_optab
, wider_mode
)->insn_code
!= CODE_FOR_nothing
)
2691 last
= get_last_insn ();
2693 x
= widen_operand (op0
, wider_mode
, mode
, true, true);
2694 x
= expand_unop (wider_mode
, bswap_optab
, x
, NULL_RTX
, true);
2697 x
= expand_shift (RSHIFT_EXPR
, wider_mode
, x
,
2698 size_int (GET_MODE_BITSIZE (wider_mode
)
2699 - GET_MODE_BITSIZE (mode
)),
2705 target
= gen_reg_rtx (mode
);
2706 emit_move_insn (target
, gen_lowpart (mode
, x
));
2709 delete_insns_since (last
);
2714 /* Try calculating bswap as two bswaps of two word-sized operands. */
2717 expand_doubleword_bswap (enum machine_mode mode
, rtx op
, rtx target
)
2721 t1
= expand_unop (word_mode
, bswap_optab
,
2722 operand_subword_force (op
, 0, mode
), NULL_RTX
, true);
2723 t0
= expand_unop (word_mode
, bswap_optab
,
2724 operand_subword_force (op
, 1, mode
), NULL_RTX
, true);
2727 target
= gen_reg_rtx (mode
);
2729 emit_clobber (target
);
2730 emit_move_insn (operand_subword (target
, 0, 1, mode
), t0
);
2731 emit_move_insn (operand_subword (target
, 1, 1, mode
), t1
);
2736 /* Try calculating (parity x) as (and (popcount x) 1), where
2737 popcount can also be done in a wider mode. */
2739 expand_parity (enum machine_mode mode
, rtx op0
, rtx target
)
2741 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2742 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2744 enum machine_mode wider_mode
;
2745 for (wider_mode
= mode
; wider_mode
!= VOIDmode
;
2746 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2748 if (optab_handler (popcount_optab
, wider_mode
)->insn_code
2749 != CODE_FOR_nothing
)
2751 rtx xop0
, temp
, last
;
2753 last
= get_last_insn ();
2756 target
= gen_reg_rtx (mode
);
2757 xop0
= widen_operand (op0
, wider_mode
, mode
, true, false);
2758 temp
= expand_unop (wider_mode
, popcount_optab
, xop0
, NULL_RTX
,
2761 temp
= expand_binop (wider_mode
, and_optab
, temp
, const1_rtx
,
2762 target
, true, OPTAB_DIRECT
);
2764 delete_insns_since (last
);
2773 /* Try calculating ctz(x) as K - clz(x & -x) ,
2774 where K is GET_MODE_BITSIZE(mode) - 1.
2776 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2777 don't have to worry about what the hardware does in that case. (If
2778 the clz instruction produces the usual value at 0, which is K, the
2779 result of this code sequence will be -1; expand_ffs, below, relies
2780 on this. It might be nice to have it be K instead, for consistency
2781 with the (very few) processors that provide a ctz with a defined
2782 value, but that would take one more instruction, and it would be
2783 less convenient for expand_ffs anyway. */
2786 expand_ctz (enum machine_mode mode
, rtx op0
, rtx target
)
2790 if (optab_handler (clz_optab
, mode
)->insn_code
== CODE_FOR_nothing
)
2795 temp
= expand_unop_direct (mode
, neg_optab
, op0
, NULL_RTX
, true);
2797 temp
= expand_binop (mode
, and_optab
, op0
, temp
, NULL_RTX
,
2798 true, OPTAB_DIRECT
);
2800 temp
= expand_unop_direct (mode
, clz_optab
, temp
, NULL_RTX
, true);
2802 temp
= expand_binop (mode
, sub_optab
, GEN_INT (GET_MODE_BITSIZE (mode
) - 1),
2804 true, OPTAB_DIRECT
);
2814 add_equal_note (seq
, temp
, CTZ
, op0
, 0);
2820 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2821 else with the sequence used by expand_clz.
2823 The ffs builtin promises to return zero for a zero value and ctz/clz
2824 may have an undefined value in that case. If they do not give us a
2825 convenient value, we have to generate a test and branch. */
2827 expand_ffs (enum machine_mode mode
, rtx op0
, rtx target
)
2829 HOST_WIDE_INT val
= 0;
2830 bool defined_at_zero
= false;
2833 if (optab_handler (ctz_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
2837 temp
= expand_unop_direct (mode
, ctz_optab
, op0
, 0, true);
2841 defined_at_zero
= (CTZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2);
2843 else if (optab_handler (clz_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
2846 temp
= expand_ctz (mode
, op0
, 0);
2850 if (CLZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2)
2852 defined_at_zero
= true;
2853 val
= (GET_MODE_BITSIZE (mode
) - 1) - val
;
2859 if (defined_at_zero
&& val
== -1)
2860 /* No correction needed at zero. */;
2863 /* We don't try to do anything clever with the situation found
2864 on some processors (eg Alpha) where ctz(0:mode) ==
2865 bitsize(mode). If someone can think of a way to send N to -1
2866 and leave alone all values in the range 0..N-1 (where N is a
2867 power of two), cheaper than this test-and-branch, please add it.
2869 The test-and-branch is done after the operation itself, in case
2870 the operation sets condition codes that can be recycled for this.
2871 (This is true on i386, for instance.) */
2873 rtx nonzero_label
= gen_label_rtx ();
2874 emit_cmp_and_jump_insns (op0
, CONST0_RTX (mode
), NE
, 0,
2875 mode
, true, nonzero_label
);
2877 convert_move (temp
, GEN_INT (-1), false);
2878 emit_label (nonzero_label
);
2881 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2882 to produce a value in the range 0..bitsize. */
2883 temp
= expand_binop (mode
, add_optab
, temp
, GEN_INT (1),
2884 target
, false, OPTAB_DIRECT
);
2891 add_equal_note (seq
, temp
, FFS
, op0
, 0);
2900 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2901 conditions, VAL may already be a SUBREG against which we cannot generate
2902 a further SUBREG. In this case, we expect forcing the value into a
2903 register will work around the situation. */
2906 lowpart_subreg_maybe_copy (enum machine_mode omode
, rtx val
,
2907 enum machine_mode imode
)
2910 ret
= lowpart_subreg (omode
, val
, imode
);
2913 val
= force_reg (imode
, val
);
2914 ret
= lowpart_subreg (omode
, val
, imode
);
2915 gcc_assert (ret
!= NULL
);
2920 /* Expand a floating point absolute value or negation operation via a
2921 logical operation on the sign bit. */
2924 expand_absneg_bit (enum rtx_code code
, enum machine_mode mode
,
2925 rtx op0
, rtx target
)
2927 const struct real_format
*fmt
;
2928 int bitpos
, word
, nwords
, i
;
2929 enum machine_mode imode
;
2930 HOST_WIDE_INT hi
, lo
;
2933 /* The format has to have a simple sign bit. */
2934 fmt
= REAL_MODE_FORMAT (mode
);
2938 bitpos
= fmt
->signbit_rw
;
2942 /* Don't create negative zeros if the format doesn't support them. */
2943 if (code
== NEG
&& !fmt
->has_signed_zero
)
2946 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
2948 imode
= int_mode_for_mode (mode
);
2949 if (imode
== BLKmode
)
2958 if (FLOAT_WORDS_BIG_ENDIAN
)
2959 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
2961 word
= bitpos
/ BITS_PER_WORD
;
2962 bitpos
= bitpos
% BITS_PER_WORD
;
2963 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
2966 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
2969 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
2973 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
2979 if (target
== 0 || target
== op0
)
2980 target
= gen_reg_rtx (mode
);
2986 for (i
= 0; i
< nwords
; ++i
)
2988 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
2989 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
2993 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2995 immed_double_const (lo
, hi
, imode
),
2996 targ_piece
, 1, OPTAB_LIB_WIDEN
);
2997 if (temp
!= targ_piece
)
2998 emit_move_insn (targ_piece
, temp
);
3001 emit_move_insn (targ_piece
, op0_piece
);
3004 insns
= get_insns ();
3011 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
3012 gen_lowpart (imode
, op0
),
3013 immed_double_const (lo
, hi
, imode
),
3014 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3015 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3017 set_unique_reg_note (get_last_insn (), REG_EQUAL
,
3018 gen_rtx_fmt_e (code
, mode
, copy_rtx (op0
)));
3024 /* As expand_unop, but will fail rather than attempt the operation in a
3025 different mode or with a libcall. */
3027 expand_unop_direct (enum machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
3030 if (optab_handler (unoptab
, mode
)->insn_code
!= CODE_FOR_nothing
)
3032 int icode
= (int) optab_handler (unoptab
, mode
)->insn_code
;
3033 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
3035 rtx last
= get_last_insn ();
3041 temp
= gen_reg_rtx (mode
);
3043 if (GET_MODE (xop0
) != VOIDmode
3044 && GET_MODE (xop0
) != mode0
)
3045 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
3047 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
3049 if (!insn_data
[icode
].operand
[1].predicate (xop0
, mode0
))
3050 xop0
= copy_to_mode_reg (mode0
, xop0
);
3052 if (!insn_data
[icode
].operand
[0].predicate (temp
, mode
))
3053 temp
= gen_reg_rtx (mode
);
3055 pat
= GEN_FCN (icode
) (temp
, xop0
);
3058 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
3059 && ! add_equal_note (pat
, temp
, unoptab
->code
, xop0
, NULL_RTX
))
3061 delete_insns_since (last
);
3062 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
3070 delete_insns_since (last
);
3075 /* Generate code to perform an operation specified by UNOPTAB
3076 on operand OP0, with result having machine-mode MODE.
3078 UNSIGNEDP is for the case where we have to widen the operands
3079 to perform the operation. It says to use zero-extension.
3081 If TARGET is nonzero, the value
3082 is generated there, if it is convenient to do so.
3083 In all cases an rtx is returned for the locus of the value;
3084 this may or may not be TARGET. */
3087 expand_unop (enum machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
3090 enum mode_class mclass
= GET_MODE_CLASS (mode
);
3091 enum machine_mode wider_mode
;
3095 temp
= expand_unop_direct (mode
, unoptab
, op0
, target
, unsignedp
);
3099 /* It can't be done in this mode. Can we open-code it in a wider mode? */
3101 /* Widening (or narrowing) clz needs special treatment. */
3102 if (unoptab
== clz_optab
)
3104 temp
= widen_clz (mode
, op0
, target
);
3108 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
3109 && optab_handler (unoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
3111 temp
= expand_doubleword_clz (mode
, op0
, target
);
3119 /* Widening (or narrowing) bswap needs special treatment. */
3120 if (unoptab
== bswap_optab
)
3122 temp
= widen_bswap (mode
, op0
, target
);
3126 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
3127 && optab_handler (unoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
3129 temp
= expand_doubleword_bswap (mode
, op0
, target
);
3137 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3138 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
3139 wider_mode
!= VOIDmode
;
3140 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3142 if (optab_handler (unoptab
, wider_mode
)->insn_code
!= CODE_FOR_nothing
)
3145 rtx last
= get_last_insn ();
3147 /* For certain operations, we need not actually extend
3148 the narrow operand, as long as we will truncate the
3149 results to the same narrowness. */
3151 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3152 (unoptab
== neg_optab
3153 || unoptab
== one_cmpl_optab
)
3154 && mclass
== MODE_INT
);
3156 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3161 if (mclass
!= MODE_INT
3162 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode
),
3163 GET_MODE_BITSIZE (wider_mode
)))
3166 target
= gen_reg_rtx (mode
);
3167 convert_move (target
, temp
, 0);
3171 return gen_lowpart (mode
, temp
);
3174 delete_insns_since (last
);
3178 /* These can be done a word at a time. */
3179 if (unoptab
== one_cmpl_optab
3180 && mclass
== MODE_INT
3181 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
3182 && optab_handler (unoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
3187 if (target
== 0 || target
== op0
)
3188 target
= gen_reg_rtx (mode
);
3192 /* Do the actual arithmetic. */
3193 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
3195 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
3196 rtx x
= expand_unop (word_mode
, unoptab
,
3197 operand_subword_force (op0
, i
, mode
),
3198 target_piece
, unsignedp
);
3200 if (target_piece
!= x
)
3201 emit_move_insn (target_piece
, x
);
3204 insns
= get_insns ();
3211 if (unoptab
->code
== NEG
)
3213 /* Try negating floating point values by flipping the sign bit. */
3214 if (SCALAR_FLOAT_MODE_P (mode
))
3216 temp
= expand_absneg_bit (NEG
, mode
, op0
, target
);
3221 /* If there is no negation pattern, and we have no negative zero,
3222 try subtracting from zero. */
3223 if (!HONOR_SIGNED_ZEROS (mode
))
3225 temp
= expand_binop (mode
, (unoptab
== negv_optab
3226 ? subv_optab
: sub_optab
),
3227 CONST0_RTX (mode
), op0
, target
,
3228 unsignedp
, OPTAB_DIRECT
);
3234 /* Try calculating parity (x) as popcount (x) % 2. */
3235 if (unoptab
== parity_optab
)
3237 temp
= expand_parity (mode
, op0
, target
);
3242 /* Try implementing ffs (x) in terms of clz (x). */
3243 if (unoptab
== ffs_optab
)
3245 temp
= expand_ffs (mode
, op0
, target
);
3250 /* Try implementing ctz (x) in terms of clz (x). */
3251 if (unoptab
== ctz_optab
)
3253 temp
= expand_ctz (mode
, op0
, target
);
3259 /* Now try a library call in this mode. */
3260 libfunc
= optab_libfunc (unoptab
, mode
);
3266 enum machine_mode outmode
= mode
;
3268 /* All of these functions return small values. Thus we choose to
3269 have them return something that isn't a double-word. */
3270 if (unoptab
== ffs_optab
|| unoptab
== clz_optab
|| unoptab
== ctz_optab
3271 || unoptab
== popcount_optab
|| unoptab
== parity_optab
)
3273 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node
),
3274 optab_libfunc (unoptab
, mode
)));
3278 /* Pass 1 for NO_QUEUE so we don't lose any increments
3279 if the libcall is cse'd or moved. */
3280 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, outmode
,
3282 insns
= get_insns ();
3285 target
= gen_reg_rtx (outmode
);
3286 eq_value
= gen_rtx_fmt_e (unoptab
->code
, mode
, op0
);
3287 if (GET_MODE_SIZE (outmode
) < GET_MODE_SIZE (mode
))
3288 eq_value
= simplify_gen_unary (TRUNCATE
, outmode
, eq_value
, mode
);
3289 else if (GET_MODE_SIZE (outmode
) > GET_MODE_SIZE (mode
))
3290 eq_value
= simplify_gen_unary (ZERO_EXTEND
, outmode
, eq_value
, mode
);
3291 emit_libcall_block (insns
, target
, value
, eq_value
);
3296 /* It can't be done in this mode. Can we do it in a wider mode? */
3298 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3300 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
3301 wider_mode
!= VOIDmode
;
3302 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3304 if ((optab_handler (unoptab
, wider_mode
)->insn_code
3305 != CODE_FOR_nothing
)
3306 || optab_libfunc (unoptab
, wider_mode
))
3309 rtx last
= get_last_insn ();
3311 /* For certain operations, we need not actually extend
3312 the narrow operand, as long as we will truncate the
3313 results to the same narrowness. */
3315 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3316 (unoptab
== neg_optab
3317 || unoptab
== one_cmpl_optab
)
3318 && mclass
== MODE_INT
);
3320 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3323 /* If we are generating clz using wider mode, adjust the
3325 if (unoptab
== clz_optab
&& temp
!= 0)
3326 temp
= expand_binop (wider_mode
, sub_optab
, temp
,
3327 GEN_INT (GET_MODE_BITSIZE (wider_mode
)
3328 - GET_MODE_BITSIZE (mode
)),
3329 target
, true, OPTAB_DIRECT
);
3333 if (mclass
!= MODE_INT
)
3336 target
= gen_reg_rtx (mode
);
3337 convert_move (target
, temp
, 0);
3341 return gen_lowpart (mode
, temp
);
3344 delete_insns_since (last
);
3349 /* One final attempt at implementing negation via subtraction,
3350 this time allowing widening of the operand. */
3351 if (unoptab
->code
== NEG
&& !HONOR_SIGNED_ZEROS (mode
))
3354 temp
= expand_binop (mode
,
3355 unoptab
== negv_optab
? subv_optab
: sub_optab
,
3356 CONST0_RTX (mode
), op0
,
3357 target
, unsignedp
, OPTAB_LIB_WIDEN
);
3365 /* Emit code to compute the absolute value of OP0, with result to
3366 TARGET if convenient. (TARGET may be 0.) The return value says
3367 where the result actually is to be found.
3369 MODE is the mode of the operand; the mode of the result is
3370 different but can be deduced from MODE.
3375 expand_abs_nojump (enum machine_mode mode
, rtx op0
, rtx target
,
3376 int result_unsignedp
)
3381 result_unsignedp
= 1;
3383 /* First try to do it with a special abs instruction. */
3384 temp
= expand_unop (mode
, result_unsignedp
? abs_optab
: absv_optab
,
3389 /* For floating point modes, try clearing the sign bit. */
3390 if (SCALAR_FLOAT_MODE_P (mode
))
3392 temp
= expand_absneg_bit (ABS
, mode
, op0
, target
);
3397 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3398 if (optab_handler (smax_optab
, mode
)->insn_code
!= CODE_FOR_nothing
3399 && !HONOR_SIGNED_ZEROS (mode
))
3401 rtx last
= get_last_insn ();
3403 temp
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, 0);
3405 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3411 delete_insns_since (last
);
3414 /* If this machine has expensive jumps, we can do integer absolute
3415 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3416 where W is the width of MODE. */
3418 if (GET_MODE_CLASS (mode
) == MODE_INT
3419 && BRANCH_COST (optimize_insn_for_speed_p (),
3422 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
3423 size_int (GET_MODE_BITSIZE (mode
) - 1),
3426 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
3429 temp
= expand_binop (mode
, result_unsignedp
? sub_optab
: subv_optab
,
3430 temp
, extended
, target
, 0, OPTAB_LIB_WIDEN
);
3440 expand_abs (enum machine_mode mode
, rtx op0
, rtx target
,
3441 int result_unsignedp
, int safe
)
3446 result_unsignedp
= 1;
3448 temp
= expand_abs_nojump (mode
, op0
, target
, result_unsignedp
);
3452 /* If that does not win, use conditional jump and negate. */
3454 /* It is safe to use the target if it is the same
3455 as the source if this is also a pseudo register */
3456 if (op0
== target
&& REG_P (op0
)
3457 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
3460 op1
= gen_label_rtx ();
3461 if (target
== 0 || ! safe
3462 || GET_MODE (target
) != mode
3463 || (MEM_P (target
) && MEM_VOLATILE_P (target
))
3465 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
3466 target
= gen_reg_rtx (mode
);
3468 emit_move_insn (target
, op0
);
3471 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
3472 NULL_RTX
, NULL_RTX
, op1
);
3474 op0
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3477 emit_move_insn (target
, op0
);
3483 /* Emit code to compute the one's complement absolute value of OP0
3484 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3485 (TARGET may be NULL_RTX.) The return value says where the result
3486 actually is to be found.
3488 MODE is the mode of the operand; the mode of the result is
3489 different but can be deduced from MODE. */
3492 expand_one_cmpl_abs_nojump (enum machine_mode mode
, rtx op0
, rtx target
)
3496 /* Not applicable for floating point modes. */
3497 if (FLOAT_MODE_P (mode
))
3500 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3501 if (optab_handler (smax_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
3503 rtx last
= get_last_insn ();
3505 temp
= expand_unop (mode
, one_cmpl_optab
, op0
, NULL_RTX
, 0);
3507 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3513 delete_insns_since (last
);
3516 /* If this machine has expensive jumps, we can do one's complement
3517 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3519 if (GET_MODE_CLASS (mode
) == MODE_INT
3520 && BRANCH_COST (optimize_insn_for_speed_p (),
3523 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
3524 size_int (GET_MODE_BITSIZE (mode
) - 1),
3527 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
3537 /* A subroutine of expand_copysign, perform the copysign operation using the
3538 abs and neg primitives advertised to exist on the target. The assumption
3539 is that we have a split register file, and leaving op0 in fp registers,
3540 and not playing with subregs so much, will help the register allocator. */
3543 expand_copysign_absneg (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3544 int bitpos
, bool op0_is_abs
)
3546 enum machine_mode imode
;
3553 /* Check if the back end provides an insn that handles signbit for the
3555 icode
= (int) signbit_optab
->handlers
[(int) mode
].insn_code
;
3556 if (icode
!= CODE_FOR_nothing
)
3558 imode
= insn_data
[icode
].operand
[0].mode
;
3559 sign
= gen_reg_rtx (imode
);
3560 emit_unop_insn (icode
, sign
, op1
, UNKNOWN
);
3564 HOST_WIDE_INT hi
, lo
;
3566 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3568 imode
= int_mode_for_mode (mode
);
3569 if (imode
== BLKmode
)
3571 op1
= gen_lowpart (imode
, op1
);
3578 if (FLOAT_WORDS_BIG_ENDIAN
)
3579 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3581 word
= bitpos
/ BITS_PER_WORD
;
3582 bitpos
= bitpos
% BITS_PER_WORD
;
3583 op1
= operand_subword_force (op1
, word
, mode
);
3586 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
3589 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
3593 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
3597 sign
= gen_reg_rtx (imode
);
3598 sign
= expand_binop (imode
, and_optab
, op1
,
3599 immed_double_const (lo
, hi
, imode
),
3600 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3605 op0
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
3612 if (target
== NULL_RTX
)
3613 target
= copy_to_reg (op0
);
3615 emit_move_insn (target
, op0
);
3618 label
= gen_label_rtx ();
3619 emit_cmp_and_jump_insns (sign
, const0_rtx
, EQ
, NULL_RTX
, imode
, 1, label
);
3621 if (GET_CODE (op0
) == CONST_DOUBLE
)
3622 op0
= simplify_unary_operation (NEG
, mode
, op0
, mode
);
3624 op0
= expand_unop (mode
, neg_optab
, op0
, target
, 0);
3626 emit_move_insn (target
, op0
);
3634 /* A subroutine of expand_copysign, perform the entire copysign operation
3635 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3636 is true if op0 is known to have its sign bit clear. */
3639 expand_copysign_bit (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3640 int bitpos
, bool op0_is_abs
)
3642 enum machine_mode imode
;
3643 HOST_WIDE_INT hi
, lo
;
3644 int word
, nwords
, i
;
3647 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3649 imode
= int_mode_for_mode (mode
);
3650 if (imode
== BLKmode
)
3659 if (FLOAT_WORDS_BIG_ENDIAN
)
3660 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3662 word
= bitpos
/ BITS_PER_WORD
;
3663 bitpos
= bitpos
% BITS_PER_WORD
;
3664 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
3667 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
3670 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
3674 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
3678 if (target
== 0 || target
== op0
|| target
== op1
)
3679 target
= gen_reg_rtx (mode
);
3685 for (i
= 0; i
< nwords
; ++i
)
3687 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
3688 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
3693 op0_piece
= expand_binop (imode
, and_optab
, op0_piece
,
3694 immed_double_const (~lo
, ~hi
, imode
),
3695 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3697 op1
= expand_binop (imode
, and_optab
,
3698 operand_subword_force (op1
, i
, mode
),
3699 immed_double_const (lo
, hi
, imode
),
3700 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3702 temp
= expand_binop (imode
, ior_optab
, op0_piece
, op1
,
3703 targ_piece
, 1, OPTAB_LIB_WIDEN
);
3704 if (temp
!= targ_piece
)
3705 emit_move_insn (targ_piece
, temp
);
3708 emit_move_insn (targ_piece
, op0_piece
);
3711 insns
= get_insns ();
3718 op1
= expand_binop (imode
, and_optab
, gen_lowpart (imode
, op1
),
3719 immed_double_const (lo
, hi
, imode
),
3720 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3722 op0
= gen_lowpart (imode
, op0
);
3724 op0
= expand_binop (imode
, and_optab
, op0
,
3725 immed_double_const (~lo
, ~hi
, imode
),
3726 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3728 temp
= expand_binop (imode
, ior_optab
, op0
, op1
,
3729 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3730 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3736 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3737 scalar floating point mode. Return NULL if we do not know how to
3738 expand the operation inline. */
3741 expand_copysign (rtx op0
, rtx op1
, rtx target
)
3743 enum machine_mode mode
= GET_MODE (op0
);
3744 const struct real_format
*fmt
;
3748 gcc_assert (SCALAR_FLOAT_MODE_P (mode
));
3749 gcc_assert (GET_MODE (op1
) == mode
);
3751 /* First try to do it with a special instruction. */
3752 temp
= expand_binop (mode
, copysign_optab
, op0
, op1
,
3753 target
, 0, OPTAB_DIRECT
);
3757 fmt
= REAL_MODE_FORMAT (mode
);
3758 if (fmt
== NULL
|| !fmt
->has_signed_zero
)
3762 if (GET_CODE (op0
) == CONST_DOUBLE
)
3764 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0
)))
3765 op0
= simplify_unary_operation (ABS
, mode
, op0
, mode
);
3769 if (fmt
->signbit_ro
>= 0
3770 && (GET_CODE (op0
) == CONST_DOUBLE
3771 || (optab_handler (neg_optab
, mode
)->insn_code
!= CODE_FOR_nothing
3772 && optab_handler (abs_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)))
3774 temp
= expand_copysign_absneg (mode
, op0
, op1
, target
,
3775 fmt
->signbit_ro
, op0_is_abs
);
3780 if (fmt
->signbit_rw
< 0)
3782 return expand_copysign_bit (mode
, op0
, op1
, target
,
3783 fmt
->signbit_rw
, op0_is_abs
);
3786 /* Generate an instruction whose insn-code is INSN_CODE,
3787 with two operands: an output TARGET and an input OP0.
3788 TARGET *must* be nonzero, and the output is always stored there.
3789 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3790 the value that is stored into TARGET.
3792 Return false if expansion failed. */
3795 maybe_emit_unop_insn (int icode
, rtx target
, rtx op0
, enum rtx_code code
)
3798 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
3800 rtx last
= get_last_insn ();
3804 /* Now, if insn does not accept our operands, put them into pseudos. */
3806 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
3807 op0
= copy_to_mode_reg (mode0
, op0
);
3809 if (!insn_data
[icode
].operand
[0].predicate (temp
, GET_MODE (temp
)))
3810 temp
= gen_reg_rtx (GET_MODE (temp
));
3812 pat
= GEN_FCN (icode
) (temp
, op0
);
3815 delete_insns_since (last
);
3819 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
&& code
!= UNKNOWN
)
3820 add_equal_note (pat
, temp
, code
, op0
, NULL_RTX
);
3825 emit_move_insn (target
, temp
);
3828 /* Generate an instruction whose insn-code is INSN_CODE,
3829 with two operands: an output TARGET and an input OP0.
3830 TARGET *must* be nonzero, and the output is always stored there.
3831 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3832 the value that is stored into TARGET. */
3835 emit_unop_insn (int icode
, rtx target
, rtx op0
, enum rtx_code code
)
3837 bool ok
= maybe_emit_unop_insn (icode
, target
, op0
, code
);
3841 struct no_conflict_data
3843 rtx target
, first
, insn
;
3847 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3848 the currently examined clobber / store has to stay in the list of
3849 insns that constitute the actual libcall block. */
3851 no_conflict_move_test (rtx dest
, const_rtx set
, void *p0
)
3853 struct no_conflict_data
*p
= (struct no_conflict_data
*) p0
;
3855 /* If this inns directly contributes to setting the target, it must stay. */
3856 if (reg_overlap_mentioned_p (p
->target
, dest
))
3857 p
->must_stay
= true;
3858 /* If we haven't committed to keeping any other insns in the list yet,
3859 there is nothing more to check. */
3860 else if (p
->insn
== p
->first
)
3862 /* If this insn sets / clobbers a register that feeds one of the insns
3863 already in the list, this insn has to stay too. */
3864 else if (reg_overlap_mentioned_p (dest
, PATTERN (p
->first
))
3865 || (CALL_P (p
->first
) && (find_reg_fusage (p
->first
, USE
, dest
)))
3866 || reg_used_between_p (dest
, p
->first
, p
->insn
)
3867 /* Likewise if this insn depends on a register set by a previous
3868 insn in the list, or if it sets a result (presumably a hard
3869 register) that is set or clobbered by a previous insn.
3870 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3871 SET_DEST perform the former check on the address, and the latter
3872 check on the MEM. */
3873 || (GET_CODE (set
) == SET
3874 && (modified_in_p (SET_SRC (set
), p
->first
)
3875 || modified_in_p (SET_DEST (set
), p
->first
)
3876 || modified_between_p (SET_SRC (set
), p
->first
, p
->insn
)
3877 || modified_between_p (SET_DEST (set
), p
->first
, p
->insn
))))
3878 p
->must_stay
= true;
3882 /* Emit code to make a call to a constant function or a library call.
3884 INSNS is a list containing all insns emitted in the call.
3885 These insns leave the result in RESULT. Our block is to copy RESULT
3886 to TARGET, which is logically equivalent to EQUIV.
3888 We first emit any insns that set a pseudo on the assumption that these are
3889 loading constants into registers; doing so allows them to be safely cse'ed
3890 between blocks. Then we emit all the other insns in the block, followed by
3891 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3892 note with an operand of EQUIV. */
3895 emit_libcall_block (rtx insns
, rtx target
, rtx result
, rtx equiv
)
3897 rtx final_dest
= target
;
3898 rtx next
, last
, insn
;
3900 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3901 into a MEM later. Protect the libcall block from this change. */
3902 if (! REG_P (target
) || REG_USERVAR_P (target
))
3903 target
= gen_reg_rtx (GET_MODE (target
));
3905 /* If we're using non-call exceptions, a libcall corresponding to an
3906 operation that may trap may also trap. */
3907 /* ??? See the comment in front of make_reg_eh_region_note. */
3908 if (flag_non_call_exceptions
&& may_trap_p (equiv
))
3910 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3913 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
3916 int lp_nr
= INTVAL (XEXP (note
, 0));
3917 if (lp_nr
== 0 || lp_nr
== INT_MIN
)
3918 remove_note (insn
, note
);
3924 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3925 reg note to indicate that this call cannot throw or execute a nonlocal
3926 goto (unless there is already a REG_EH_REGION note, in which case
3928 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3930 make_reg_eh_region_note_nothrow_nononlocal (insn
);
3933 /* First emit all insns that set pseudos. Remove them from the list as
3934 we go. Avoid insns that set pseudos which were referenced in previous
3935 insns. These can be generated by move_by_pieces, for example,
3936 to update an address. Similarly, avoid insns that reference things
3937 set in previous insns. */
3939 for (insn
= insns
; insn
; insn
= next
)
3941 rtx set
= single_set (insn
);
3943 next
= NEXT_INSN (insn
);
3945 if (set
!= 0 && REG_P (SET_DEST (set
))
3946 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
)
3948 struct no_conflict_data data
;
3950 data
.target
= const0_rtx
;
3954 note_stores (PATTERN (insn
), no_conflict_move_test
, &data
);
3955 if (! data
.must_stay
)
3957 if (PREV_INSN (insn
))
3958 NEXT_INSN (PREV_INSN (insn
)) = next
;
3963 PREV_INSN (next
) = PREV_INSN (insn
);
3969 /* Some ports use a loop to copy large arguments onto the stack.
3970 Don't move anything outside such a loop. */
3975 /* Write the remaining insns followed by the final copy. */
3976 for (insn
= insns
; insn
; insn
= next
)
3978 next
= NEXT_INSN (insn
);
3983 last
= emit_move_insn (target
, result
);
3984 if (optab_handler (mov_optab
, GET_MODE (target
))->insn_code
3985 != CODE_FOR_nothing
)
3986 set_unique_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
));
3988 if (final_dest
!= target
)
3989 emit_move_insn (final_dest
, target
);
3992 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3993 PURPOSE describes how this comparison will be used. CODE is the rtx
3994 comparison code we will be using.
3996 ??? Actually, CODE is slightly weaker than that. A target is still
3997 required to implement all of the normal bcc operations, but not
3998 required to implement all (or any) of the unordered bcc operations. */
4001 can_compare_p (enum rtx_code code
, enum machine_mode mode
,
4002 enum can_compare_purpose purpose
)
4005 test
= gen_rtx_fmt_ee (code
, mode
, const0_rtx
, const0_rtx
);
4010 if (purpose
== ccp_jump
4011 && (icode
= optab_handler (cbranch_optab
, mode
)->insn_code
) != CODE_FOR_nothing
4012 && insn_data
[icode
].operand
[0].predicate (test
, mode
))
4014 if (purpose
== ccp_store_flag
4015 && (icode
= optab_handler (cstore_optab
, mode
)->insn_code
) != CODE_FOR_nothing
4016 && insn_data
[icode
].operand
[1].predicate (test
, mode
))
4018 if (purpose
== ccp_cmov
4019 && optab_handler (cmov_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
4022 mode
= GET_MODE_WIDER_MODE (mode
);
4023 PUT_MODE (test
, mode
);
4025 while (mode
!= VOIDmode
);
4030 /* This function is called when we are going to emit a compare instruction that
4031 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
4033 *PMODE is the mode of the inputs (in case they are const_int).
4034 *PUNSIGNEDP nonzero says that the operands are unsigned;
4035 this matters if they need to be widened (as given by METHODS).
4037 If they have mode BLKmode, then SIZE specifies the size of both operands.
4039 This function performs all the setup necessary so that the caller only has
4040 to emit a single comparison insn. This setup can involve doing a BLKmode
4041 comparison or emitting a library call to perform the comparison if no insn
4042 is available to handle it.
4043 The values which are passed in through pointers can be modified; the caller
4044 should perform the comparison on the modified values. Constant
4045 comparisons must have already been folded. */
4048 prepare_cmp_insn (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4049 int unsignedp
, enum optab_methods methods
,
4050 rtx
*ptest
, enum machine_mode
*pmode
)
4052 enum machine_mode mode
= *pmode
;
4054 enum machine_mode cmp_mode
;
4055 enum mode_class mclass
;
4057 /* The other methods are not needed. */
4058 gcc_assert (methods
== OPTAB_DIRECT
|| methods
== OPTAB_WIDEN
4059 || methods
== OPTAB_LIB_WIDEN
);
4061 /* If we are optimizing, force expensive constants into a register. */
4062 if (CONSTANT_P (x
) && optimize
4063 && (rtx_cost (x
, COMPARE
, optimize_insn_for_speed_p ())
4064 > COSTS_N_INSNS (1)))
4065 x
= force_reg (mode
, x
);
4067 if (CONSTANT_P (y
) && optimize
4068 && (rtx_cost (y
, COMPARE
, optimize_insn_for_speed_p ())
4069 > COSTS_N_INSNS (1)))
4070 y
= force_reg (mode
, y
);
4073 /* Make sure if we have a canonical comparison. The RTL
4074 documentation states that canonical comparisons are required only
4075 for targets which have cc0. */
4076 gcc_assert (!CONSTANT_P (x
) || CONSTANT_P (y
));
4079 /* Don't let both operands fail to indicate the mode. */
4080 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
4081 x
= force_reg (mode
, x
);
4082 if (mode
== VOIDmode
)
4083 mode
= GET_MODE (x
) != VOIDmode
? GET_MODE (x
) : GET_MODE (y
);
4085 /* Handle all BLKmode compares. */
4087 if (mode
== BLKmode
)
4089 enum machine_mode result_mode
;
4090 enum insn_code cmp_code
;
4095 = GEN_INT (MIN (MEM_ALIGN (x
), MEM_ALIGN (y
)) / BITS_PER_UNIT
);
4099 /* Try to use a memory block compare insn - either cmpstr
4100 or cmpmem will do. */
4101 for (cmp_mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
4102 cmp_mode
!= VOIDmode
;
4103 cmp_mode
= GET_MODE_WIDER_MODE (cmp_mode
))
4105 cmp_code
= cmpmem_optab
[cmp_mode
];
4106 if (cmp_code
== CODE_FOR_nothing
)
4107 cmp_code
= cmpstr_optab
[cmp_mode
];
4108 if (cmp_code
== CODE_FOR_nothing
)
4109 cmp_code
= cmpstrn_optab
[cmp_mode
];
4110 if (cmp_code
== CODE_FOR_nothing
)
4113 /* Must make sure the size fits the insn's mode. */
4114 if ((CONST_INT_P (size
)
4115 && INTVAL (size
) >= (1 << GET_MODE_BITSIZE (cmp_mode
)))
4116 || (GET_MODE_BITSIZE (GET_MODE (size
))
4117 > GET_MODE_BITSIZE (cmp_mode
)))
4120 result_mode
= insn_data
[cmp_code
].operand
[0].mode
;
4121 result
= gen_reg_rtx (result_mode
);
4122 size
= convert_to_mode (cmp_mode
, size
, 1);
4123 emit_insn (GEN_FCN (cmp_code
) (result
, x
, y
, size
, opalign
));
4125 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, result
, const0_rtx
);
4126 *pmode
= result_mode
;
4130 if (methods
!= OPTAB_LIB
&& methods
!= OPTAB_LIB_WIDEN
)
4133 /* Otherwise call a library function, memcmp. */
4134 libfunc
= memcmp_libfunc
;
4135 length_type
= sizetype
;
4136 result_mode
= TYPE_MODE (integer_type_node
);
4137 cmp_mode
= TYPE_MODE (length_type
);
4138 size
= convert_to_mode (TYPE_MODE (length_type
), size
,
4139 TYPE_UNSIGNED (length_type
));
4141 result
= emit_library_call_value (libfunc
, 0, LCT_PURE
,
4147 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, result
, const0_rtx
);
4148 *pmode
= result_mode
;
4152 /* Don't allow operands to the compare to trap, as that can put the
4153 compare and branch in different basic blocks. */
4154 if (flag_non_call_exceptions
)
4157 x
= force_reg (mode
, x
);
4159 y
= force_reg (mode
, y
);
4162 if (GET_MODE_CLASS (mode
) == MODE_CC
)
4164 gcc_assert (can_compare_p (comparison
, CCmode
, ccp_jump
));
4165 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
4169 mclass
= GET_MODE_CLASS (mode
);
4170 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
4174 enum insn_code icode
;
4175 icode
= optab_handler (cbranch_optab
, cmp_mode
)->insn_code
;
4176 if (icode
!= CODE_FOR_nothing
4177 && insn_data
[icode
].operand
[0].predicate (test
, VOIDmode
))
4179 rtx last
= get_last_insn ();
4180 rtx op0
= prepare_operand (icode
, x
, 1, mode
, cmp_mode
, unsignedp
);
4181 rtx op1
= prepare_operand (icode
, y
, 2, mode
, cmp_mode
, unsignedp
);
4183 && insn_data
[icode
].operand
[1].predicate
4184 (op0
, insn_data
[icode
].operand
[1].mode
)
4185 && insn_data
[icode
].operand
[2].predicate
4186 (op1
, insn_data
[icode
].operand
[2].mode
))
4188 XEXP (test
, 0) = op0
;
4189 XEXP (test
, 1) = op1
;
4194 delete_insns_since (last
);
4197 if (methods
== OPTAB_DIRECT
|| !CLASS_HAS_WIDER_MODES_P (mclass
))
4199 cmp_mode
= GET_MODE_WIDER_MODE (cmp_mode
);
4201 while (cmp_mode
!= VOIDmode
);
4203 if (methods
!= OPTAB_LIB_WIDEN
)
4206 if (!SCALAR_FLOAT_MODE_P (mode
))
4210 /* Handle a libcall just for the mode we are using. */
4211 libfunc
= optab_libfunc (cmp_optab
, mode
);
4212 gcc_assert (libfunc
);
4214 /* If we want unsigned, and this mode has a distinct unsigned
4215 comparison routine, use that. */
4218 rtx ulibfunc
= optab_libfunc (ucmp_optab
, mode
);
4223 result
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4224 targetm
.libgcc_cmp_return_mode (),
4225 2, x
, mode
, y
, mode
);
4227 /* There are two kinds of comparison routines. Biased routines
4228 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4229 of gcc expect that the comparison operation is equivalent
4230 to the modified comparison. For signed comparisons compare the
4231 result against 1 in the biased case, and zero in the unbiased
4232 case. For unsigned comparisons always compare against 1 after
4233 biasing the unbiased result by adding 1. This gives us a way to
4238 if (!TARGET_LIB_INT_CMP_BIASED
)
4241 x
= plus_constant (result
, 1);
4247 prepare_cmp_insn (x
, y
, comparison
, NULL_RTX
, unsignedp
, methods
,
4251 prepare_float_lib_cmp (x
, y
, comparison
, ptest
, pmode
);
4259 /* Before emitting an insn with code ICODE, make sure that X, which is going
4260 to be used for operand OPNUM of the insn, is converted from mode MODE to
4261 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4262 that it is accepted by the operand predicate. Return the new value. */
4265 prepare_operand (int icode
, rtx x
, int opnum
, enum machine_mode mode
,
4266 enum machine_mode wider_mode
, int unsignedp
)
4268 if (mode
!= wider_mode
)
4269 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
4271 if (!insn_data
[icode
].operand
[opnum
].predicate
4272 (x
, insn_data
[icode
].operand
[opnum
].mode
))
4274 if (reload_completed
)
4276 x
= copy_to_mode_reg (insn_data
[icode
].operand
[opnum
].mode
, x
);
4282 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4283 we can do the branch. */
4286 emit_cmp_and_jump_insn_1 (rtx test
, enum machine_mode mode
, rtx label
)
4288 enum machine_mode optab_mode
;
4289 enum mode_class mclass
;
4290 enum insn_code icode
;
4292 mclass
= GET_MODE_CLASS (mode
);
4293 optab_mode
= (mclass
== MODE_CC
) ? CCmode
: mode
;
4294 icode
= optab_handler (cbranch_optab
, optab_mode
)->insn_code
;
4296 gcc_assert (icode
!= CODE_FOR_nothing
);
4297 gcc_assert (insn_data
[icode
].operand
[0].predicate (test
, VOIDmode
));
4298 emit_jump_insn (GEN_FCN (icode
) (test
, XEXP (test
, 0), XEXP (test
, 1), label
));
4301 /* Generate code to compare X with Y so that the condition codes are
4302 set and to jump to LABEL if the condition is true. If X is a
4303 constant and Y is not a constant, then the comparison is swapped to
4304 ensure that the comparison RTL has the canonical form.
4306 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4307 need to be widened. UNSIGNEDP is also used to select the proper
4308 branch condition code.
4310 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4312 MODE is the mode of the inputs (in case they are const_int).
4314 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4315 It will be potentially converted into an unsigned variant based on
4316 UNSIGNEDP to select a proper jump instruction. */
4319 emit_cmp_and_jump_insns (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4320 enum machine_mode mode
, int unsignedp
, rtx label
)
4322 rtx op0
= x
, op1
= y
;
4325 /* Swap operands and condition to ensure canonical RTL. */
4326 if (swap_commutative_operands_p (x
, y
)
4327 && can_compare_p (swap_condition (comparison
), mode
, ccp_jump
))
4330 comparison
= swap_condition (comparison
);
4333 /* If OP0 is still a constant, then both X and Y must be constants
4334 or the opposite comparison is not supported. Force X into a register
4335 to create canonical RTL. */
4336 if (CONSTANT_P (op0
))
4337 op0
= force_reg (mode
, op0
);
4340 comparison
= unsigned_condition (comparison
);
4342 prepare_cmp_insn (op0
, op1
, comparison
, size
, unsignedp
, OPTAB_LIB_WIDEN
,
4344 emit_cmp_and_jump_insn_1 (test
, mode
, label
);
4348 /* Emit a library call comparison between floating point X and Y.
4349 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4352 prepare_float_lib_cmp (rtx x
, rtx y
, enum rtx_code comparison
,
4353 rtx
*ptest
, enum machine_mode
*pmode
)
4355 enum rtx_code swapped
= swap_condition (comparison
);
4356 enum rtx_code reversed
= reverse_condition_maybe_unordered (comparison
);
4357 enum machine_mode orig_mode
= GET_MODE (x
);
4358 enum machine_mode mode
, cmp_mode
;
4359 rtx value
, target
, insns
, equiv
;
4361 bool reversed_p
= false;
4362 cmp_mode
= targetm
.libgcc_cmp_return_mode ();
4364 for (mode
= orig_mode
;
4366 mode
= GET_MODE_WIDER_MODE (mode
))
4368 if (code_to_optab
[comparison
]
4369 && (libfunc
= optab_libfunc (code_to_optab
[comparison
], mode
)))
4372 if (code_to_optab
[swapped
]
4373 && (libfunc
= optab_libfunc (code_to_optab
[swapped
], mode
)))
4376 tmp
= x
; x
= y
; y
= tmp
;
4377 comparison
= swapped
;
4381 if (code_to_optab
[reversed
]
4382 && (libfunc
= optab_libfunc (code_to_optab
[reversed
], mode
))
4383 && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, reversed
))
4385 comparison
= reversed
;
4391 gcc_assert (mode
!= VOIDmode
);
4393 if (mode
!= orig_mode
)
4395 x
= convert_to_mode (mode
, x
, 0);
4396 y
= convert_to_mode (mode
, y
, 0);
4399 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4400 the RTL. The allows the RTL optimizers to delete the libcall if the
4401 condition can be determined at compile-time. */
4402 if (comparison
== UNORDERED
)
4404 rtx temp
= simplify_gen_relational (NE
, cmp_mode
, mode
, x
, x
);
4405 equiv
= simplify_gen_relational (NE
, cmp_mode
, mode
, y
, y
);
4406 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4407 temp
, const_true_rtx
, equiv
);
4411 equiv
= simplify_gen_relational (comparison
, cmp_mode
, mode
, x
, y
);
4412 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4414 rtx true_rtx
, false_rtx
;
4419 true_rtx
= const0_rtx
;
4420 false_rtx
= const_true_rtx
;
4424 true_rtx
= const_true_rtx
;
4425 false_rtx
= const0_rtx
;
4429 true_rtx
= const1_rtx
;
4430 false_rtx
= const0_rtx
;
4434 true_rtx
= const0_rtx
;
4435 false_rtx
= constm1_rtx
;
4439 true_rtx
= constm1_rtx
;
4440 false_rtx
= const0_rtx
;
4444 true_rtx
= const0_rtx
;
4445 false_rtx
= const1_rtx
;
4451 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4452 equiv
, true_rtx
, false_rtx
);
4457 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4458 cmp_mode
, 2, x
, mode
, y
, mode
);
4459 insns
= get_insns ();
4462 target
= gen_reg_rtx (cmp_mode
);
4463 emit_libcall_block (insns
, target
, value
, equiv
);
4465 if (comparison
== UNORDERED
4466 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4467 comparison
= reversed_p
? EQ
: NE
;
4469 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, target
, const0_rtx
);
4473 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4476 emit_indirect_jump (rtx loc
)
4478 if (!insn_data
[(int) CODE_FOR_indirect_jump
].operand
[0].predicate
4480 loc
= copy_to_mode_reg (Pmode
, loc
);
4482 emit_jump_insn (gen_indirect_jump (loc
));
4486 #ifdef HAVE_conditional_move
4488 /* Emit a conditional move instruction if the machine supports one for that
4489 condition and machine mode.
4491 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4492 the mode to use should they be constants. If it is VOIDmode, they cannot
4495 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4496 should be stored there. MODE is the mode to use should they be constants.
4497 If it is VOIDmode, they cannot both be constants.
4499 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4500 is not supported. */
4503 emit_conditional_move (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4504 enum machine_mode cmode
, rtx op2
, rtx op3
,
4505 enum machine_mode mode
, int unsignedp
)
4507 rtx tem
, subtarget
, comparison
, insn
;
4508 enum insn_code icode
;
4509 enum rtx_code reversed
;
4511 /* If one operand is constant, make it the second one. Only do this
4512 if the other operand is not constant as well. */
4514 if (swap_commutative_operands_p (op0
, op1
))
4519 code
= swap_condition (code
);
4522 /* get_condition will prefer to generate LT and GT even if the old
4523 comparison was against zero, so undo that canonicalization here since
4524 comparisons against zero are cheaper. */
4525 if (code
== LT
&& op1
== const1_rtx
)
4526 code
= LE
, op1
= const0_rtx
;
4527 else if (code
== GT
&& op1
== constm1_rtx
)
4528 code
= GE
, op1
= const0_rtx
;
4530 if (cmode
== VOIDmode
)
4531 cmode
= GET_MODE (op0
);
4533 if (swap_commutative_operands_p (op2
, op3
)
4534 && ((reversed
= reversed_comparison_code_parts (code
, op0
, op1
, NULL
))
4543 if (mode
== VOIDmode
)
4544 mode
= GET_MODE (op2
);
4546 icode
= movcc_gen_code
[mode
];
4548 if (icode
== CODE_FOR_nothing
)
4552 target
= gen_reg_rtx (mode
);
4556 /* If the insn doesn't accept these operands, put them in pseudos. */
4558 if (!insn_data
[icode
].operand
[0].predicate
4559 (subtarget
, insn_data
[icode
].operand
[0].mode
))
4560 subtarget
= gen_reg_rtx (insn_data
[icode
].operand
[0].mode
);
4562 if (!insn_data
[icode
].operand
[2].predicate
4563 (op2
, insn_data
[icode
].operand
[2].mode
))
4564 op2
= copy_to_mode_reg (insn_data
[icode
].operand
[2].mode
, op2
);
4566 if (!insn_data
[icode
].operand
[3].predicate
4567 (op3
, insn_data
[icode
].operand
[3].mode
))
4568 op3
= copy_to_mode_reg (insn_data
[icode
].operand
[3].mode
, op3
);
4570 /* Everything should now be in the suitable form. */
4572 code
= unsignedp
? unsigned_condition (code
) : code
;
4573 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4575 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4576 return NULL and let the caller figure out how best to deal with this
4578 if (!COMPARISON_P (comparison
))
4581 do_pending_stack_adjust ();
4583 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4584 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4585 &comparison
, &cmode
);
4589 insn
= GEN_FCN (icode
) (subtarget
, comparison
, op2
, op3
);
4591 /* If that failed, then give up. */
4599 insn
= get_insns ();
4602 if (subtarget
!= target
)
4603 convert_move (target
, subtarget
, 0);
4608 /* Return nonzero if a conditional move of mode MODE is supported.
4610 This function is for combine so it can tell whether an insn that looks
4611 like a conditional move is actually supported by the hardware. If we
4612 guess wrong we lose a bit on optimization, but that's it. */
4613 /* ??? sparc64 supports conditionally moving integers values based on fp
4614 comparisons, and vice versa. How do we handle them? */
4617 can_conditionally_move_p (enum machine_mode mode
)
4619 if (movcc_gen_code
[mode
] != CODE_FOR_nothing
)
4625 #endif /* HAVE_conditional_move */
4627 /* Emit a conditional addition instruction if the machine supports one for that
4628 condition and machine mode.
4630 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4631 the mode to use should they be constants. If it is VOIDmode, they cannot
4634 OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4635 should be stored there. MODE is the mode to use should they be constants.
4636 If it is VOIDmode, they cannot both be constants.
4638 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4639 is not supported. */
4642 emit_conditional_add (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4643 enum machine_mode cmode
, rtx op2
, rtx op3
,
4644 enum machine_mode mode
, int unsignedp
)
4646 rtx tem
, subtarget
, comparison
, insn
;
4647 enum insn_code icode
;
4648 enum rtx_code reversed
;
4650 /* If one operand is constant, make it the second one. Only do this
4651 if the other operand is not constant as well. */
4653 if (swap_commutative_operands_p (op0
, op1
))
4658 code
= swap_condition (code
);
4661 /* get_condition will prefer to generate LT and GT even if the old
4662 comparison was against zero, so undo that canonicalization here since
4663 comparisons against zero are cheaper. */
4664 if (code
== LT
&& op1
== const1_rtx
)
4665 code
= LE
, op1
= const0_rtx
;
4666 else if (code
== GT
&& op1
== constm1_rtx
)
4667 code
= GE
, op1
= const0_rtx
;
4669 if (cmode
== VOIDmode
)
4670 cmode
= GET_MODE (op0
);
4672 if (swap_commutative_operands_p (op2
, op3
)
4673 && ((reversed
= reversed_comparison_code_parts (code
, op0
, op1
, NULL
))
4682 if (mode
== VOIDmode
)
4683 mode
= GET_MODE (op2
);
4685 icode
= optab_handler (addcc_optab
, mode
)->insn_code
;
4687 if (icode
== CODE_FOR_nothing
)
4691 target
= gen_reg_rtx (mode
);
4693 /* If the insn doesn't accept these operands, put them in pseudos. */
4695 if (!insn_data
[icode
].operand
[0].predicate
4696 (target
, insn_data
[icode
].operand
[0].mode
))
4697 subtarget
= gen_reg_rtx (insn_data
[icode
].operand
[0].mode
);
4701 if (!insn_data
[icode
].operand
[2].predicate
4702 (op2
, insn_data
[icode
].operand
[2].mode
))
4703 op2
= copy_to_mode_reg (insn_data
[icode
].operand
[2].mode
, op2
);
4705 if (!insn_data
[icode
].operand
[3].predicate
4706 (op3
, insn_data
[icode
].operand
[3].mode
))
4707 op3
= copy_to_mode_reg (insn_data
[icode
].operand
[3].mode
, op3
);
4709 /* Everything should now be in the suitable form. */
4711 code
= unsignedp
? unsigned_condition (code
) : code
;
4712 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4714 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4715 return NULL and let the caller figure out how best to deal with this
4717 if (!COMPARISON_P (comparison
))
4720 do_pending_stack_adjust ();
4722 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4723 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4724 &comparison
, &cmode
);
4728 insn
= GEN_FCN (icode
) (subtarget
, comparison
, op2
, op3
);
4730 /* If that failed, then give up. */
4738 insn
= get_insns ();
4741 if (subtarget
!= target
)
4742 convert_move (target
, subtarget
, 0);
4747 /* These functions attempt to generate an insn body, rather than
4748 emitting the insn, but if the gen function already emits them, we
4749 make no attempt to turn them back into naked patterns. */
4751 /* Generate and return an insn body to add Y to X. */
4754 gen_add2_insn (rtx x
, rtx y
)
4756 int icode
= (int) optab_handler (add_optab
, GET_MODE (x
))->insn_code
;
4758 gcc_assert (insn_data
[icode
].operand
[0].predicate
4759 (x
, insn_data
[icode
].operand
[0].mode
));
4760 gcc_assert (insn_data
[icode
].operand
[1].predicate
4761 (x
, insn_data
[icode
].operand
[1].mode
));
4762 gcc_assert (insn_data
[icode
].operand
[2].predicate
4763 (y
, insn_data
[icode
].operand
[2].mode
));
4765 return GEN_FCN (icode
) (x
, x
, y
);
4768 /* Generate and return an insn body to add r1 and c,
4769 storing the result in r0. */
4772 gen_add3_insn (rtx r0
, rtx r1
, rtx c
)
4774 int icode
= (int) optab_handler (add_optab
, GET_MODE (r0
))->insn_code
;
4776 if (icode
== CODE_FOR_nothing
4777 || !(insn_data
[icode
].operand
[0].predicate
4778 (r0
, insn_data
[icode
].operand
[0].mode
))
4779 || !(insn_data
[icode
].operand
[1].predicate
4780 (r1
, insn_data
[icode
].operand
[1].mode
))
4781 || !(insn_data
[icode
].operand
[2].predicate
4782 (c
, insn_data
[icode
].operand
[2].mode
)))
4785 return GEN_FCN (icode
) (r0
, r1
, c
);
4789 have_add2_insn (rtx x
, rtx y
)
4793 gcc_assert (GET_MODE (x
) != VOIDmode
);
4795 icode
= (int) optab_handler (add_optab
, GET_MODE (x
))->insn_code
;
4797 if (icode
== CODE_FOR_nothing
)
4800 if (!(insn_data
[icode
].operand
[0].predicate
4801 (x
, insn_data
[icode
].operand
[0].mode
))
4802 || !(insn_data
[icode
].operand
[1].predicate
4803 (x
, insn_data
[icode
].operand
[1].mode
))
4804 || !(insn_data
[icode
].operand
[2].predicate
4805 (y
, insn_data
[icode
].operand
[2].mode
)))
4811 /* Generate and return an insn body to subtract Y from X. */
4814 gen_sub2_insn (rtx x
, rtx y
)
4816 int icode
= (int) optab_handler (sub_optab
, GET_MODE (x
))->insn_code
;
4818 gcc_assert (insn_data
[icode
].operand
[0].predicate
4819 (x
, insn_data
[icode
].operand
[0].mode
));
4820 gcc_assert (insn_data
[icode
].operand
[1].predicate
4821 (x
, insn_data
[icode
].operand
[1].mode
));
4822 gcc_assert (insn_data
[icode
].operand
[2].predicate
4823 (y
, insn_data
[icode
].operand
[2].mode
));
4825 return GEN_FCN (icode
) (x
, x
, y
);
4828 /* Generate and return an insn body to subtract r1 and c,
4829 storing the result in r0. */
4832 gen_sub3_insn (rtx r0
, rtx r1
, rtx c
)
4834 int icode
= (int) optab_handler (sub_optab
, GET_MODE (r0
))->insn_code
;
4836 if (icode
== CODE_FOR_nothing
4837 || !(insn_data
[icode
].operand
[0].predicate
4838 (r0
, insn_data
[icode
].operand
[0].mode
))
4839 || !(insn_data
[icode
].operand
[1].predicate
4840 (r1
, insn_data
[icode
].operand
[1].mode
))
4841 || !(insn_data
[icode
].operand
[2].predicate
4842 (c
, insn_data
[icode
].operand
[2].mode
)))
4845 return GEN_FCN (icode
) (r0
, r1
, c
);
4849 have_sub2_insn (rtx x
, rtx y
)
4853 gcc_assert (GET_MODE (x
) != VOIDmode
);
4855 icode
= (int) optab_handler (sub_optab
, GET_MODE (x
))->insn_code
;
4857 if (icode
== CODE_FOR_nothing
)
4860 if (!(insn_data
[icode
].operand
[0].predicate
4861 (x
, insn_data
[icode
].operand
[0].mode
))
4862 || !(insn_data
[icode
].operand
[1].predicate
4863 (x
, insn_data
[icode
].operand
[1].mode
))
4864 || !(insn_data
[icode
].operand
[2].predicate
4865 (y
, insn_data
[icode
].operand
[2].mode
)))
4871 /* Generate the body of an instruction to copy Y into X.
4872 It may be a list of insns, if one insn isn't enough. */
4875 gen_move_insn (rtx x
, rtx y
)
4880 emit_move_insn_1 (x
, y
);
4886 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4887 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4888 no such operation exists, CODE_FOR_nothing will be returned. */
4891 can_extend_p (enum machine_mode to_mode
, enum machine_mode from_mode
,
4895 #ifdef HAVE_ptr_extend
4897 return CODE_FOR_ptr_extend
;
4900 tab
= unsignedp
? zext_optab
: sext_optab
;
4901 return convert_optab_handler (tab
, to_mode
, from_mode
)->insn_code
;
4904 /* Generate the body of an insn to extend Y (with mode MFROM)
4905 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4908 gen_extend_insn (rtx x
, rtx y
, enum machine_mode mto
,
4909 enum machine_mode mfrom
, int unsignedp
)
4911 enum insn_code icode
= can_extend_p (mto
, mfrom
, unsignedp
);
4912 return GEN_FCN (icode
) (x
, y
);
4915 /* can_fix_p and can_float_p say whether the target machine
4916 can directly convert a given fixed point type to
4917 a given floating point type, or vice versa.
4918 The returned value is the CODE_FOR_... value to use,
4919 or CODE_FOR_nothing if these modes cannot be directly converted.
4921 *TRUNCP_PTR is set to 1 if it is necessary to output
4922 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4924 static enum insn_code
4925 can_fix_p (enum machine_mode fixmode
, enum machine_mode fltmode
,
4926 int unsignedp
, int *truncp_ptr
)
4929 enum insn_code icode
;
4931 tab
= unsignedp
? ufixtrunc_optab
: sfixtrunc_optab
;
4932 icode
= convert_optab_handler (tab
, fixmode
, fltmode
)->insn_code
;
4933 if (icode
!= CODE_FOR_nothing
)
4939 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4940 for this to work. We need to rework the fix* and ftrunc* patterns
4941 and documentation. */
4942 tab
= unsignedp
? ufix_optab
: sfix_optab
;
4943 icode
= convert_optab_handler (tab
, fixmode
, fltmode
)->insn_code
;
4944 if (icode
!= CODE_FOR_nothing
4945 && optab_handler (ftrunc_optab
, fltmode
)->insn_code
!= CODE_FOR_nothing
)
4952 return CODE_FOR_nothing
;
4955 static enum insn_code
4956 can_float_p (enum machine_mode fltmode
, enum machine_mode fixmode
,
4961 tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
4962 return convert_optab_handler (tab
, fltmode
, fixmode
)->insn_code
;
4965 /* Generate code to convert FROM to floating point
4966 and store in TO. FROM must be fixed point and not VOIDmode.
4967 UNSIGNEDP nonzero means regard FROM as unsigned.
4968 Normally this is done by correcting the final value
4969 if it is negative. */
4972 expand_float (rtx to
, rtx from
, int unsignedp
)
4974 enum insn_code icode
;
4976 enum machine_mode fmode
, imode
;
4977 bool can_do_signed
= false;
4979 /* Crash now, because we won't be able to decide which mode to use. */
4980 gcc_assert (GET_MODE (from
) != VOIDmode
);
4982 /* Look for an insn to do the conversion. Do it in the specified
4983 modes if possible; otherwise convert either input, output or both to
4984 wider mode. If the integer mode is wider than the mode of FROM,
4985 we can do the conversion signed even if the input is unsigned. */
4987 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
4988 fmode
= GET_MODE_WIDER_MODE (fmode
))
4989 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
4990 imode
= GET_MODE_WIDER_MODE (imode
))
4992 int doing_unsigned
= unsignedp
;
4994 if (fmode
!= GET_MODE (to
)
4995 && significand_size (fmode
) < GET_MODE_BITSIZE (GET_MODE (from
)))
4998 icode
= can_float_p (fmode
, imode
, unsignedp
);
4999 if (icode
== CODE_FOR_nothing
&& unsignedp
)
5001 enum insn_code scode
= can_float_p (fmode
, imode
, 0);
5002 if (scode
!= CODE_FOR_nothing
)
5003 can_do_signed
= true;
5004 if (imode
!= GET_MODE (from
))
5005 icode
= scode
, doing_unsigned
= 0;
5008 if (icode
!= CODE_FOR_nothing
)
5010 if (imode
!= GET_MODE (from
))
5011 from
= convert_to_mode (imode
, from
, unsignedp
);
5013 if (fmode
!= GET_MODE (to
))
5014 target
= gen_reg_rtx (fmode
);
5016 emit_unop_insn (icode
, target
, from
,
5017 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
5020 convert_move (to
, target
, 0);
5025 /* Unsigned integer, and no way to convert directly. Convert as signed,
5026 then unconditionally adjust the result. */
5027 if (unsignedp
&& can_do_signed
)
5029 rtx label
= gen_label_rtx ();
5031 REAL_VALUE_TYPE offset
;
5033 /* Look for a usable floating mode FMODE wider than the source and at
5034 least as wide as the target. Using FMODE will avoid rounding woes
5035 with unsigned values greater than the signed maximum value. */
5037 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
5038 fmode
= GET_MODE_WIDER_MODE (fmode
))
5039 if (GET_MODE_BITSIZE (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
5040 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
5043 if (fmode
== VOIDmode
)
5045 /* There is no such mode. Pretend the target is wide enough. */
5046 fmode
= GET_MODE (to
);
5048 /* Avoid double-rounding when TO is narrower than FROM. */
5049 if ((significand_size (fmode
) + 1)
5050 < GET_MODE_BITSIZE (GET_MODE (from
)))
5053 rtx neglabel
= gen_label_rtx ();
5055 /* Don't use TARGET if it isn't a register, is a hard register,
5056 or is the wrong mode. */
5058 || REGNO (target
) < FIRST_PSEUDO_REGISTER
5059 || GET_MODE (target
) != fmode
)
5060 target
= gen_reg_rtx (fmode
);
5062 imode
= GET_MODE (from
);
5063 do_pending_stack_adjust ();
5065 /* Test whether the sign bit is set. */
5066 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
5069 /* The sign bit is not set. Convert as signed. */
5070 expand_float (target
, from
, 0);
5071 emit_jump_insn (gen_jump (label
));
5074 /* The sign bit is set.
5075 Convert to a usable (positive signed) value by shifting right
5076 one bit, while remembering if a nonzero bit was shifted
5077 out; i.e., compute (from & 1) | (from >> 1). */
5079 emit_label (neglabel
);
5080 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
5081 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5082 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, integer_one_node
,
5084 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
5086 expand_float (target
, temp
, 0);
5088 /* Multiply by 2 to undo the shift above. */
5089 temp
= expand_binop (fmode
, add_optab
, target
, target
,
5090 target
, 0, OPTAB_LIB_WIDEN
);
5092 emit_move_insn (target
, temp
);
5094 do_pending_stack_adjust ();
5100 /* If we are about to do some arithmetic to correct for an
5101 unsigned operand, do it in a pseudo-register. */
5103 if (GET_MODE (to
) != fmode
5104 || !REG_P (to
) || REGNO (to
) < FIRST_PSEUDO_REGISTER
)
5105 target
= gen_reg_rtx (fmode
);
5107 /* Convert as signed integer to floating. */
5108 expand_float (target
, from
, 0);
5110 /* If FROM is negative (and therefore TO is negative),
5111 correct its value by 2**bitwidth. */
5113 do_pending_stack_adjust ();
5114 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
),
5118 real_2expN (&offset
, GET_MODE_BITSIZE (GET_MODE (from
)), fmode
);
5119 temp
= expand_binop (fmode
, add_optab
, target
,
5120 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
5121 target
, 0, OPTAB_LIB_WIDEN
);
5123 emit_move_insn (target
, temp
);
5125 do_pending_stack_adjust ();
5130 /* No hardware instruction available; call a library routine. */
5135 convert_optab tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
5137 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
5138 from
= convert_to_mode (SImode
, from
, unsignedp
);
5140 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5141 gcc_assert (libfunc
);
5145 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5146 GET_MODE (to
), 1, from
,
5148 insns
= get_insns ();
5151 emit_libcall_block (insns
, target
, value
,
5152 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FLOAT
: FLOAT
,
5153 GET_MODE (to
), from
));
5158 /* Copy result to requested destination
5159 if we have been computing in a temp location. */
5163 if (GET_MODE (target
) == GET_MODE (to
))
5164 emit_move_insn (to
, target
);
5166 convert_move (to
, target
, 0);
5170 /* Generate code to convert FROM to fixed point and store in TO. FROM
5171 must be floating point. */
5174 expand_fix (rtx to
, rtx from
, int unsignedp
)
5176 enum insn_code icode
;
5178 enum machine_mode fmode
, imode
;
5181 /* We first try to find a pair of modes, one real and one integer, at
5182 least as wide as FROM and TO, respectively, in which we can open-code
5183 this conversion. If the integer mode is wider than the mode of TO,
5184 we can do the conversion either signed or unsigned. */
5186 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5187 fmode
= GET_MODE_WIDER_MODE (fmode
))
5188 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
5189 imode
= GET_MODE_WIDER_MODE (imode
))
5191 int doing_unsigned
= unsignedp
;
5193 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
5194 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
5195 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
5197 if (icode
!= CODE_FOR_nothing
)
5199 rtx last
= get_last_insn ();
5200 if (fmode
!= GET_MODE (from
))
5201 from
= convert_to_mode (fmode
, from
, 0);
5205 rtx temp
= gen_reg_rtx (GET_MODE (from
));
5206 from
= expand_unop (GET_MODE (from
), ftrunc_optab
, from
,
5210 if (imode
!= GET_MODE (to
))
5211 target
= gen_reg_rtx (imode
);
5213 if (maybe_emit_unop_insn (icode
, target
, from
,
5214 doing_unsigned
? UNSIGNED_FIX
: FIX
))
5217 convert_move (to
, target
, unsignedp
);
5220 delete_insns_since (last
);
5224 /* For an unsigned conversion, there is one more way to do it.
5225 If we have a signed conversion, we generate code that compares
5226 the real value to the largest representable positive number. If if
5227 is smaller, the conversion is done normally. Otherwise, subtract
5228 one plus the highest signed number, convert, and add it back.
5230 We only need to check all real modes, since we know we didn't find
5231 anything with a wider integer mode.
5233 This code used to extend FP value into mode wider than the destination.
5234 This is needed for decimal float modes which cannot accurately
5235 represent one plus the highest signed number of the same size, but
5236 not for binary modes. Consider, for instance conversion from SFmode
5239 The hot path through the code is dealing with inputs smaller than 2^63
5240 and doing just the conversion, so there is no bits to lose.
5242 In the other path we know the value is positive in the range 2^63..2^64-1
5243 inclusive. (as for other input overflow happens and result is undefined)
5244 So we know that the most important bit set in mantissa corresponds to
5245 2^63. The subtraction of 2^63 should not generate any rounding as it
5246 simply clears out that bit. The rest is trivial. */
5248 if (unsignedp
&& GET_MODE_BITSIZE (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
5249 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5250 fmode
= GET_MODE_WIDER_MODE (fmode
))
5251 if (CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0, &must_trunc
)
5252 && (!DECIMAL_FLOAT_MODE_P (fmode
)
5253 || GET_MODE_BITSIZE (fmode
) > GET_MODE_BITSIZE (GET_MODE (to
))))
5256 REAL_VALUE_TYPE offset
;
5257 rtx limit
, lab1
, lab2
, insn
;
5259 bitsize
= GET_MODE_BITSIZE (GET_MODE (to
));
5260 real_2expN (&offset
, bitsize
- 1, fmode
);
5261 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
5262 lab1
= gen_label_rtx ();
5263 lab2
= gen_label_rtx ();
5265 if (fmode
!= GET_MODE (from
))
5266 from
= convert_to_mode (fmode
, from
, 0);
5268 /* See if we need to do the subtraction. */
5269 do_pending_stack_adjust ();
5270 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
),
5273 /* If not, do the signed "fix" and branch around fixup code. */
5274 expand_fix (to
, from
, 0);
5275 emit_jump_insn (gen_jump (lab2
));
5278 /* Otherwise, subtract 2**(N-1), convert to signed number,
5279 then add 2**(N-1). Do the addition using XOR since this
5280 will often generate better code. */
5282 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
5283 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
5284 expand_fix (to
, target
, 0);
5285 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
5287 ((HOST_WIDE_INT
) 1 << (bitsize
- 1),
5289 to
, 1, OPTAB_LIB_WIDEN
);
5292 emit_move_insn (to
, target
);
5296 if (optab_handler (mov_optab
, GET_MODE (to
))->insn_code
5297 != CODE_FOR_nothing
)
5299 /* Make a place for a REG_NOTE and add it. */
5300 insn
= emit_move_insn (to
, to
);
5301 set_unique_reg_note (insn
,
5303 gen_rtx_fmt_e (UNSIGNED_FIX
,
5311 /* We can't do it with an insn, so use a library call. But first ensure
5312 that the mode of TO is at least as wide as SImode, since those are the
5313 only library calls we know about. */
5315 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
5317 target
= gen_reg_rtx (SImode
);
5319 expand_fix (target
, from
, unsignedp
);
5327 convert_optab tab
= unsignedp
? ufix_optab
: sfix_optab
;
5328 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5329 gcc_assert (libfunc
);
5333 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5334 GET_MODE (to
), 1, from
,
5336 insns
= get_insns ();
5339 emit_libcall_block (insns
, target
, value
,
5340 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
5341 GET_MODE (to
), from
));
5346 if (GET_MODE (to
) == GET_MODE (target
))
5347 emit_move_insn (to
, target
);
5349 convert_move (to
, target
, 0);
5353 /* Generate code to convert FROM or TO a fixed-point.
5354 If UINTP is true, either TO or FROM is an unsigned integer.
5355 If SATP is true, we need to saturate the result. */
5358 expand_fixed_convert (rtx to
, rtx from
, int uintp
, int satp
)
5360 enum machine_mode to_mode
= GET_MODE (to
);
5361 enum machine_mode from_mode
= GET_MODE (from
);
5363 enum rtx_code this_code
;
5364 enum insn_code code
;
5368 if (to_mode
== from_mode
)
5370 emit_move_insn (to
, from
);
5376 tab
= satp
? satfractuns_optab
: fractuns_optab
;
5377 this_code
= satp
? UNSIGNED_SAT_FRACT
: UNSIGNED_FRACT_CONVERT
;
5381 tab
= satp
? satfract_optab
: fract_optab
;
5382 this_code
= satp
? SAT_FRACT
: FRACT_CONVERT
;
5384 code
= tab
->handlers
[to_mode
][from_mode
].insn_code
;
5385 if (code
!= CODE_FOR_nothing
)
5387 emit_unop_insn (code
, to
, from
, this_code
);
5391 libfunc
= convert_optab_libfunc (tab
, to_mode
, from_mode
);
5392 gcc_assert (libfunc
);
5395 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, to_mode
,
5396 1, from
, from_mode
);
5397 insns
= get_insns ();
5400 emit_libcall_block (insns
, to
, value
,
5401 gen_rtx_fmt_e (tab
->code
, to_mode
, from
));
5404 /* Generate code to convert FROM to fixed point and store in TO. FROM
5405 must be floating point, TO must be signed. Use the conversion optab
5406 TAB to do the conversion. */
5409 expand_sfix_optab (rtx to
, rtx from
, convert_optab tab
)
5411 enum insn_code icode
;
5413 enum machine_mode fmode
, imode
;
5415 /* We first try to find a pair of modes, one real and one integer, at
5416 least as wide as FROM and TO, respectively, in which we can open-code
5417 this conversion. If the integer mode is wider than the mode of TO,
5418 we can do the conversion either signed or unsigned. */
5420 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5421 fmode
= GET_MODE_WIDER_MODE (fmode
))
5422 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
5423 imode
= GET_MODE_WIDER_MODE (imode
))
5425 icode
= convert_optab_handler (tab
, imode
, fmode
)->insn_code
;
5426 if (icode
!= CODE_FOR_nothing
)
5428 rtx last
= get_last_insn ();
5429 if (fmode
!= GET_MODE (from
))
5430 from
= convert_to_mode (fmode
, from
, 0);
5432 if (imode
!= GET_MODE (to
))
5433 target
= gen_reg_rtx (imode
);
5435 if (!maybe_emit_unop_insn (icode
, target
, from
, UNKNOWN
))
5437 delete_insns_since (last
);
5441 convert_move (to
, target
, 0);
5449 /* Report whether we have an instruction to perform the operation
5450 specified by CODE on operands of mode MODE. */
5452 have_insn_for (enum rtx_code code
, enum machine_mode mode
)
5454 return (code_to_optab
[(int) code
] != 0
5455 && (optab_handler (code_to_optab
[(int) code
], mode
)->insn_code
5456 != CODE_FOR_nothing
));
5459 /* Set all insn_code fields to CODE_FOR_nothing. */
5462 init_insn_codes (void)
5466 for (i
= 0; i
< (unsigned int) OTI_MAX
; i
++)
5471 op
= &optab_table
[i
];
5472 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
5473 optab_handler (op
, j
)->insn_code
= CODE_FOR_nothing
;
5475 for (i
= 0; i
< (unsigned int) COI_MAX
; i
++)
5480 op
= &convert_optab_table
[i
];
5481 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
5482 for (k
= 0; k
< NUM_MACHINE_MODES
; k
++)
5483 convert_optab_handler (op
, j
, k
)->insn_code
= CODE_FOR_nothing
;
5487 /* Initialize OP's code to CODE, and write it into the code_to_optab table. */
5489 init_optab (optab op
, enum rtx_code code
)
5492 code_to_optab
[(int) code
] = op
;
5495 /* Same, but fill in its code as CODE, and do _not_ write it into
5496 the code_to_optab table. */
5498 init_optabv (optab op
, enum rtx_code code
)
5503 /* Conversion optabs never go in the code_to_optab table. */
5505 init_convert_optab (convert_optab op
, enum rtx_code code
)
5510 /* Initialize the libfunc fields of an entire group of entries in some
5511 optab. Each entry is set equal to a string consisting of a leading
5512 pair of underscores followed by a generic operation name followed by
5513 a mode name (downshifted to lowercase) followed by a single character
5514 representing the number of operands for the given operation (which is
5515 usually one of the characters '2', '3', or '4').
5517 OPTABLE is the table in which libfunc fields are to be initialized.
5518 OPNAME is the generic (string) name of the operation.
5519 SUFFIX is the character which specifies the number of operands for
5520 the given generic operation.
5521 MODE is the mode to generate for.
5525 gen_libfunc (optab optable
, const char *opname
, int suffix
, enum machine_mode mode
)
5527 unsigned opname_len
= strlen (opname
);
5528 const char *mname
= GET_MODE_NAME (mode
);
5529 unsigned mname_len
= strlen (mname
);
5530 char *libfunc_name
= XALLOCAVEC (char, 2 + opname_len
+ mname_len
+ 1 + 1);
5537 for (q
= opname
; *q
; )
5539 for (q
= mname
; *q
; q
++)
5540 *p
++ = TOLOWER (*q
);
5544 set_optab_libfunc (optable
, mode
,
5545 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5548 /* Like gen_libfunc, but verify that integer operation is involved. */
5551 gen_int_libfunc (optab optable
, const char *opname
, char suffix
,
5552 enum machine_mode mode
)
5554 int maxsize
= 2 * BITS_PER_WORD
;
5556 if (GET_MODE_CLASS (mode
) != MODE_INT
)
5558 if (maxsize
< LONG_LONG_TYPE_SIZE
)
5559 maxsize
= LONG_LONG_TYPE_SIZE
;
5560 if (GET_MODE_CLASS (mode
) != MODE_INT
5561 || mode
< word_mode
|| GET_MODE_BITSIZE (mode
) > maxsize
)
5563 gen_libfunc (optable
, opname
, suffix
, mode
);
5566 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */
5569 gen_fp_libfunc (optab optable
, const char *opname
, char suffix
,
5570 enum machine_mode mode
)
5574 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5575 gen_libfunc (optable
, opname
, suffix
, mode
);
5576 if (DECIMAL_FLOAT_MODE_P (mode
))
5578 dec_opname
= XALLOCAVEC (char, sizeof (DECIMAL_PREFIX
) + strlen (opname
));
5579 /* For BID support, change the name to have either a bid_ or dpd_ prefix
5580 depending on the low level floating format used. */
5581 memcpy (dec_opname
, DECIMAL_PREFIX
, sizeof (DECIMAL_PREFIX
) - 1);
5582 strcpy (dec_opname
+ sizeof (DECIMAL_PREFIX
) - 1, opname
);
5583 gen_libfunc (optable
, dec_opname
, suffix
, mode
);
5587 /* Like gen_libfunc, but verify that fixed-point operation is involved. */
5590 gen_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5591 enum machine_mode mode
)
5593 if (!ALL_FIXED_POINT_MODE_P (mode
))
5595 gen_libfunc (optable
, opname
, suffix
, mode
);
5598 /* Like gen_libfunc, but verify that signed fixed-point operation is
5602 gen_signed_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5603 enum machine_mode mode
)
5605 if (!SIGNED_FIXED_POINT_MODE_P (mode
))
5607 gen_libfunc (optable
, opname
, suffix
, mode
);
5610 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
5614 gen_unsigned_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5615 enum machine_mode mode
)
5617 if (!UNSIGNED_FIXED_POINT_MODE_P (mode
))
5619 gen_libfunc (optable
, opname
, suffix
, mode
);
5622 /* Like gen_libfunc, but verify that FP or INT operation is involved. */
5625 gen_int_fp_libfunc (optab optable
, const char *name
, char suffix
,
5626 enum machine_mode mode
)
5628 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5629 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5630 if (INTEGRAL_MODE_P (mode
))
5631 gen_int_libfunc (optable
, name
, suffix
, mode
);
5634 /* Like gen_libfunc, but verify that FP or INT operation is involved
5635 and add 'v' suffix for integer operation. */
5638 gen_intv_fp_libfunc (optab optable
, const char *name
, char suffix
,
5639 enum machine_mode mode
)
5641 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5642 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5643 if (GET_MODE_CLASS (mode
) == MODE_INT
)
5645 int len
= strlen (name
);
5646 char *v_name
= XALLOCAVEC (char, len
+ 2);
5647 strcpy (v_name
, name
);
5649 v_name
[len
+ 1] = 0;
5650 gen_int_libfunc (optable
, v_name
, suffix
, mode
);
5654 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
5658 gen_int_fp_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5659 enum machine_mode mode
)
5661 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5662 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5663 if (INTEGRAL_MODE_P (mode
))
5664 gen_int_libfunc (optable
, name
, suffix
, mode
);
5665 if (ALL_FIXED_POINT_MODE_P (mode
))
5666 gen_fixed_libfunc (optable
, name
, suffix
, mode
);
5669 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
5673 gen_int_fp_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5674 enum machine_mode mode
)
5676 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5677 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5678 if (INTEGRAL_MODE_P (mode
))
5679 gen_int_libfunc (optable
, name
, suffix
, mode
);
5680 if (SIGNED_FIXED_POINT_MODE_P (mode
))
5681 gen_signed_fixed_libfunc (optable
, name
, suffix
, mode
);
5684 /* Like gen_libfunc, but verify that INT or FIXED operation is
5688 gen_int_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5689 enum machine_mode mode
)
5691 if (INTEGRAL_MODE_P (mode
))
5692 gen_int_libfunc (optable
, name
, suffix
, mode
);
5693 if (ALL_FIXED_POINT_MODE_P (mode
))
5694 gen_fixed_libfunc (optable
, name
, suffix
, mode
);
5697 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
5701 gen_int_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5702 enum machine_mode mode
)
5704 if (INTEGRAL_MODE_P (mode
))
5705 gen_int_libfunc (optable
, name
, suffix
, mode
);
5706 if (SIGNED_FIXED_POINT_MODE_P (mode
))
5707 gen_signed_fixed_libfunc (optable
, name
, suffix
, mode
);
5710 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
5714 gen_int_unsigned_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5715 enum machine_mode mode
)
5717 if (INTEGRAL_MODE_P (mode
))
5718 gen_int_libfunc (optable
, name
, suffix
, mode
);
5719 if (UNSIGNED_FIXED_POINT_MODE_P (mode
))
5720 gen_unsigned_fixed_libfunc (optable
, name
, suffix
, mode
);
5723 /* Initialize the libfunc fields of an entire group of entries of an
5724 inter-mode-class conversion optab. The string formation rules are
5725 similar to the ones for init_libfuncs, above, but instead of having
5726 a mode name and an operand count these functions have two mode names
5727 and no operand count. */
5730 gen_interclass_conv_libfunc (convert_optab tab
,
5732 enum machine_mode tmode
,
5733 enum machine_mode fmode
)
5735 size_t opname_len
= strlen (opname
);
5736 size_t mname_len
= 0;
5738 const char *fname
, *tname
;
5740 char *libfunc_name
, *suffix
;
5741 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
5744 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5745 depends on which underlying decimal floating point format is used. */
5746 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
5748 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
5750 nondec_name
= XALLOCAVEC (char, 2 + opname_len
+ mname_len
+ 1 + 1);
5751 nondec_name
[0] = '_';
5752 nondec_name
[1] = '_';
5753 memcpy (&nondec_name
[2], opname
, opname_len
);
5754 nondec_suffix
= nondec_name
+ opname_len
+ 2;
5756 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 1);
5759 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
5760 memcpy (&dec_name
[2+dec_len
], opname
, opname_len
);
5761 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
5763 fname
= GET_MODE_NAME (fmode
);
5764 tname
= GET_MODE_NAME (tmode
);
5766 if (DECIMAL_FLOAT_MODE_P(fmode
) || DECIMAL_FLOAT_MODE_P(tmode
))
5768 libfunc_name
= dec_name
;
5769 suffix
= dec_suffix
;
5773 libfunc_name
= nondec_name
;
5774 suffix
= nondec_suffix
;
5778 for (q
= fname
; *q
; p
++, q
++)
5780 for (q
= tname
; *q
; p
++, q
++)
5785 set_conv_libfunc (tab
, tmode
, fmode
,
5786 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5789 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5790 int->fp conversion. */
5793 gen_int_to_fp_conv_libfunc (convert_optab tab
,
5795 enum machine_mode tmode
,
5796 enum machine_mode fmode
)
5798 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
5800 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
5802 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5805 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
5809 gen_ufloat_conv_libfunc (convert_optab tab
,
5810 const char *opname ATTRIBUTE_UNUSED
,
5811 enum machine_mode tmode
,
5812 enum machine_mode fmode
)
5814 if (DECIMAL_FLOAT_MODE_P (tmode
))
5815 gen_int_to_fp_conv_libfunc (tab
, "floatuns", tmode
, fmode
);
5817 gen_int_to_fp_conv_libfunc (tab
, "floatun", tmode
, fmode
);
5820 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5821 fp->int conversion. */
5824 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab
,
5826 enum machine_mode tmode
,
5827 enum machine_mode fmode
)
5829 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
5831 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
)
5833 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5836 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5837 fp->int conversion with no decimal floating point involved. */
5840 gen_fp_to_int_conv_libfunc (convert_optab tab
,
5842 enum machine_mode tmode
,
5843 enum machine_mode fmode
)
5845 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
5847 if (GET_MODE_CLASS (tmode
) != MODE_INT
)
5849 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5852 /* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
5853 The string formation rules are
5854 similar to the ones for init_libfunc, above. */
5857 gen_intraclass_conv_libfunc (convert_optab tab
, const char *opname
,
5858 enum machine_mode tmode
, enum machine_mode fmode
)
5860 size_t opname_len
= strlen (opname
);
5861 size_t mname_len
= 0;
5863 const char *fname
, *tname
;
5865 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
5866 char *libfunc_name
, *suffix
;
5869 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5870 depends on which underlying decimal floating point format is used. */
5871 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
5873 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
5875 nondec_name
= XALLOCAVEC (char, 2 + opname_len
+ mname_len
+ 1 + 1);
5876 nondec_name
[0] = '_';
5877 nondec_name
[1] = '_';
5878 memcpy (&nondec_name
[2], opname
, opname_len
);
5879 nondec_suffix
= nondec_name
+ opname_len
+ 2;
5881 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 1);
5884 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
5885 memcpy (&dec_name
[2 + dec_len
], opname
, opname_len
);
5886 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
5888 fname
= GET_MODE_NAME (fmode
);
5889 tname
= GET_MODE_NAME (tmode
);
5891 if (DECIMAL_FLOAT_MODE_P(fmode
) || DECIMAL_FLOAT_MODE_P(tmode
))
5893 libfunc_name
= dec_name
;
5894 suffix
= dec_suffix
;
5898 libfunc_name
= nondec_name
;
5899 suffix
= nondec_suffix
;
5903 for (q
= fname
; *q
; p
++, q
++)
5905 for (q
= tname
; *q
; p
++, q
++)
5911 set_conv_libfunc (tab
, tmode
, fmode
,
5912 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5915 /* Pick proper libcall for trunc_optab. We need to chose if we do
5916 truncation or extension and interclass or intraclass. */
5919 gen_trunc_conv_libfunc (convert_optab tab
,
5921 enum machine_mode tmode
,
5922 enum machine_mode fmode
)
5924 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
5926 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
5931 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (fmode
))
5932 || (GET_MODE_CLASS (fmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (tmode
)))
5933 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5935 if (GET_MODE_PRECISION (fmode
) <= GET_MODE_PRECISION (tmode
))
5938 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
5939 && GET_MODE_CLASS (fmode
) == MODE_FLOAT
)
5940 || (DECIMAL_FLOAT_MODE_P (fmode
) && DECIMAL_FLOAT_MODE_P (tmode
)))
5941 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5944 /* Pick proper libcall for extend_optab. We need to chose if we do
5945 truncation or extension and interclass or intraclass. */
5948 gen_extend_conv_libfunc (convert_optab tab
,
5949 const char *opname ATTRIBUTE_UNUSED
,
5950 enum machine_mode tmode
,
5951 enum machine_mode fmode
)
5953 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
5955 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
5960 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (fmode
))
5961 || (GET_MODE_CLASS (fmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (tmode
)))
5962 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5964 if (GET_MODE_PRECISION (fmode
) > GET_MODE_PRECISION (tmode
))
5967 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
5968 && GET_MODE_CLASS (fmode
) == MODE_FLOAT
)
5969 || (DECIMAL_FLOAT_MODE_P (fmode
) && DECIMAL_FLOAT_MODE_P (tmode
)))
5970 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5973 /* Pick proper libcall for fract_optab. We need to chose if we do
5974 interclass or intraclass. */
5977 gen_fract_conv_libfunc (convert_optab tab
,
5979 enum machine_mode tmode
,
5980 enum machine_mode fmode
)
5984 if (!(ALL_FIXED_POINT_MODE_P (tmode
) || ALL_FIXED_POINT_MODE_P (fmode
)))
5987 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
5988 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5990 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5993 /* Pick proper libcall for fractuns_optab. */
5996 gen_fractuns_conv_libfunc (convert_optab tab
,
5998 enum machine_mode tmode
,
5999 enum machine_mode fmode
)
6003 /* One mode must be a fixed-point mode, and the other must be an integer
6005 if (!((ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
)
6006 || (ALL_FIXED_POINT_MODE_P (fmode
)
6007 && GET_MODE_CLASS (tmode
) == MODE_INT
)))
6010 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6013 /* Pick proper libcall for satfract_optab. We need to chose if we do
6014 interclass or intraclass. */
6017 gen_satfract_conv_libfunc (convert_optab tab
,
6019 enum machine_mode tmode
,
6020 enum machine_mode fmode
)
6024 /* TMODE must be a fixed-point mode. */
6025 if (!ALL_FIXED_POINT_MODE_P (tmode
))
6028 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
6029 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6031 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6034 /* Pick proper libcall for satfractuns_optab. */
6037 gen_satfractuns_conv_libfunc (convert_optab tab
,
6039 enum machine_mode tmode
,
6040 enum machine_mode fmode
)
6044 /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
6045 if (!(ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
))
6048 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6051 /* A table of previously-created libfuncs, hashed by name. */
6052 static GTY ((param_is (union tree_node
))) htab_t libfunc_decls
;
6054 /* Hashtable callbacks for libfunc_decls. */
6057 libfunc_decl_hash (const void *entry
)
6059 return htab_hash_string (IDENTIFIER_POINTER (DECL_NAME ((const_tree
) entry
)));
6063 libfunc_decl_eq (const void *entry1
, const void *entry2
)
6065 return DECL_NAME ((const_tree
) entry1
) == (const_tree
) entry2
;
6068 /* Build a decl for a libfunc named NAME. */
6071 build_libfunc_function (const char *name
)
6073 tree decl
= build_decl (UNKNOWN_LOCATION
, FUNCTION_DECL
,
6074 get_identifier (name
),
6075 build_function_type (integer_type_node
, NULL_TREE
));
6076 /* ??? We don't have any type information except for this is
6077 a function. Pretend this is "int foo()". */
6078 DECL_ARTIFICIAL (decl
) = 1;
6079 DECL_EXTERNAL (decl
) = 1;
6080 TREE_PUBLIC (decl
) = 1;
6081 gcc_assert (DECL_ASSEMBLER_NAME (decl
));
6083 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
6084 are the flags assigned by targetm.encode_section_info. */
6085 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl
), 0), NULL
);
6091 init_one_libfunc (const char *name
)
6097 if (libfunc_decls
== NULL
)
6098 libfunc_decls
= htab_create_ggc (37, libfunc_decl_hash
,
6099 libfunc_decl_eq
, NULL
);
6101 /* See if we have already created a libfunc decl for this function. */
6102 id
= get_identifier (name
);
6103 hash
= htab_hash_string (name
);
6104 slot
= htab_find_slot_with_hash (libfunc_decls
, id
, hash
, INSERT
);
6105 decl
= (tree
) *slot
;
6108 /* Create a new decl, so that it can be passed to
6109 targetm.encode_section_info. */
6110 decl
= build_libfunc_function (name
);
6113 return XEXP (DECL_RTL (decl
), 0);
6116 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */
6119 set_user_assembler_libfunc (const char *name
, const char *asmspec
)
6125 id
= get_identifier (name
);
6126 hash
= htab_hash_string (name
);
6127 slot
= htab_find_slot_with_hash (libfunc_decls
, id
, hash
, NO_INSERT
);
6129 decl
= (tree
) *slot
;
6130 set_user_assembler_name (decl
, asmspec
);
6131 return XEXP (DECL_RTL (decl
), 0);
6134 /* Call this to reset the function entry for one optab (OPTABLE) in mode
6135 MODE to NAME, which should be either 0 or a string constant. */
6137 set_optab_libfunc (optab optable
, enum machine_mode mode
, const char *name
)
6140 struct libfunc_entry e
;
6141 struct libfunc_entry
**slot
;
6142 e
.optab
= (size_t) (optable
- &optab_table
[0]);
6147 val
= init_one_libfunc (name
);
6150 slot
= (struct libfunc_entry
**) htab_find_slot (libfunc_hash
, &e
, INSERT
);
6152 *slot
= GGC_NEW (struct libfunc_entry
);
6153 (*slot
)->optab
= (size_t) (optable
- &optab_table
[0]);
6154 (*slot
)->mode1
= mode
;
6155 (*slot
)->mode2
= VOIDmode
;
6156 (*slot
)->libfunc
= val
;
6159 /* Call this to reset the function entry for one conversion optab
6160 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
6161 either 0 or a string constant. */
6163 set_conv_libfunc (convert_optab optable
, enum machine_mode tmode
,
6164 enum machine_mode fmode
, const char *name
)
6167 struct libfunc_entry e
;
6168 struct libfunc_entry
**slot
;
6169 e
.optab
= (size_t) (optable
- &convert_optab_table
[0]);
6174 val
= init_one_libfunc (name
);
6177 slot
= (struct libfunc_entry
**) htab_find_slot (libfunc_hash
, &e
, INSERT
);
6179 *slot
= GGC_NEW (struct libfunc_entry
);
6180 (*slot
)->optab
= (size_t) (optable
- &convert_optab_table
[0]);
6181 (*slot
)->mode1
= tmode
;
6182 (*slot
)->mode2
= fmode
;
6183 (*slot
)->libfunc
= val
;
6186 /* Call this to initialize the contents of the optabs
6187 appropriately for the current target machine. */
6195 libfunc_hash
= htab_create_ggc (10, hash_libfunc
, eq_libfunc
, NULL
);
6196 /* Start by initializing all tables to contain CODE_FOR_nothing. */
6198 #ifdef HAVE_conditional_move
6199 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
6200 movcc_gen_code
[i
] = CODE_FOR_nothing
;
6203 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
6205 vcond_gen_code
[i
] = CODE_FOR_nothing
;
6206 vcondu_gen_code
[i
] = CODE_FOR_nothing
;
6209 #if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
6210 /* We statically initialize the insn_codes with CODE_FOR_nothing. */
6217 init_optab (add_optab
, PLUS
);
6218 init_optabv (addv_optab
, PLUS
);
6219 init_optab (sub_optab
, MINUS
);
6220 init_optabv (subv_optab
, MINUS
);
6221 init_optab (ssadd_optab
, SS_PLUS
);
6222 init_optab (usadd_optab
, US_PLUS
);
6223 init_optab (sssub_optab
, SS_MINUS
);
6224 init_optab (ussub_optab
, US_MINUS
);
6225 init_optab (smul_optab
, MULT
);
6226 init_optab (ssmul_optab
, SS_MULT
);
6227 init_optab (usmul_optab
, US_MULT
);
6228 init_optabv (smulv_optab
, MULT
);
6229 init_optab (smul_highpart_optab
, UNKNOWN
);
6230 init_optab (umul_highpart_optab
, UNKNOWN
);
6231 init_optab (smul_widen_optab
, UNKNOWN
);
6232 init_optab (umul_widen_optab
, UNKNOWN
);
6233 init_optab (usmul_widen_optab
, UNKNOWN
);
6234 init_optab (smadd_widen_optab
, UNKNOWN
);
6235 init_optab (umadd_widen_optab
, UNKNOWN
);
6236 init_optab (ssmadd_widen_optab
, UNKNOWN
);
6237 init_optab (usmadd_widen_optab
, UNKNOWN
);
6238 init_optab (smsub_widen_optab
, UNKNOWN
);
6239 init_optab (umsub_widen_optab
, UNKNOWN
);
6240 init_optab (ssmsub_widen_optab
, UNKNOWN
);
6241 init_optab (usmsub_widen_optab
, UNKNOWN
);
6242 init_optab (sdiv_optab
, DIV
);
6243 init_optab (ssdiv_optab
, SS_DIV
);
6244 init_optab (usdiv_optab
, US_DIV
);
6245 init_optabv (sdivv_optab
, DIV
);
6246 init_optab (sdivmod_optab
, UNKNOWN
);
6247 init_optab (udiv_optab
, UDIV
);
6248 init_optab (udivmod_optab
, UNKNOWN
);
6249 init_optab (smod_optab
, MOD
);
6250 init_optab (umod_optab
, UMOD
);
6251 init_optab (fmod_optab
, UNKNOWN
);
6252 init_optab (remainder_optab
, UNKNOWN
);
6253 init_optab (ftrunc_optab
, UNKNOWN
);
6254 init_optab (and_optab
, AND
);
6255 init_optab (ior_optab
, IOR
);
6256 init_optab (xor_optab
, XOR
);
6257 init_optab (ashl_optab
, ASHIFT
);
6258 init_optab (ssashl_optab
, SS_ASHIFT
);
6259 init_optab (usashl_optab
, US_ASHIFT
);
6260 init_optab (ashr_optab
, ASHIFTRT
);
6261 init_optab (lshr_optab
, LSHIFTRT
);
6262 init_optab (rotl_optab
, ROTATE
);
6263 init_optab (rotr_optab
, ROTATERT
);
6264 init_optab (smin_optab
, SMIN
);
6265 init_optab (smax_optab
, SMAX
);
6266 init_optab (umin_optab
, UMIN
);
6267 init_optab (umax_optab
, UMAX
);
6268 init_optab (pow_optab
, UNKNOWN
);
6269 init_optab (atan2_optab
, UNKNOWN
);
6271 /* These three have codes assigned exclusively for the sake of
6273 init_optab (mov_optab
, SET
);
6274 init_optab (movstrict_optab
, STRICT_LOW_PART
);
6275 init_optab (cbranch_optab
, COMPARE
);
6277 init_optab (cmov_optab
, UNKNOWN
);
6278 init_optab (cstore_optab
, UNKNOWN
);
6279 init_optab (ctrap_optab
, UNKNOWN
);
6281 init_optab (storent_optab
, UNKNOWN
);
6283 init_optab (cmp_optab
, UNKNOWN
);
6284 init_optab (ucmp_optab
, UNKNOWN
);
6286 init_optab (eq_optab
, EQ
);
6287 init_optab (ne_optab
, NE
);
6288 init_optab (gt_optab
, GT
);
6289 init_optab (ge_optab
, GE
);
6290 init_optab (lt_optab
, LT
);
6291 init_optab (le_optab
, LE
);
6292 init_optab (unord_optab
, UNORDERED
);
6294 init_optab (neg_optab
, NEG
);
6295 init_optab (ssneg_optab
, SS_NEG
);
6296 init_optab (usneg_optab
, US_NEG
);
6297 init_optabv (negv_optab
, NEG
);
6298 init_optab (abs_optab
, ABS
);
6299 init_optabv (absv_optab
, ABS
);
6300 init_optab (addcc_optab
, UNKNOWN
);
6301 init_optab (one_cmpl_optab
, NOT
);
6302 init_optab (bswap_optab
, BSWAP
);
6303 init_optab (ffs_optab
, FFS
);
6304 init_optab (clz_optab
, CLZ
);
6305 init_optab (ctz_optab
, CTZ
);
6306 init_optab (popcount_optab
, POPCOUNT
);
6307 init_optab (parity_optab
, PARITY
);
6308 init_optab (sqrt_optab
, SQRT
);
6309 init_optab (floor_optab
, UNKNOWN
);
6310 init_optab (ceil_optab
, UNKNOWN
);
6311 init_optab (round_optab
, UNKNOWN
);
6312 init_optab (btrunc_optab
, UNKNOWN
);
6313 init_optab (nearbyint_optab
, UNKNOWN
);
6314 init_optab (rint_optab
, UNKNOWN
);
6315 init_optab (sincos_optab
, UNKNOWN
);
6316 init_optab (sin_optab
, UNKNOWN
);
6317 init_optab (asin_optab
, UNKNOWN
);
6318 init_optab (cos_optab
, UNKNOWN
);
6319 init_optab (acos_optab
, UNKNOWN
);
6320 init_optab (exp_optab
, UNKNOWN
);
6321 init_optab (exp10_optab
, UNKNOWN
);
6322 init_optab (exp2_optab
, UNKNOWN
);
6323 init_optab (expm1_optab
, UNKNOWN
);
6324 init_optab (ldexp_optab
, UNKNOWN
);
6325 init_optab (scalb_optab
, UNKNOWN
);
6326 init_optab (significand_optab
, UNKNOWN
);
6327 init_optab (logb_optab
, UNKNOWN
);
6328 init_optab (ilogb_optab
, UNKNOWN
);
6329 init_optab (log_optab
, UNKNOWN
);
6330 init_optab (log10_optab
, UNKNOWN
);
6331 init_optab (log2_optab
, UNKNOWN
);
6332 init_optab (log1p_optab
, UNKNOWN
);
6333 init_optab (tan_optab
, UNKNOWN
);
6334 init_optab (atan_optab
, UNKNOWN
);
6335 init_optab (copysign_optab
, UNKNOWN
);
6336 init_optab (signbit_optab
, UNKNOWN
);
6338 init_optab (isinf_optab
, UNKNOWN
);
6340 init_optab (strlen_optab
, UNKNOWN
);
6341 init_optab (push_optab
, UNKNOWN
);
6343 init_optab (reduc_smax_optab
, UNKNOWN
);
6344 init_optab (reduc_umax_optab
, UNKNOWN
);
6345 init_optab (reduc_smin_optab
, UNKNOWN
);
6346 init_optab (reduc_umin_optab
, UNKNOWN
);
6347 init_optab (reduc_splus_optab
, UNKNOWN
);
6348 init_optab (reduc_uplus_optab
, UNKNOWN
);
6350 init_optab (ssum_widen_optab
, UNKNOWN
);
6351 init_optab (usum_widen_optab
, UNKNOWN
);
6352 init_optab (sdot_prod_optab
, UNKNOWN
);
6353 init_optab (udot_prod_optab
, UNKNOWN
);
6355 init_optab (vec_extract_optab
, UNKNOWN
);
6356 init_optab (vec_extract_even_optab
, UNKNOWN
);
6357 init_optab (vec_extract_odd_optab
, UNKNOWN
);
6358 init_optab (vec_interleave_high_optab
, UNKNOWN
);
6359 init_optab (vec_interleave_low_optab
, UNKNOWN
);
6360 init_optab (vec_set_optab
, UNKNOWN
);
6361 init_optab (vec_init_optab
, UNKNOWN
);
6362 init_optab (vec_shl_optab
, UNKNOWN
);
6363 init_optab (vec_shr_optab
, UNKNOWN
);
6364 init_optab (vec_realign_load_optab
, UNKNOWN
);
6365 init_optab (movmisalign_optab
, UNKNOWN
);
6366 init_optab (vec_widen_umult_hi_optab
, UNKNOWN
);
6367 init_optab (vec_widen_umult_lo_optab
, UNKNOWN
);
6368 init_optab (vec_widen_smult_hi_optab
, UNKNOWN
);
6369 init_optab (vec_widen_smult_lo_optab
, UNKNOWN
);
6370 init_optab (vec_unpacks_hi_optab
, UNKNOWN
);
6371 init_optab (vec_unpacks_lo_optab
, UNKNOWN
);
6372 init_optab (vec_unpacku_hi_optab
, UNKNOWN
);
6373 init_optab (vec_unpacku_lo_optab
, UNKNOWN
);
6374 init_optab (vec_unpacks_float_hi_optab
, UNKNOWN
);
6375 init_optab (vec_unpacks_float_lo_optab
, UNKNOWN
);
6376 init_optab (vec_unpacku_float_hi_optab
, UNKNOWN
);
6377 init_optab (vec_unpacku_float_lo_optab
, UNKNOWN
);
6378 init_optab (vec_pack_trunc_optab
, UNKNOWN
);
6379 init_optab (vec_pack_usat_optab
, UNKNOWN
);
6380 init_optab (vec_pack_ssat_optab
, UNKNOWN
);
6381 init_optab (vec_pack_ufix_trunc_optab
, UNKNOWN
);
6382 init_optab (vec_pack_sfix_trunc_optab
, UNKNOWN
);
6384 init_optab (powi_optab
, UNKNOWN
);
6387 init_convert_optab (sext_optab
, SIGN_EXTEND
);
6388 init_convert_optab (zext_optab
, ZERO_EXTEND
);
6389 init_convert_optab (trunc_optab
, TRUNCATE
);
6390 init_convert_optab (sfix_optab
, FIX
);
6391 init_convert_optab (ufix_optab
, UNSIGNED_FIX
);
6392 init_convert_optab (sfixtrunc_optab
, UNKNOWN
);
6393 init_convert_optab (ufixtrunc_optab
, UNKNOWN
);
6394 init_convert_optab (sfloat_optab
, FLOAT
);
6395 init_convert_optab (ufloat_optab
, UNSIGNED_FLOAT
);
6396 init_convert_optab (lrint_optab
, UNKNOWN
);
6397 init_convert_optab (lround_optab
, UNKNOWN
);
6398 init_convert_optab (lfloor_optab
, UNKNOWN
);
6399 init_convert_optab (lceil_optab
, UNKNOWN
);
6401 init_convert_optab (fract_optab
, FRACT_CONVERT
);
6402 init_convert_optab (fractuns_optab
, UNSIGNED_FRACT_CONVERT
);
6403 init_convert_optab (satfract_optab
, SAT_FRACT
);
6404 init_convert_optab (satfractuns_optab
, UNSIGNED_SAT_FRACT
);
6406 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
6408 movmem_optab
[i
] = CODE_FOR_nothing
;
6409 cmpstr_optab
[i
] = CODE_FOR_nothing
;
6410 cmpstrn_optab
[i
] = CODE_FOR_nothing
;
6411 cmpmem_optab
[i
] = CODE_FOR_nothing
;
6412 setmem_optab
[i
] = CODE_FOR_nothing
;
6414 sync_add_optab
[i
] = CODE_FOR_nothing
;
6415 sync_sub_optab
[i
] = CODE_FOR_nothing
;
6416 sync_ior_optab
[i
] = CODE_FOR_nothing
;
6417 sync_and_optab
[i
] = CODE_FOR_nothing
;
6418 sync_xor_optab
[i
] = CODE_FOR_nothing
;
6419 sync_nand_optab
[i
] = CODE_FOR_nothing
;
6420 sync_old_add_optab
[i
] = CODE_FOR_nothing
;
6421 sync_old_sub_optab
[i
] = CODE_FOR_nothing
;
6422 sync_old_ior_optab
[i
] = CODE_FOR_nothing
;
6423 sync_old_and_optab
[i
] = CODE_FOR_nothing
;
6424 sync_old_xor_optab
[i
] = CODE_FOR_nothing
;
6425 sync_old_nand_optab
[i
] = CODE_FOR_nothing
;
6426 sync_new_add_optab
[i
] = CODE_FOR_nothing
;
6427 sync_new_sub_optab
[i
] = CODE_FOR_nothing
;
6428 sync_new_ior_optab
[i
] = CODE_FOR_nothing
;
6429 sync_new_and_optab
[i
] = CODE_FOR_nothing
;
6430 sync_new_xor_optab
[i
] = CODE_FOR_nothing
;
6431 sync_new_nand_optab
[i
] = CODE_FOR_nothing
;
6432 sync_compare_and_swap
[i
] = CODE_FOR_nothing
;
6433 sync_lock_test_and_set
[i
] = CODE_FOR_nothing
;
6434 sync_lock_release
[i
] = CODE_FOR_nothing
;
6436 reload_in_optab
[i
] = reload_out_optab
[i
] = CODE_FOR_nothing
;
6439 /* Fill in the optabs with the insns we support. */
6442 /* Initialize the optabs with the names of the library functions. */
6443 add_optab
->libcall_basename
= "add";
6444 add_optab
->libcall_suffix
= '3';
6445 add_optab
->libcall_gen
= gen_int_fp_fixed_libfunc
;
6446 addv_optab
->libcall_basename
= "add";
6447 addv_optab
->libcall_suffix
= '3';
6448 addv_optab
->libcall_gen
= gen_intv_fp_libfunc
;
6449 ssadd_optab
->libcall_basename
= "ssadd";
6450 ssadd_optab
->libcall_suffix
= '3';
6451 ssadd_optab
->libcall_gen
= gen_signed_fixed_libfunc
;
6452 usadd_optab
->libcall_basename
= "usadd";
6453 usadd_optab
->libcall_suffix
= '3';
6454 usadd_optab
->libcall_gen
= gen_unsigned_fixed_libfunc
;
6455 sub_optab
->libcall_basename
= "sub";
6456 sub_optab
->libcall_suffix
= '3';
6457 sub_optab
->libcall_gen
= gen_int_fp_fixed_libfunc
;
6458 subv_optab
->libcall_basename
= "sub";
6459 subv_optab
->libcall_suffix
= '3';
6460 subv_optab
->libcall_gen
= gen_intv_fp_libfunc
;
6461 sssub_optab
->libcall_basename
= "sssub";
6462 sssub_optab
->libcall_suffix
= '3';
6463 sssub_optab
->libcall_gen
= gen_signed_fixed_libfunc
;
6464 ussub_optab
->libcall_basename
= "ussub";
6465 ussub_optab
->libcall_suffix
= '3';
6466 ussub_optab
->libcall_gen
= gen_unsigned_fixed_libfunc
;
6467 smul_optab
->libcall_basename
= "mul";
6468 smul_optab
->libcall_suffix
= '3';
6469 smul_optab
->libcall_gen
= gen_int_fp_fixed_libfunc
;
6470 smulv_optab
->libcall_basename
= "mul";
6471 smulv_optab
->libcall_suffix
= '3';
6472 smulv_optab
->libcall_gen
= gen_intv_fp_libfunc
;
6473 ssmul_optab
->libcall_basename
= "ssmul";
6474 ssmul_optab
->libcall_suffix
= '3';
6475 ssmul_optab
->libcall_gen
= gen_signed_fixed_libfunc
;
6476 usmul_optab
->libcall_basename
= "usmul";
6477 usmul_optab
->libcall_suffix
= '3';
6478 usmul_optab
->libcall_gen
= gen_unsigned_fixed_libfunc
;
6479 sdiv_optab
->libcall_basename
= "div";
6480 sdiv_optab
->libcall_suffix
= '3';
6481 sdiv_optab
->libcall_gen
= gen_int_fp_signed_fixed_libfunc
;
6482 sdivv_optab
->libcall_basename
= "divv";
6483 sdivv_optab
->libcall_suffix
= '3';
6484 sdivv_optab
->libcall_gen
= gen_int_libfunc
;
6485 ssdiv_optab
->libcall_basename
= "ssdiv";
6486 ssdiv_optab
->libcall_suffix
= '3';
6487 ssdiv_optab
->libcall_gen
= gen_signed_fixed_libfunc
;
6488 udiv_optab
->libcall_basename
= "udiv";
6489 udiv_optab
->libcall_suffix
= '3';
6490 udiv_optab
->libcall_gen
= gen_int_unsigned_fixed_libfunc
;
6491 usdiv_optab
->libcall_basename
= "usdiv";
6492 usdiv_optab
->libcall_suffix
= '3';
6493 usdiv_optab
->libcall_gen
= gen_unsigned_fixed_libfunc
;
6494 sdivmod_optab
->libcall_basename
= "divmod";
6495 sdivmod_optab
->libcall_suffix
= '4';
6496 sdivmod_optab
->libcall_gen
= gen_int_libfunc
;
6497 udivmod_optab
->libcall_basename
= "udivmod";
6498 udivmod_optab
->libcall_suffix
= '4';
6499 udivmod_optab
->libcall_gen
= gen_int_libfunc
;
6500 smod_optab
->libcall_basename
= "mod";
6501 smod_optab
->libcall_suffix
= '3';
6502 smod_optab
->libcall_gen
= gen_int_libfunc
;
6503 umod_optab
->libcall_basename
= "umod";
6504 umod_optab
->libcall_suffix
= '3';
6505 umod_optab
->libcall_gen
= gen_int_libfunc
;
6506 ftrunc_optab
->libcall_basename
= "ftrunc";
6507 ftrunc_optab
->libcall_suffix
= '2';
6508 ftrunc_optab
->libcall_gen
= gen_fp_libfunc
;
6509 and_optab
->libcall_basename
= "and";
6510 and_optab
->libcall_suffix
= '3';
6511 and_optab
->libcall_gen
= gen_int_libfunc
;
6512 ior_optab
->libcall_basename
= "ior";
6513 ior_optab
->libcall_suffix
= '3';
6514 ior_optab
->libcall_gen
= gen_int_libfunc
;
6515 xor_optab
->libcall_basename
= "xor";
6516 xor_optab
->libcall_suffix
= '3';
6517 xor_optab
->libcall_gen
= gen_int_libfunc
;
6518 ashl_optab
->libcall_basename
= "ashl";
6519 ashl_optab
->libcall_suffix
= '3';
6520 ashl_optab
->libcall_gen
= gen_int_fixed_libfunc
;
6521 ssashl_optab
->libcall_basename
= "ssashl";
6522 ssashl_optab
->libcall_suffix
= '3';
6523 ssashl_optab
->libcall_gen
= gen_signed_fixed_libfunc
;
6524 usashl_optab
->libcall_basename
= "usashl";
6525 usashl_optab
->libcall_suffix
= '3';
6526 usashl_optab
->libcall_gen
= gen_unsigned_fixed_libfunc
;
6527 ashr_optab
->libcall_basename
= "ashr";
6528 ashr_optab
->libcall_suffix
= '3';
6529 ashr_optab
->libcall_gen
= gen_int_signed_fixed_libfunc
;
6530 lshr_optab
->libcall_basename
= "lshr";
6531 lshr_optab
->libcall_suffix
= '3';
6532 lshr_optab
->libcall_gen
= gen_int_unsigned_fixed_libfunc
;
6533 smin_optab
->libcall_basename
= "min";
6534 smin_optab
->libcall_suffix
= '3';
6535 smin_optab
->libcall_gen
= gen_int_fp_libfunc
;
6536 smax_optab
->libcall_basename
= "max";
6537 smax_optab
->libcall_suffix
= '3';
6538 smax_optab
->libcall_gen
= gen_int_fp_libfunc
;
6539 umin_optab
->libcall_basename
= "umin";
6540 umin_optab
->libcall_suffix
= '3';
6541 umin_optab
->libcall_gen
= gen_int_libfunc
;
6542 umax_optab
->libcall_basename
= "umax";
6543 umax_optab
->libcall_suffix
= '3';
6544 umax_optab
->libcall_gen
= gen_int_libfunc
;
6545 neg_optab
->libcall_basename
= "neg";
6546 neg_optab
->libcall_suffix
= '2';
6547 neg_optab
->libcall_gen
= gen_int_fp_fixed_libfunc
;
6548 ssneg_optab
->libcall_basename
= "ssneg";
6549 ssneg_optab
->libcall_suffix
= '2';
6550 ssneg_optab
->libcall_gen
= gen_signed_fixed_libfunc
;
6551 usneg_optab
->libcall_basename
= "usneg";
6552 usneg_optab
->libcall_suffix
= '2';
6553 usneg_optab
->libcall_gen
= gen_unsigned_fixed_libfunc
;
6554 negv_optab
->libcall_basename
= "neg";
6555 negv_optab
->libcall_suffix
= '2';
6556 negv_optab
->libcall_gen
= gen_intv_fp_libfunc
;
6557 one_cmpl_optab
->libcall_basename
= "one_cmpl";
6558 one_cmpl_optab
->libcall_suffix
= '2';
6559 one_cmpl_optab
->libcall_gen
= gen_int_libfunc
;
6560 ffs_optab
->libcall_basename
= "ffs";
6561 ffs_optab
->libcall_suffix
= '2';
6562 ffs_optab
->libcall_gen
= gen_int_libfunc
;
6563 clz_optab
->libcall_basename
= "clz";
6564 clz_optab
->libcall_suffix
= '2';
6565 clz_optab
->libcall_gen
= gen_int_libfunc
;
6566 ctz_optab
->libcall_basename
= "ctz";
6567 ctz_optab
->libcall_suffix
= '2';
6568 ctz_optab
->libcall_gen
= gen_int_libfunc
;
6569 popcount_optab
->libcall_basename
= "popcount";
6570 popcount_optab
->libcall_suffix
= '2';
6571 popcount_optab
->libcall_gen
= gen_int_libfunc
;
6572 parity_optab
->libcall_basename
= "parity";
6573 parity_optab
->libcall_suffix
= '2';
6574 parity_optab
->libcall_gen
= gen_int_libfunc
;
6576 /* Comparison libcalls for integers MUST come in pairs,
6578 cmp_optab
->libcall_basename
= "cmp";
6579 cmp_optab
->libcall_suffix
= '2';
6580 cmp_optab
->libcall_gen
= gen_int_fp_fixed_libfunc
;
6581 ucmp_optab
->libcall_basename
= "ucmp";
6582 ucmp_optab
->libcall_suffix
= '2';
6583 ucmp_optab
->libcall_gen
= gen_int_libfunc
;
6585 /* EQ etc are floating point only. */
6586 eq_optab
->libcall_basename
= "eq";
6587 eq_optab
->libcall_suffix
= '2';
6588 eq_optab
->libcall_gen
= gen_fp_libfunc
;
6589 ne_optab
->libcall_basename
= "ne";
6590 ne_optab
->libcall_suffix
= '2';
6591 ne_optab
->libcall_gen
= gen_fp_libfunc
;
6592 gt_optab
->libcall_basename
= "gt";
6593 gt_optab
->libcall_suffix
= '2';
6594 gt_optab
->libcall_gen
= gen_fp_libfunc
;
6595 ge_optab
->libcall_basename
= "ge";
6596 ge_optab
->libcall_suffix
= '2';
6597 ge_optab
->libcall_gen
= gen_fp_libfunc
;
6598 lt_optab
->libcall_basename
= "lt";
6599 lt_optab
->libcall_suffix
= '2';
6600 lt_optab
->libcall_gen
= gen_fp_libfunc
;
6601 le_optab
->libcall_basename
= "le";
6602 le_optab
->libcall_suffix
= '2';
6603 le_optab
->libcall_gen
= gen_fp_libfunc
;
6604 unord_optab
->libcall_basename
= "unord";
6605 unord_optab
->libcall_suffix
= '2';
6606 unord_optab
->libcall_gen
= gen_fp_libfunc
;
6608 powi_optab
->libcall_basename
= "powi";
6609 powi_optab
->libcall_suffix
= '2';
6610 powi_optab
->libcall_gen
= gen_fp_libfunc
;
6613 sfloat_optab
->libcall_basename
= "float";
6614 sfloat_optab
->libcall_gen
= gen_int_to_fp_conv_libfunc
;
6615 ufloat_optab
->libcall_gen
= gen_ufloat_conv_libfunc
;
6616 sfix_optab
->libcall_basename
= "fix";
6617 sfix_optab
->libcall_gen
= gen_fp_to_int_conv_libfunc
;
6618 ufix_optab
->libcall_basename
= "fixuns";
6619 ufix_optab
->libcall_gen
= gen_fp_to_int_conv_libfunc
;
6620 lrint_optab
->libcall_basename
= "lrint";
6621 lrint_optab
->libcall_gen
= gen_int_to_fp_nondecimal_conv_libfunc
;
6622 lround_optab
->libcall_basename
= "lround";
6623 lround_optab
->libcall_gen
= gen_int_to_fp_nondecimal_conv_libfunc
;
6624 lfloor_optab
->libcall_basename
= "lfloor";
6625 lfloor_optab
->libcall_gen
= gen_int_to_fp_nondecimal_conv_libfunc
;
6626 lceil_optab
->libcall_basename
= "lceil";
6627 lceil_optab
->libcall_gen
= gen_int_to_fp_nondecimal_conv_libfunc
;
6629 /* trunc_optab is also used for FLOAT_EXTEND. */
6630 sext_optab
->libcall_basename
= "extend";
6631 sext_optab
->libcall_gen
= gen_extend_conv_libfunc
;
6632 trunc_optab
->libcall_basename
= "trunc";
6633 trunc_optab
->libcall_gen
= gen_trunc_conv_libfunc
;
6635 /* Conversions for fixed-point modes and other modes. */
6636 fract_optab
->libcall_basename
= "fract";
6637 fract_optab
->libcall_gen
= gen_fract_conv_libfunc
;
6638 satfract_optab
->libcall_basename
= "satfract";
6639 satfract_optab
->libcall_gen
= gen_satfract_conv_libfunc
;
6640 fractuns_optab
->libcall_basename
= "fractuns";
6641 fractuns_optab
->libcall_gen
= gen_fractuns_conv_libfunc
;
6642 satfractuns_optab
->libcall_basename
= "satfractuns";
6643 satfractuns_optab
->libcall_gen
= gen_satfractuns_conv_libfunc
;
6645 /* The ffs function operates on `int'. Fall back on it if we do not
6646 have a libgcc2 function for that width. */
6647 if (INT_TYPE_SIZE
< BITS_PER_WORD
)
6648 set_optab_libfunc (ffs_optab
, mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0),
6651 /* Explicitly initialize the bswap libfuncs since we need them to be
6652 valid for things other than word_mode. */
6653 set_optab_libfunc (bswap_optab
, SImode
, "__bswapsi2");
6654 set_optab_libfunc (bswap_optab
, DImode
, "__bswapdi2");
6656 /* Use cabs for double complex abs, since systems generally have cabs.
6657 Don't define any libcall for float complex, so that cabs will be used. */
6658 if (complex_double_type_node
)
6659 set_optab_libfunc (abs_optab
, TYPE_MODE (complex_double_type_node
), "cabs");
6661 abort_libfunc
= init_one_libfunc ("abort");
6662 memcpy_libfunc
= init_one_libfunc ("memcpy");
6663 memmove_libfunc
= init_one_libfunc ("memmove");
6664 memcmp_libfunc
= init_one_libfunc ("memcmp");
6665 memset_libfunc
= init_one_libfunc ("memset");
6666 setbits_libfunc
= init_one_libfunc ("__setbits");
6668 #ifndef DONT_USE_BUILTIN_SETJMP
6669 setjmp_libfunc
= init_one_libfunc ("__builtin_setjmp");
6670 longjmp_libfunc
= init_one_libfunc ("__builtin_longjmp");
6672 setjmp_libfunc
= init_one_libfunc ("setjmp");
6673 longjmp_libfunc
= init_one_libfunc ("longjmp");
6675 unwind_sjlj_register_libfunc
= init_one_libfunc ("_Unwind_SjLj_Register");
6676 unwind_sjlj_unregister_libfunc
6677 = init_one_libfunc ("_Unwind_SjLj_Unregister");
6679 /* For function entry/exit instrumentation. */
6680 profile_function_entry_libfunc
6681 = init_one_libfunc ("__cyg_profile_func_enter");
6682 profile_function_exit_libfunc
6683 = init_one_libfunc ("__cyg_profile_func_exit");
6685 gcov_flush_libfunc
= init_one_libfunc ("__gcov_flush");
6687 /* Allow the target to add more libcalls or rename some, etc. */
6688 targetm
.init_libfuncs ();
6693 /* Print information about the current contents of the optabs on
6697 debug_optab_libfuncs (void)
6703 /* Dump the arithmetic optabs. */
6704 for (i
= 0; i
!= (int) OTI_MAX
; i
++)
6705 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
6710 o
= &optab_table
[i
];
6711 l
= optab_libfunc (o
, (enum machine_mode
) j
);
6714 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
6715 fprintf (stderr
, "%s\t%s:\t%s\n",
6716 GET_RTX_NAME (o
->code
),
6722 /* Dump the conversion optabs. */
6723 for (i
= 0; i
< (int) COI_MAX
; ++i
)
6724 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
6725 for (k
= 0; k
< NUM_MACHINE_MODES
; ++k
)
6730 o
= &convert_optab_table
[i
];
6731 l
= convert_optab_libfunc (o
, (enum machine_mode
) j
,
6732 (enum machine_mode
) k
);
6735 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
6736 fprintf (stderr
, "%s\t%s\t%s:\t%s\n",
6737 GET_RTX_NAME (o
->code
),
6746 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6747 CODE. Return 0 on failure. */
6750 gen_cond_trap (enum rtx_code code
, rtx op1
, rtx op2
, rtx tcode
)
6752 enum machine_mode mode
= GET_MODE (op1
);
6753 enum insn_code icode
;
6757 if (mode
== VOIDmode
)
6760 icode
= optab_handler (ctrap_optab
, mode
)->insn_code
;
6761 if (icode
== CODE_FOR_nothing
)
6764 /* Some targets only accept a zero trap code. */
6765 if (insn_data
[icode
].operand
[3].predicate
6766 && !insn_data
[icode
].operand
[3].predicate (tcode
, VOIDmode
))
6769 do_pending_stack_adjust ();
6771 prepare_cmp_insn (op1
, op2
, code
, NULL_RTX
, false, OPTAB_DIRECT
,
6776 insn
= GEN_FCN (icode
) (trap_rtx
, XEXP (trap_rtx
, 0), XEXP (trap_rtx
, 1),
6779 /* If that failed, then give up. */
6787 insn
= get_insns ();
6792 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6793 or unsigned operation code. */
6795 static enum rtx_code
6796 get_rtx_code (enum tree_code tcode
, bool unsignedp
)
6808 code
= unsignedp
? LTU
: LT
;
6811 code
= unsignedp
? LEU
: LE
;
6814 code
= unsignedp
? GTU
: GT
;
6817 code
= unsignedp
? GEU
: GE
;
6820 case UNORDERED_EXPR
:
6851 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6852 unsigned operators. Do not generate compare instruction. */
6855 vector_compare_rtx (tree cond
, bool unsignedp
, enum insn_code icode
)
6857 enum rtx_code rcode
;
6859 rtx rtx_op0
, rtx_op1
;
6861 /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
6862 ensures that condition is a relational operation. */
6863 gcc_assert (COMPARISON_CLASS_P (cond
));
6865 rcode
= get_rtx_code (TREE_CODE (cond
), unsignedp
);
6866 t_op0
= TREE_OPERAND (cond
, 0);
6867 t_op1
= TREE_OPERAND (cond
, 1);
6869 /* Expand operands. */
6870 rtx_op0
= expand_expr (t_op0
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op0
)),
6872 rtx_op1
= expand_expr (t_op1
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op1
)),
6875 if (!insn_data
[icode
].operand
[4].predicate (rtx_op0
, GET_MODE (rtx_op0
))
6876 && GET_MODE (rtx_op0
) != VOIDmode
)
6877 rtx_op0
= force_reg (GET_MODE (rtx_op0
), rtx_op0
);
6879 if (!insn_data
[icode
].operand
[5].predicate (rtx_op1
, GET_MODE (rtx_op1
))
6880 && GET_MODE (rtx_op1
) != VOIDmode
)
6881 rtx_op1
= force_reg (GET_MODE (rtx_op1
), rtx_op1
);
6883 return gen_rtx_fmt_ee (rcode
, VOIDmode
, rtx_op0
, rtx_op1
);
6886 /* Return insn code for TYPE, the type of a VEC_COND_EXPR. */
6888 static inline enum insn_code
6889 get_vcond_icode (tree type
, enum machine_mode mode
)
6891 enum insn_code icode
= CODE_FOR_nothing
;
6893 if (TYPE_UNSIGNED (type
))
6894 icode
= vcondu_gen_code
[mode
];
6896 icode
= vcond_gen_code
[mode
];
6900 /* Return TRUE iff, appropriate vector insns are available
6901 for vector cond expr with type TYPE in VMODE mode. */
6904 expand_vec_cond_expr_p (tree type
, enum machine_mode vmode
)
6906 if (get_vcond_icode (type
, vmode
) == CODE_FOR_nothing
)
6911 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
6915 expand_vec_cond_expr (tree vec_cond_type
, tree op0
, tree op1
, tree op2
,
6918 enum insn_code icode
;
6919 rtx comparison
, rtx_op1
, rtx_op2
, cc_op0
, cc_op1
;
6920 enum machine_mode mode
= TYPE_MODE (vec_cond_type
);
6921 bool unsignedp
= TYPE_UNSIGNED (vec_cond_type
);
6923 icode
= get_vcond_icode (vec_cond_type
, mode
);
6924 if (icode
== CODE_FOR_nothing
)
6927 if (!target
|| !insn_data
[icode
].operand
[0].predicate (target
, mode
))
6928 target
= gen_reg_rtx (mode
);
6930 /* Get comparison rtx. First expand both cond expr operands. */
6931 comparison
= vector_compare_rtx (op0
,
6933 cc_op0
= XEXP (comparison
, 0);
6934 cc_op1
= XEXP (comparison
, 1);
6935 /* Expand both operands and force them in reg, if required. */
6936 rtx_op1
= expand_normal (op1
);
6937 if (!insn_data
[icode
].operand
[1].predicate (rtx_op1
, mode
)
6938 && mode
!= VOIDmode
)
6939 rtx_op1
= force_reg (mode
, rtx_op1
);
6941 rtx_op2
= expand_normal (op2
);
6942 if (!insn_data
[icode
].operand
[2].predicate (rtx_op2
, mode
)
6943 && mode
!= VOIDmode
)
6944 rtx_op2
= force_reg (mode
, rtx_op2
);
6946 /* Emit instruction! */
6947 emit_insn (GEN_FCN (icode
) (target
, rtx_op1
, rtx_op2
,
6948 comparison
, cc_op0
, cc_op1
));
6954 /* This is an internal subroutine of the other compare_and_swap expanders.
6955 MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
6956 operation. TARGET is an optional place to store the value result of
6957 the operation. ICODE is the particular instruction to expand. Return
6958 the result of the operation. */
6961 expand_val_compare_and_swap_1 (rtx mem
, rtx old_val
, rtx new_val
,
6962 rtx target
, enum insn_code icode
)
6964 enum machine_mode mode
= GET_MODE (mem
);
6967 if (!target
|| !insn_data
[icode
].operand
[0].predicate (target
, mode
))
6968 target
= gen_reg_rtx (mode
);
6970 if (GET_MODE (old_val
) != VOIDmode
&& GET_MODE (old_val
) != mode
)
6971 old_val
= convert_modes (mode
, GET_MODE (old_val
), old_val
, 1);
6972 if (!insn_data
[icode
].operand
[2].predicate (old_val
, mode
))
6973 old_val
= force_reg (mode
, old_val
);
6975 if (GET_MODE (new_val
) != VOIDmode
&& GET_MODE (new_val
) != mode
)
6976 new_val
= convert_modes (mode
, GET_MODE (new_val
), new_val
, 1);
6977 if (!insn_data
[icode
].operand
[3].predicate (new_val
, mode
))
6978 new_val
= force_reg (mode
, new_val
);
6980 insn
= GEN_FCN (icode
) (target
, mem
, old_val
, new_val
);
6981 if (insn
== NULL_RTX
)
6988 /* Expand a compare-and-swap operation and return its value. */
6991 expand_val_compare_and_swap (rtx mem
, rtx old_val
, rtx new_val
, rtx target
)
6993 enum machine_mode mode
= GET_MODE (mem
);
6994 enum insn_code icode
= sync_compare_and_swap
[mode
];
6996 if (icode
== CODE_FOR_nothing
)
6999 return expand_val_compare_and_swap_1 (mem
, old_val
, new_val
, target
, icode
);
7002 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
7006 find_cc_set (rtx x
, const_rtx pat
, void *data
)
7008 if (REG_P (x
) && GET_MODE_CLASS (GET_MODE (x
)) == MODE_CC
7009 && GET_CODE (pat
) == SET
)
7011 rtx
*p_cc_reg
= (rtx
*) data
;
7012 gcc_assert (!*p_cc_reg
);
7017 /* Expand a compare-and-swap operation and store true into the result if
7018 the operation was successful and false otherwise. Return the result.
7019 Unlike other routines, TARGET is not optional. */
7022 expand_bool_compare_and_swap (rtx mem
, rtx old_val
, rtx new_val
, rtx target
)
7024 enum machine_mode mode
= GET_MODE (mem
);
7025 enum insn_code icode
;
7026 rtx subtarget
, seq
, cc_reg
;
7028 /* If the target supports a compare-and-swap pattern that simultaneously
7029 sets some flag for success, then use it. Otherwise use the regular
7030 compare-and-swap and follow that immediately with a compare insn. */
7031 icode
= sync_compare_and_swap
[mode
];
7032 if (icode
== CODE_FOR_nothing
)
7038 subtarget
= expand_val_compare_and_swap_1 (mem
, old_val
, new_val
,
7041 if (subtarget
== NULL_RTX
)
7047 if (have_insn_for (COMPARE
, CCmode
))
7048 note_stores (PATTERN (get_last_insn ()), find_cc_set
, &cc_reg
);
7052 /* We might be comparing against an old value. Try again. :-( */
7053 if (!cc_reg
&& MEM_P (old_val
))
7056 old_val
= force_reg (mode
, old_val
);
7063 return emit_store_flag_force (target
, EQ
, cc_reg
, const0_rtx
, VOIDmode
, 0, 1);
7065 return emit_store_flag_force (target
, EQ
, subtarget
, old_val
, VOIDmode
, 1, 1);
7068 /* This is a helper function for the other atomic operations. This function
7069 emits a loop that contains SEQ that iterates until a compare-and-swap
7070 operation at the end succeeds. MEM is the memory to be modified. SEQ is
7071 a set of instructions that takes a value from OLD_REG as an input and
7072 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
7073 set to the current contents of MEM. After SEQ, a compare-and-swap will
7074 attempt to update MEM with NEW_REG. The function returns true when the
7075 loop was generated successfully. */
7078 expand_compare_and_swap_loop (rtx mem
, rtx old_reg
, rtx new_reg
, rtx seq
)
7080 enum machine_mode mode
= GET_MODE (mem
);
7081 enum insn_code icode
;
7082 rtx label
, cmp_reg
, subtarget
, cc_reg
;
7084 /* The loop we want to generate looks like
7090 cmp_reg = compare-and-swap(mem, old_reg, new_reg)
7091 if (cmp_reg != old_reg)
7094 Note that we only do the plain load from memory once. Subsequent
7095 iterations use the value loaded by the compare-and-swap pattern. */
7097 label
= gen_label_rtx ();
7098 cmp_reg
= gen_reg_rtx (mode
);
7100 emit_move_insn (cmp_reg
, mem
);
7102 emit_move_insn (old_reg
, cmp_reg
);
7106 /* If the target supports a compare-and-swap pattern that simultaneously
7107 sets some flag for success, then use it. Otherwise use the regular
7108 compare-and-swap and follow that immediately with a compare insn. */
7109 icode
= sync_compare_and_swap
[mode
];
7110 if (icode
== CODE_FOR_nothing
)
7113 subtarget
= expand_val_compare_and_swap_1 (mem
, old_reg
, new_reg
,
7115 if (subtarget
== NULL_RTX
)
7119 if (have_insn_for (COMPARE
, CCmode
))
7120 note_stores (PATTERN (get_last_insn ()), find_cc_set
, &cc_reg
);
7124 old_reg
= const0_rtx
;
7128 if (subtarget
!= cmp_reg
)
7129 emit_move_insn (cmp_reg
, subtarget
);
7132 /* ??? Mark this jump predicted not taken? */
7133 emit_cmp_and_jump_insns (cmp_reg
, old_reg
, NE
, const0_rtx
, GET_MODE (cmp_reg
), 1,
7138 /* This function generates the atomic operation MEM CODE= VAL. In this
7139 case, we do not care about any resulting value. Returns NULL if we
7140 cannot generate the operation. */
7143 expand_sync_operation (rtx mem
, rtx val
, enum rtx_code code
)
7145 enum machine_mode mode
= GET_MODE (mem
);
7146 enum insn_code icode
;
7149 /* Look to see if the target supports the operation directly. */
7153 icode
= sync_add_optab
[mode
];
7156 icode
= sync_ior_optab
[mode
];
7159 icode
= sync_xor_optab
[mode
];
7162 icode
= sync_and_optab
[mode
];
7165 icode
= sync_nand_optab
[mode
];
7169 icode
= sync_sub_optab
[mode
];
7170 if (icode
== CODE_FOR_nothing
|| CONST_INT_P (val
))
7172 icode
= sync_add_optab
[mode
];
7173 if (icode
!= CODE_FOR_nothing
)
7175 val
= expand_simple_unop (mode
, NEG
, val
, NULL_RTX
, 1);
7185 /* Generate the direct operation, if present. */
7186 if (icode
!= CODE_FOR_nothing
)
7188 if (GET_MODE (val
) != VOIDmode
&& GET_MODE (val
) != mode
)
7189 val
= convert_modes (mode
, GET_MODE (val
), val
, 1);
7190 if (!insn_data
[icode
].operand
[1].predicate (val
, mode
))
7191 val
= force_reg (mode
, val
);
7193 insn
= GEN_FCN (icode
) (mem
, val
);
7201 /* Failing that, generate a compare-and-swap loop in which we perform the
7202 operation with normal arithmetic instructions. */
7203 if (sync_compare_and_swap
[mode
] != CODE_FOR_nothing
)
7205 rtx t0
= gen_reg_rtx (mode
), t1
;
7212 t1
= expand_simple_binop (mode
, AND
, t1
, val
, NULL_RTX
,
7213 true, OPTAB_LIB_WIDEN
);
7214 t1
= expand_simple_unop (mode
, code
, t1
, NULL_RTX
, true);
7217 t1
= expand_simple_binop (mode
, code
, t1
, val
, NULL_RTX
,
7218 true, OPTAB_LIB_WIDEN
);
7219 insn
= get_insns ();
7222 if (t1
!= NULL
&& expand_compare_and_swap_loop (mem
, t0
, t1
, insn
))
7229 /* This function generates the atomic operation MEM CODE= VAL. In this
7230 case, we do care about the resulting value: if AFTER is true then
7231 return the value MEM holds after the operation, if AFTER is false
7232 then return the value MEM holds before the operation. TARGET is an
7233 optional place for the result value to be stored. */
7236 expand_sync_fetch_operation (rtx mem
, rtx val
, enum rtx_code code
,
7237 bool after
, rtx target
)
7239 enum machine_mode mode
= GET_MODE (mem
);
7240 enum insn_code old_code
, new_code
, icode
;
7244 /* Look to see if the target supports the operation directly. */
7248 old_code
= sync_old_add_optab
[mode
];
7249 new_code
= sync_new_add_optab
[mode
];
7252 old_code
= sync_old_ior_optab
[mode
];
7253 new_code
= sync_new_ior_optab
[mode
];
7256 old_code
= sync_old_xor_optab
[mode
];
7257 new_code
= sync_new_xor_optab
[mode
];
7260 old_code
= sync_old_and_optab
[mode
];
7261 new_code
= sync_new_and_optab
[mode
];
7264 old_code
= sync_old_nand_optab
[mode
];
7265 new_code
= sync_new_nand_optab
[mode
];
7269 old_code
= sync_old_sub_optab
[mode
];
7270 new_code
= sync_new_sub_optab
[mode
];
7271 if ((old_code
== CODE_FOR_nothing
&& new_code
== CODE_FOR_nothing
)
7272 || CONST_INT_P (val
))
7274 old_code
= sync_old_add_optab
[mode
];
7275 new_code
= sync_new_add_optab
[mode
];
7276 if (old_code
!= CODE_FOR_nothing
|| new_code
!= CODE_FOR_nothing
)
7278 val
= expand_simple_unop (mode
, NEG
, val
, NULL_RTX
, 1);
7288 /* If the target does supports the proper new/old operation, great. But
7289 if we only support the opposite old/new operation, check to see if we
7290 can compensate. In the case in which the old value is supported, then
7291 we can always perform the operation again with normal arithmetic. In
7292 the case in which the new value is supported, then we can only handle
7293 this in the case the operation is reversible. */
7298 if (icode
== CODE_FOR_nothing
)
7301 if (icode
!= CODE_FOR_nothing
)
7308 if (icode
== CODE_FOR_nothing
7309 && (code
== PLUS
|| code
== MINUS
|| code
== XOR
))
7312 if (icode
!= CODE_FOR_nothing
)
7317 /* If we found something supported, great. */
7318 if (icode
!= CODE_FOR_nothing
)
7320 if (!target
|| !insn_data
[icode
].operand
[0].predicate (target
, mode
))
7321 target
= gen_reg_rtx (mode
);
7323 if (GET_MODE (val
) != VOIDmode
&& GET_MODE (val
) != mode
)
7324 val
= convert_modes (mode
, GET_MODE (val
), val
, 1);
7325 if (!insn_data
[icode
].operand
[2].predicate (val
, mode
))
7326 val
= force_reg (mode
, val
);
7328 insn
= GEN_FCN (icode
) (target
, mem
, val
);
7333 /* If we need to compensate for using an operation with the
7334 wrong return value, do so now. */
7341 else if (code
== MINUS
)
7347 target
= expand_simple_binop (mode
, AND
, target
, val
,
7350 target
= expand_simple_unop (mode
, code
, target
,
7354 target
= expand_simple_binop (mode
, code
, target
, val
,
7363 /* Failing that, generate a compare-and-swap loop in which we perform the
7364 operation with normal arithmetic instructions. */
7365 if (sync_compare_and_swap
[mode
] != CODE_FOR_nothing
)
7367 rtx t0
= gen_reg_rtx (mode
), t1
;
7369 if (!target
|| !register_operand (target
, mode
))
7370 target
= gen_reg_rtx (mode
);
7375 emit_move_insn (target
, t0
);
7379 t1
= expand_simple_binop (mode
, AND
, t1
, val
, NULL_RTX
,
7380 true, OPTAB_LIB_WIDEN
);
7381 t1
= expand_simple_unop (mode
, code
, t1
, NULL_RTX
, true);
7384 t1
= expand_simple_binop (mode
, code
, t1
, val
, NULL_RTX
,
7385 true, OPTAB_LIB_WIDEN
);
7387 emit_move_insn (target
, t1
);
7389 insn
= get_insns ();
7392 if (t1
!= NULL
&& expand_compare_and_swap_loop (mem
, t0
, t1
, insn
))
7399 /* This function expands a test-and-set operation. Ideally we atomically
7400 store VAL in MEM and return the previous value in MEM. Some targets
7401 may not support this operation and only support VAL with the constant 1;
7402 in this case while the return value will be 0/1, but the exact value
7403 stored in MEM is target defined. TARGET is an option place to stick
7404 the return value. */
7407 expand_sync_lock_test_and_set (rtx mem
, rtx val
, rtx target
)
7409 enum machine_mode mode
= GET_MODE (mem
);
7410 enum insn_code icode
;
7413 /* If the target supports the test-and-set directly, great. */
7414 icode
= sync_lock_test_and_set
[mode
];
7415 if (icode
!= CODE_FOR_nothing
)
7417 if (!target
|| !insn_data
[icode
].operand
[0].predicate (target
, mode
))
7418 target
= gen_reg_rtx (mode
);
7420 if (GET_MODE (val
) != VOIDmode
&& GET_MODE (val
) != mode
)
7421 val
= convert_modes (mode
, GET_MODE (val
), val
, 1);
7422 if (!insn_data
[icode
].operand
[2].predicate (val
, mode
))
7423 val
= force_reg (mode
, val
);
7425 insn
= GEN_FCN (icode
) (target
, mem
, val
);
7433 /* Otherwise, use a compare-and-swap loop for the exchange. */
7434 if (sync_compare_and_swap
[mode
] != CODE_FOR_nothing
)
7436 if (!target
|| !register_operand (target
, mode
))
7437 target
= gen_reg_rtx (mode
);
7438 if (GET_MODE (val
) != VOIDmode
&& GET_MODE (val
) != mode
)
7439 val
= convert_modes (mode
, GET_MODE (val
), val
, 1);
7440 if (expand_compare_and_swap_loop (mem
, target
, val
, NULL_RTX
))
7447 #include "gt-optabs.h"