1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2013 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
25 #include "diagnostic-core.h"
27 /* Include insn-config.h before expr.h so that HAVE_conditional_move
28 is properly defined. */
29 #include "insn-config.h"
42 #include "basic-block.h"
45 struct target_optabs default_target_optabs
;
46 struct target_libfuncs default_target_libfuncs
;
48 struct target_optabs
*this_target_optabs
= &default_target_optabs
;
49 struct target_libfuncs
*this_target_libfuncs
= &default_target_libfuncs
;
52 #define libfunc_hash \
53 (this_target_libfuncs->x_libfunc_hash)
55 static void prepare_float_lib_cmp (rtx
, rtx
, enum rtx_code
, rtx
*,
57 static rtx
expand_unop_direct (enum machine_mode
, optab
, rtx
, rtx
, int);
58 static void emit_libcall_block_1 (rtx
, rtx
, rtx
, rtx
, bool);
60 /* Debug facility for use in GDB. */
61 void debug_optab_libfuncs (void);
63 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
64 #if ENABLE_DECIMAL_BID_FORMAT
65 #define DECIMAL_PREFIX "bid_"
67 #define DECIMAL_PREFIX "dpd_"
70 /* Used for libfunc_hash. */
73 hash_libfunc (const void *p
)
75 const struct libfunc_entry
*const e
= (const struct libfunc_entry
*) p
;
76 return ((e
->mode1
+ e
->mode2
* NUM_MACHINE_MODES
) ^ e
->op
);
79 /* Used for libfunc_hash. */
82 eq_libfunc (const void *p
, const void *q
)
84 const struct libfunc_entry
*const e1
= (const struct libfunc_entry
*) p
;
85 const struct libfunc_entry
*const e2
= (const struct libfunc_entry
*) q
;
86 return e1
->op
== e2
->op
&& e1
->mode1
== e2
->mode1
&& e1
->mode2
== e2
->mode2
;
89 /* Return libfunc corresponding operation defined by OPTAB converting
90 from MODE2 to MODE1. Trigger lazy initialization if needed, return NULL
91 if no libfunc is available. */
93 convert_optab_libfunc (convert_optab optab
, enum machine_mode mode1
,
94 enum machine_mode mode2
)
96 struct libfunc_entry e
;
97 struct libfunc_entry
**slot
;
99 /* ??? This ought to be an assert, but not all of the places
100 that we expand optabs know about the optabs that got moved
102 if (!(optab
>= FIRST_CONV_OPTAB
&& optab
<= LAST_CONVLIB_OPTAB
))
108 slot
= (struct libfunc_entry
**)
109 htab_find_slot (libfunc_hash
, &e
, NO_INSERT
);
112 const struct convert_optab_libcall_d
*d
113 = &convlib_def
[optab
- FIRST_CONV_OPTAB
];
115 if (d
->libcall_gen
== NULL
)
118 d
->libcall_gen (optab
, d
->libcall_basename
, mode1
, mode2
);
119 slot
= (struct libfunc_entry
**)
120 htab_find_slot (libfunc_hash
, &e
, NO_INSERT
);
124 return (*slot
)->libfunc
;
127 /* Return libfunc corresponding operation defined by OPTAB in MODE.
128 Trigger lazy initialization if needed, return NULL if no libfunc is
131 optab_libfunc (optab optab
, enum machine_mode mode
)
133 struct libfunc_entry e
;
134 struct libfunc_entry
**slot
;
136 /* ??? This ought to be an assert, but not all of the places
137 that we expand optabs know about the optabs that got moved
139 if (!(optab
>= FIRST_NORM_OPTAB
&& optab
<= LAST_NORMLIB_OPTAB
))
145 slot
= (struct libfunc_entry
**)
146 htab_find_slot (libfunc_hash
, &e
, NO_INSERT
);
149 const struct optab_libcall_d
*d
150 = &normlib_def
[optab
- FIRST_NORM_OPTAB
];
152 if (d
->libcall_gen
== NULL
)
155 d
->libcall_gen (optab
, d
->libcall_basename
, d
->libcall_suffix
, mode
);
156 slot
= (struct libfunc_entry
**)
157 htab_find_slot (libfunc_hash
, &e
, NO_INSERT
);
161 return (*slot
)->libfunc
;
165 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
166 the result of operation CODE applied to OP0 (and OP1 if it is a binary
169 If the last insn does not set TARGET, don't do anything, but return 1.
171 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
172 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
173 try again, ensuring that TARGET is not one of the operands. */
176 add_equal_note (rtx insns
, rtx target
, enum rtx_code code
, rtx op0
, rtx op1
)
181 gcc_assert (insns
&& INSN_P (insns
) && NEXT_INSN (insns
));
183 if (GET_RTX_CLASS (code
) != RTX_COMM_ARITH
184 && GET_RTX_CLASS (code
) != RTX_BIN_ARITH
185 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
186 && GET_RTX_CLASS (code
) != RTX_COMPARE
187 && GET_RTX_CLASS (code
) != RTX_UNARY
)
190 if (GET_CODE (target
) == ZERO_EXTRACT
)
193 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
194 a value changing in the insn, so the note would be invalid for CSE. */
195 if (reg_overlap_mentioned_p (target
, op0
)
196 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
199 for (last_insn
= insns
;
200 NEXT_INSN (last_insn
) != NULL_RTX
;
201 last_insn
= NEXT_INSN (last_insn
))
204 set
= single_set (last_insn
);
208 if (! rtx_equal_p (SET_DEST (set
), target
)
209 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
210 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
211 || ! rtx_equal_p (XEXP (SET_DEST (set
), 0), target
)))
214 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
224 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (target
) != GET_MODE (op0
))
226 note
= gen_rtx_fmt_e (code
, GET_MODE (op0
), copy_rtx (op0
));
227 if (GET_MODE_SIZE (GET_MODE (op0
))
228 > GET_MODE_SIZE (GET_MODE (target
)))
229 note
= simplify_gen_unary (TRUNCATE
, GET_MODE (target
),
230 note
, GET_MODE (op0
));
232 note
= simplify_gen_unary (ZERO_EXTEND
, GET_MODE (target
),
233 note
, GET_MODE (op0
));
238 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
242 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
244 set_unique_reg_note (last_insn
, REG_EQUAL
, note
);
249 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
250 for a widening operation would be. In most cases this would be OP0, but if
251 that's a constant it'll be VOIDmode, which isn't useful. */
253 static enum machine_mode
254 widened_mode (enum machine_mode to_mode
, rtx op0
, rtx op1
)
256 enum machine_mode m0
= GET_MODE (op0
);
257 enum machine_mode m1
= GET_MODE (op1
);
258 enum machine_mode result
;
260 if (m0
== VOIDmode
&& m1
== VOIDmode
)
262 else if (m0
== VOIDmode
|| GET_MODE_SIZE (m0
) < GET_MODE_SIZE (m1
))
267 if (GET_MODE_SIZE (result
) > GET_MODE_SIZE (to_mode
))
273 /* Find a widening optab even if it doesn't widen as much as we want.
274 E.g. if from_mode is HImode, and to_mode is DImode, and there is no
275 direct HI->SI insn, then return SI->DI, if that exists.
276 If PERMIT_NON_WIDENING is non-zero then this can be used with
277 non-widening optabs also. */
280 find_widening_optab_handler_and_mode (optab op
, enum machine_mode to_mode
,
281 enum machine_mode from_mode
,
282 int permit_non_widening
,
283 enum machine_mode
*found_mode
)
285 for (; (permit_non_widening
|| from_mode
!= to_mode
)
286 && GET_MODE_SIZE (from_mode
) <= GET_MODE_SIZE (to_mode
)
287 && from_mode
!= VOIDmode
;
288 from_mode
= GET_MODE_WIDER_MODE (from_mode
))
290 enum insn_code handler
= widening_optab_handler (op
, to_mode
,
293 if (handler
!= CODE_FOR_nothing
)
296 *found_mode
= from_mode
;
301 return CODE_FOR_nothing
;
304 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
305 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
306 not actually do a sign-extend or zero-extend, but can leave the
307 higher-order bits of the result rtx undefined, for example, in the case
308 of logical operations, but not right shifts. */
311 widen_operand (rtx op
, enum machine_mode mode
, enum machine_mode oldmode
,
312 int unsignedp
, int no_extend
)
316 /* If we don't have to extend and this is a constant, return it. */
317 if (no_extend
&& GET_MODE (op
) == VOIDmode
)
320 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
321 extend since it will be more efficient to do so unless the signedness of
322 a promoted object differs from our extension. */
324 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)
325 && SUBREG_PROMOTED_UNSIGNED_P (op
) == unsignedp
))
326 return convert_modes (mode
, oldmode
, op
, unsignedp
);
328 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
330 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
331 return gen_lowpart (mode
, force_reg (GET_MODE (op
), op
));
333 /* Otherwise, get an object of MODE, clobber it, and set the low-order
336 result
= gen_reg_rtx (mode
);
337 emit_clobber (result
);
338 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
342 /* Return the optab used for computing the operation given by the tree code,
343 CODE and the tree EXP. This function is not always usable (for example, it
344 cannot give complete results for multiplication or division) but probably
345 ought to be relied on more widely throughout the expander. */
347 optab_for_tree_code (enum tree_code code
, const_tree type
,
348 enum optab_subtype subtype
)
360 return one_cmpl_optab
;
365 case MULT_HIGHPART_EXPR
:
366 return TYPE_UNSIGNED (type
) ? umul_highpart_optab
: smul_highpart_optab
;
372 return TYPE_UNSIGNED (type
) ? umod_optab
: smod_optab
;
380 if (TYPE_SATURATING(type
))
381 return TYPE_UNSIGNED(type
) ? usdiv_optab
: ssdiv_optab
;
382 return TYPE_UNSIGNED (type
) ? udiv_optab
: sdiv_optab
;
385 if (TREE_CODE (type
) == VECTOR_TYPE
)
387 if (subtype
== optab_vector
)
388 return TYPE_SATURATING (type
) ? unknown_optab
: vashl_optab
;
390 gcc_assert (subtype
== optab_scalar
);
392 if (TYPE_SATURATING(type
))
393 return TYPE_UNSIGNED(type
) ? usashl_optab
: ssashl_optab
;
397 if (TREE_CODE (type
) == VECTOR_TYPE
)
399 if (subtype
== optab_vector
)
400 return TYPE_UNSIGNED (type
) ? vlshr_optab
: vashr_optab
;
402 gcc_assert (subtype
== optab_scalar
);
404 return TYPE_UNSIGNED (type
) ? lshr_optab
: ashr_optab
;
407 if (TREE_CODE (type
) == VECTOR_TYPE
)
409 if (subtype
== optab_vector
)
412 gcc_assert (subtype
== optab_scalar
);
417 if (TREE_CODE (type
) == VECTOR_TYPE
)
419 if (subtype
== optab_vector
)
422 gcc_assert (subtype
== optab_scalar
);
427 return TYPE_UNSIGNED (type
) ? umax_optab
: smax_optab
;
430 return TYPE_UNSIGNED (type
) ? umin_optab
: smin_optab
;
432 case REALIGN_LOAD_EXPR
:
433 return vec_realign_load_optab
;
436 return TYPE_UNSIGNED (type
) ? usum_widen_optab
: ssum_widen_optab
;
439 return TYPE_UNSIGNED (type
) ? udot_prod_optab
: sdot_prod_optab
;
441 case WIDEN_MULT_PLUS_EXPR
:
442 return (TYPE_UNSIGNED (type
)
443 ? (TYPE_SATURATING (type
)
444 ? usmadd_widen_optab
: umadd_widen_optab
)
445 : (TYPE_SATURATING (type
)
446 ? ssmadd_widen_optab
: smadd_widen_optab
));
448 case WIDEN_MULT_MINUS_EXPR
:
449 return (TYPE_UNSIGNED (type
)
450 ? (TYPE_SATURATING (type
)
451 ? usmsub_widen_optab
: umsub_widen_optab
)
452 : (TYPE_SATURATING (type
)
453 ? ssmsub_widen_optab
: smsub_widen_optab
));
459 return TYPE_UNSIGNED (type
) ? reduc_umax_optab
: reduc_smax_optab
;
462 return TYPE_UNSIGNED (type
) ? reduc_umin_optab
: reduc_smin_optab
;
464 case REDUC_PLUS_EXPR
:
465 return TYPE_UNSIGNED (type
) ? reduc_uplus_optab
: reduc_splus_optab
;
467 case VEC_LSHIFT_EXPR
:
468 return vec_shl_optab
;
470 case VEC_RSHIFT_EXPR
:
471 return vec_shr_optab
;
473 case VEC_WIDEN_MULT_HI_EXPR
:
474 return TYPE_UNSIGNED (type
) ?
475 vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
477 case VEC_WIDEN_MULT_LO_EXPR
:
478 return TYPE_UNSIGNED (type
) ?
479 vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
481 case VEC_WIDEN_MULT_EVEN_EXPR
:
482 return TYPE_UNSIGNED (type
) ?
483 vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
485 case VEC_WIDEN_MULT_ODD_EXPR
:
486 return TYPE_UNSIGNED (type
) ?
487 vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
489 case VEC_WIDEN_LSHIFT_HI_EXPR
:
490 return TYPE_UNSIGNED (type
) ?
491 vec_widen_ushiftl_hi_optab
: vec_widen_sshiftl_hi_optab
;
493 case VEC_WIDEN_LSHIFT_LO_EXPR
:
494 return TYPE_UNSIGNED (type
) ?
495 vec_widen_ushiftl_lo_optab
: vec_widen_sshiftl_lo_optab
;
497 case VEC_UNPACK_HI_EXPR
:
498 return TYPE_UNSIGNED (type
) ?
499 vec_unpacku_hi_optab
: vec_unpacks_hi_optab
;
501 case VEC_UNPACK_LO_EXPR
:
502 return TYPE_UNSIGNED (type
) ?
503 vec_unpacku_lo_optab
: vec_unpacks_lo_optab
;
505 case VEC_UNPACK_FLOAT_HI_EXPR
:
506 /* The signedness is determined from input operand. */
507 return TYPE_UNSIGNED (type
) ?
508 vec_unpacku_float_hi_optab
: vec_unpacks_float_hi_optab
;
510 case VEC_UNPACK_FLOAT_LO_EXPR
:
511 /* The signedness is determined from input operand. */
512 return TYPE_UNSIGNED (type
) ?
513 vec_unpacku_float_lo_optab
: vec_unpacks_float_lo_optab
;
515 case VEC_PACK_TRUNC_EXPR
:
516 return vec_pack_trunc_optab
;
518 case VEC_PACK_SAT_EXPR
:
519 return TYPE_UNSIGNED (type
) ? vec_pack_usat_optab
: vec_pack_ssat_optab
;
521 case VEC_PACK_FIX_TRUNC_EXPR
:
522 /* The signedness is determined from output operand. */
523 return TYPE_UNSIGNED (type
) ?
524 vec_pack_ufix_trunc_optab
: vec_pack_sfix_trunc_optab
;
530 trapv
= INTEGRAL_TYPE_P (type
) && TYPE_OVERFLOW_TRAPS (type
);
533 case POINTER_PLUS_EXPR
:
535 if (TYPE_SATURATING(type
))
536 return TYPE_UNSIGNED(type
) ? usadd_optab
: ssadd_optab
;
537 return trapv
? addv_optab
: add_optab
;
540 if (TYPE_SATURATING(type
))
541 return TYPE_UNSIGNED(type
) ? ussub_optab
: sssub_optab
;
542 return trapv
? subv_optab
: sub_optab
;
545 if (TYPE_SATURATING(type
))
546 return TYPE_UNSIGNED(type
) ? usmul_optab
: ssmul_optab
;
547 return trapv
? smulv_optab
: smul_optab
;
550 if (TYPE_SATURATING(type
))
551 return TYPE_UNSIGNED(type
) ? usneg_optab
: ssneg_optab
;
552 return trapv
? negv_optab
: neg_optab
;
555 return trapv
? absv_optab
: abs_optab
;
558 return unknown_optab
;
563 /* Expand vector widening operations.
565 There are two different classes of operations handled here:
566 1) Operations whose result is wider than all the arguments to the operation.
567 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
568 In this case OP0 and optionally OP1 would be initialized,
569 but WIDE_OP wouldn't (not relevant for this case).
570 2) Operations whose result is of the same size as the last argument to the
571 operation, but wider than all the other arguments to the operation.
572 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
573 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
575 E.g, when called to expand the following operations, this is how
576 the arguments will be initialized:
578 widening-sum 2 oprnd0 - oprnd1
579 widening-dot-product 3 oprnd0 oprnd1 oprnd2
580 widening-mult 2 oprnd0 oprnd1 -
581 type-promotion (vec-unpack) 1 oprnd0 - - */
584 expand_widen_pattern_expr (sepops ops
, rtx op0
, rtx op1
, rtx wide_op
,
585 rtx target
, int unsignedp
)
587 struct expand_operand eops
[4];
588 tree oprnd0
, oprnd1
, oprnd2
;
589 enum machine_mode wmode
= VOIDmode
, tmode0
, tmode1
= VOIDmode
;
590 optab widen_pattern_optab
;
591 enum insn_code icode
;
592 int nops
= TREE_CODE_LENGTH (ops
->code
);
596 tmode0
= TYPE_MODE (TREE_TYPE (oprnd0
));
597 widen_pattern_optab
=
598 optab_for_tree_code (ops
->code
, TREE_TYPE (oprnd0
), optab_default
);
599 if (ops
->code
== WIDEN_MULT_PLUS_EXPR
600 || ops
->code
== WIDEN_MULT_MINUS_EXPR
)
601 icode
= find_widening_optab_handler (widen_pattern_optab
,
602 TYPE_MODE (TREE_TYPE (ops
->op2
)),
605 icode
= optab_handler (widen_pattern_optab
, tmode0
);
606 gcc_assert (icode
!= CODE_FOR_nothing
);
611 tmode1
= TYPE_MODE (TREE_TYPE (oprnd1
));
614 /* The last operand is of a wider mode than the rest of the operands. */
619 gcc_assert (tmode1
== tmode0
);
622 wmode
= TYPE_MODE (TREE_TYPE (oprnd2
));
626 create_output_operand (&eops
[op
++], target
, TYPE_MODE (ops
->type
));
627 create_convert_operand_from (&eops
[op
++], op0
, tmode0
, unsignedp
);
629 create_convert_operand_from (&eops
[op
++], op1
, tmode1
, unsignedp
);
631 create_convert_operand_from (&eops
[op
++], wide_op
, wmode
, unsignedp
);
632 expand_insn (icode
, op
, eops
);
633 return eops
[0].value
;
636 /* Generate code to perform an operation specified by TERNARY_OPTAB
637 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
639 UNSIGNEDP is for the case where we have to widen the operands
640 to perform the operation. It says to use zero-extension.
642 If TARGET is nonzero, the value
643 is generated there, if it is convenient to do so.
644 In all cases an rtx is returned for the locus of the value;
645 this may or may not be TARGET. */
648 expand_ternary_op (enum machine_mode mode
, optab ternary_optab
, rtx op0
,
649 rtx op1
, rtx op2
, rtx target
, int unsignedp
)
651 struct expand_operand ops
[4];
652 enum insn_code icode
= optab_handler (ternary_optab
, mode
);
654 gcc_assert (optab_handler (ternary_optab
, mode
) != CODE_FOR_nothing
);
656 create_output_operand (&ops
[0], target
, mode
);
657 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
658 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
659 create_convert_operand_from (&ops
[3], op2
, mode
, unsignedp
);
660 expand_insn (icode
, 4, ops
);
665 /* Like expand_binop, but return a constant rtx if the result can be
666 calculated at compile time. The arguments and return value are
667 otherwise the same as for expand_binop. */
670 simplify_expand_binop (enum machine_mode mode
, optab binoptab
,
671 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
672 enum optab_methods methods
)
674 if (CONSTANT_P (op0
) && CONSTANT_P (op1
))
676 rtx x
= simplify_binary_operation (optab_to_code (binoptab
),
682 return expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
);
685 /* Like simplify_expand_binop, but always put the result in TARGET.
686 Return true if the expansion succeeded. */
689 force_expand_binop (enum machine_mode mode
, optab binoptab
,
690 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
691 enum optab_methods methods
)
693 rtx x
= simplify_expand_binop (mode
, binoptab
, op0
, op1
,
694 target
, unsignedp
, methods
);
698 emit_move_insn (target
, x
);
702 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */
705 expand_vec_shift_expr (sepops ops
, rtx target
)
707 struct expand_operand eops
[3];
708 enum insn_code icode
;
709 rtx rtx_op1
, rtx_op2
;
710 enum machine_mode mode
= TYPE_MODE (ops
->type
);
711 tree vec_oprnd
= ops
->op0
;
712 tree shift_oprnd
= ops
->op1
;
717 case VEC_RSHIFT_EXPR
:
718 shift_optab
= vec_shr_optab
;
720 case VEC_LSHIFT_EXPR
:
721 shift_optab
= vec_shl_optab
;
727 icode
= optab_handler (shift_optab
, mode
);
728 gcc_assert (icode
!= CODE_FOR_nothing
);
730 rtx_op1
= expand_normal (vec_oprnd
);
731 rtx_op2
= expand_normal (shift_oprnd
);
733 create_output_operand (&eops
[0], target
, mode
);
734 create_input_operand (&eops
[1], rtx_op1
, GET_MODE (rtx_op1
));
735 create_convert_operand_from_type (&eops
[2], rtx_op2
, TREE_TYPE (shift_oprnd
));
736 expand_insn (icode
, 3, eops
);
738 return eops
[0].value
;
741 /* Create a new vector value in VMODE with all elements set to OP. The
742 mode of OP must be the element mode of VMODE. If OP is a constant,
743 then the return value will be a constant. */
746 expand_vector_broadcast (enum machine_mode vmode
, rtx op
)
748 enum insn_code icode
;
753 gcc_checking_assert (VECTOR_MODE_P (vmode
));
755 n
= GET_MODE_NUNITS (vmode
);
756 vec
= rtvec_alloc (n
);
757 for (i
= 0; i
< n
; ++i
)
758 RTVEC_ELT (vec
, i
) = op
;
761 return gen_rtx_CONST_VECTOR (vmode
, vec
);
763 /* ??? If the target doesn't have a vec_init, then we have no easy way
764 of performing this operation. Most of this sort of generic support
765 is hidden away in the vector lowering support in gimple. */
766 icode
= optab_handler (vec_init_optab
, vmode
);
767 if (icode
== CODE_FOR_nothing
)
770 ret
= gen_reg_rtx (vmode
);
771 emit_insn (GEN_FCN (icode
) (ret
, gen_rtx_PARALLEL (vmode
, vec
)));
776 /* This subroutine of expand_doubleword_shift handles the cases in which
777 the effective shift value is >= BITS_PER_WORD. The arguments and return
778 value are the same as for the parent routine, except that SUPERWORD_OP1
779 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
780 INTO_TARGET may be null if the caller has decided to calculate it. */
783 expand_superword_shift (optab binoptab
, rtx outof_input
, rtx superword_op1
,
784 rtx outof_target
, rtx into_target
,
785 int unsignedp
, enum optab_methods methods
)
787 if (into_target
!= 0)
788 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, superword_op1
,
789 into_target
, unsignedp
, methods
))
792 if (outof_target
!= 0)
794 /* For a signed right shift, we must fill OUTOF_TARGET with copies
795 of the sign bit, otherwise we must fill it with zeros. */
796 if (binoptab
!= ashr_optab
)
797 emit_move_insn (outof_target
, CONST0_RTX (word_mode
));
799 if (!force_expand_binop (word_mode
, binoptab
,
800 outof_input
, GEN_INT (BITS_PER_WORD
- 1),
801 outof_target
, unsignedp
, methods
))
807 /* This subroutine of expand_doubleword_shift handles the cases in which
808 the effective shift value is < BITS_PER_WORD. The arguments and return
809 value are the same as for the parent routine. */
812 expand_subword_shift (enum machine_mode op1_mode
, optab binoptab
,
813 rtx outof_input
, rtx into_input
, rtx op1
,
814 rtx outof_target
, rtx into_target
,
815 int unsignedp
, enum optab_methods methods
,
816 unsigned HOST_WIDE_INT shift_mask
)
818 optab reverse_unsigned_shift
, unsigned_shift
;
821 reverse_unsigned_shift
= (binoptab
== ashl_optab
? lshr_optab
: ashl_optab
);
822 unsigned_shift
= (binoptab
== ashl_optab
? ashl_optab
: lshr_optab
);
824 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
825 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
826 the opposite direction to BINOPTAB. */
827 if (CONSTANT_P (op1
) || shift_mask
>= BITS_PER_WORD
)
829 carries
= outof_input
;
830 tmp
= immed_double_const (BITS_PER_WORD
, 0, op1_mode
);
831 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
836 /* We must avoid shifting by BITS_PER_WORD bits since that is either
837 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
838 has unknown behavior. Do a single shift first, then shift by the
839 remainder. It's OK to use ~OP1 as the remainder if shift counts
840 are truncated to the mode size. */
841 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
842 outof_input
, const1_rtx
, 0, unsignedp
, methods
);
843 if (shift_mask
== BITS_PER_WORD
- 1)
845 tmp
= immed_double_const (-1, -1, op1_mode
);
846 tmp
= simplify_expand_binop (op1_mode
, xor_optab
, op1
, tmp
,
851 tmp
= immed_double_const (BITS_PER_WORD
- 1, 0, op1_mode
);
852 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
856 if (tmp
== 0 || carries
== 0)
858 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
859 carries
, tmp
, 0, unsignedp
, methods
);
863 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
864 so the result can go directly into INTO_TARGET if convenient. */
865 tmp
= expand_binop (word_mode
, unsigned_shift
, into_input
, op1
,
866 into_target
, unsignedp
, methods
);
870 /* Now OR in the bits carried over from OUTOF_INPUT. */
871 if (!force_expand_binop (word_mode
, ior_optab
, tmp
, carries
,
872 into_target
, unsignedp
, methods
))
875 /* Use a standard word_mode shift for the out-of half. */
876 if (outof_target
!= 0)
877 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
878 outof_target
, unsignedp
, methods
))
885 #ifdef HAVE_conditional_move
886 /* Try implementing expand_doubleword_shift using conditional moves.
887 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
888 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
889 are the shift counts to use in the former and latter case. All other
890 arguments are the same as the parent routine. */
893 expand_doubleword_shift_condmove (enum machine_mode op1_mode
, optab binoptab
,
894 enum rtx_code cmp_code
, rtx cmp1
, rtx cmp2
,
895 rtx outof_input
, rtx into_input
,
896 rtx subword_op1
, rtx superword_op1
,
897 rtx outof_target
, rtx into_target
,
898 int unsignedp
, enum optab_methods methods
,
899 unsigned HOST_WIDE_INT shift_mask
)
901 rtx outof_superword
, into_superword
;
903 /* Put the superword version of the output into OUTOF_SUPERWORD and
905 outof_superword
= outof_target
!= 0 ? gen_reg_rtx (word_mode
) : 0;
906 if (outof_target
!= 0 && subword_op1
== superword_op1
)
908 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
909 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
910 into_superword
= outof_target
;
911 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
912 outof_superword
, 0, unsignedp
, methods
))
917 into_superword
= gen_reg_rtx (word_mode
);
918 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
919 outof_superword
, into_superword
,
924 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
925 if (!expand_subword_shift (op1_mode
, binoptab
,
926 outof_input
, into_input
, subword_op1
,
927 outof_target
, into_target
,
928 unsignedp
, methods
, shift_mask
))
931 /* Select between them. Do the INTO half first because INTO_SUPERWORD
932 might be the current value of OUTOF_TARGET. */
933 if (!emit_conditional_move (into_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
934 into_target
, into_superword
, word_mode
, false))
937 if (outof_target
!= 0)
938 if (!emit_conditional_move (outof_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
939 outof_target
, outof_superword
,
947 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
948 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
949 input operand; the shift moves bits in the direction OUTOF_INPUT->
950 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
951 of the target. OP1 is the shift count and OP1_MODE is its mode.
952 If OP1 is constant, it will have been truncated as appropriate
953 and is known to be nonzero.
955 If SHIFT_MASK is zero, the result of word shifts is undefined when the
956 shift count is outside the range [0, BITS_PER_WORD). This routine must
957 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
959 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
960 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
961 fill with zeros or sign bits as appropriate.
963 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
964 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
965 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
966 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
969 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
970 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
971 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
972 function wants to calculate it itself.
974 Return true if the shift could be successfully synthesized. */
977 expand_doubleword_shift (enum machine_mode op1_mode
, optab binoptab
,
978 rtx outof_input
, rtx into_input
, rtx op1
,
979 rtx outof_target
, rtx into_target
,
980 int unsignedp
, enum optab_methods methods
,
981 unsigned HOST_WIDE_INT shift_mask
)
983 rtx superword_op1
, tmp
, cmp1
, cmp2
;
984 rtx subword_label
, done_label
;
985 enum rtx_code cmp_code
;
987 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
988 fill the result with sign or zero bits as appropriate. If so, the value
989 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
990 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
991 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
993 This isn't worthwhile for constant shifts since the optimizers will
994 cope better with in-range shift counts. */
995 if (shift_mask
>= BITS_PER_WORD
997 && !CONSTANT_P (op1
))
999 if (!expand_doubleword_shift (op1_mode
, binoptab
,
1000 outof_input
, into_input
, op1
,
1002 unsignedp
, methods
, shift_mask
))
1004 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
1005 outof_target
, unsignedp
, methods
))
1010 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
1011 is true when the effective shift value is less than BITS_PER_WORD.
1012 Set SUPERWORD_OP1 to the shift count that should be used to shift
1013 OUTOF_INPUT into INTO_TARGET when the condition is false. */
1014 tmp
= immed_double_const (BITS_PER_WORD
, 0, op1_mode
);
1015 if (!CONSTANT_P (op1
) && shift_mask
== BITS_PER_WORD
- 1)
1017 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
1018 is a subword shift count. */
1019 cmp1
= simplify_expand_binop (op1_mode
, and_optab
, op1
, tmp
,
1021 cmp2
= CONST0_RTX (op1_mode
);
1023 superword_op1
= op1
;
1027 /* Set CMP1 to OP1 - BITS_PER_WORD. */
1028 cmp1
= simplify_expand_binop (op1_mode
, sub_optab
, op1
, tmp
,
1030 cmp2
= CONST0_RTX (op1_mode
);
1032 superword_op1
= cmp1
;
1037 /* If we can compute the condition at compile time, pick the
1038 appropriate subroutine. */
1039 tmp
= simplify_relational_operation (cmp_code
, SImode
, op1_mode
, cmp1
, cmp2
);
1040 if (tmp
!= 0 && CONST_INT_P (tmp
))
1042 if (tmp
== const0_rtx
)
1043 return expand_superword_shift (binoptab
, outof_input
, superword_op1
,
1044 outof_target
, into_target
,
1045 unsignedp
, methods
);
1047 return expand_subword_shift (op1_mode
, binoptab
,
1048 outof_input
, into_input
, op1
,
1049 outof_target
, into_target
,
1050 unsignedp
, methods
, shift_mask
);
1053 #ifdef HAVE_conditional_move
1054 /* Try using conditional moves to generate straight-line code. */
1056 rtx start
= get_last_insn ();
1057 if (expand_doubleword_shift_condmove (op1_mode
, binoptab
,
1058 cmp_code
, cmp1
, cmp2
,
1059 outof_input
, into_input
,
1061 outof_target
, into_target
,
1062 unsignedp
, methods
, shift_mask
))
1064 delete_insns_since (start
);
1068 /* As a last resort, use branches to select the correct alternative. */
1069 subword_label
= gen_label_rtx ();
1070 done_label
= gen_label_rtx ();
1073 do_compare_rtx_and_jump (cmp1
, cmp2
, cmp_code
, false, op1_mode
,
1074 0, 0, subword_label
, -1);
1077 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
1078 outof_target
, into_target
,
1079 unsignedp
, methods
))
1082 emit_jump_insn (gen_jump (done_label
));
1084 emit_label (subword_label
);
1086 if (!expand_subword_shift (op1_mode
, binoptab
,
1087 outof_input
, into_input
, op1
,
1088 outof_target
, into_target
,
1089 unsignedp
, methods
, shift_mask
))
1092 emit_label (done_label
);
1096 /* Subroutine of expand_binop. Perform a double word multiplication of
1097 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1098 as the target's word_mode. This function return NULL_RTX if anything
1099 goes wrong, in which case it may have already emitted instructions
1100 which need to be deleted.
1102 If we want to multiply two two-word values and have normal and widening
1103 multiplies of single-word values, we can do this with three smaller
1106 The multiplication proceeds as follows:
1107 _______________________
1108 [__op0_high_|__op0_low__]
1109 _______________________
1110 * [__op1_high_|__op1_low__]
1111 _______________________________________________
1112 _______________________
1113 (1) [__op0_low__*__op1_low__]
1114 _______________________
1115 (2a) [__op0_low__*__op1_high_]
1116 _______________________
1117 (2b) [__op0_high_*__op1_low__]
1118 _______________________
1119 (3) [__op0_high_*__op1_high_]
1122 This gives a 4-word result. Since we are only interested in the
1123 lower 2 words, partial result (3) and the upper words of (2a) and
1124 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1125 calculated using non-widening multiplication.
1127 (1), however, needs to be calculated with an unsigned widening
1128 multiplication. If this operation is not directly supported we
1129 try using a signed widening multiplication and adjust the result.
1130 This adjustment works as follows:
1132 If both operands are positive then no adjustment is needed.
1134 If the operands have different signs, for example op0_low < 0 and
1135 op1_low >= 0, the instruction treats the most significant bit of
1136 op0_low as a sign bit instead of a bit with significance
1137 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1138 with 2**BITS_PER_WORD - op0_low, and two's complements the
1139 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1142 Similarly, if both operands are negative, we need to add
1143 (op0_low + op1_low) * 2**BITS_PER_WORD.
1145 We use a trick to adjust quickly. We logically shift op0_low right
1146 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1147 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1148 logical shift exists, we do an arithmetic right shift and subtract
1152 expand_doubleword_mult (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
1153 bool umulp
, enum optab_methods methods
)
1155 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1156 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1157 rtx wordm1
= umulp
? NULL_RTX
: GEN_INT (BITS_PER_WORD
- 1);
1158 rtx product
, adjust
, product_high
, temp
;
1160 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1161 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1162 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1163 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1165 /* If we're using an unsigned multiply to directly compute the product
1166 of the low-order words of the operands and perform any required
1167 adjustments of the operands, we begin by trying two more multiplications
1168 and then computing the appropriate sum.
1170 We have checked above that the required addition is provided.
1171 Full-word addition will normally always succeed, especially if
1172 it is provided at all, so we don't worry about its failure. The
1173 multiplication may well fail, however, so we do handle that. */
1177 /* ??? This could be done with emit_store_flag where available. */
1178 temp
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1179 NULL_RTX
, 1, methods
);
1181 op0_high
= expand_binop (word_mode
, add_optab
, op0_high
, temp
,
1182 NULL_RTX
, 0, OPTAB_DIRECT
);
1185 temp
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1186 NULL_RTX
, 0, methods
);
1189 op0_high
= expand_binop (word_mode
, sub_optab
, op0_high
, temp
,
1190 NULL_RTX
, 0, OPTAB_DIRECT
);
1197 adjust
= expand_binop (word_mode
, smul_optab
, op0_high
, op1_low
,
1198 NULL_RTX
, 0, OPTAB_DIRECT
);
1202 /* OP0_HIGH should now be dead. */
1206 /* ??? This could be done with emit_store_flag where available. */
1207 temp
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1208 NULL_RTX
, 1, methods
);
1210 op1_high
= expand_binop (word_mode
, add_optab
, op1_high
, temp
,
1211 NULL_RTX
, 0, OPTAB_DIRECT
);
1214 temp
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1215 NULL_RTX
, 0, methods
);
1218 op1_high
= expand_binop (word_mode
, sub_optab
, op1_high
, temp
,
1219 NULL_RTX
, 0, OPTAB_DIRECT
);
1226 temp
= expand_binop (word_mode
, smul_optab
, op1_high
, op0_low
,
1227 NULL_RTX
, 0, OPTAB_DIRECT
);
1231 /* OP1_HIGH should now be dead. */
1233 adjust
= expand_binop (word_mode
, add_optab
, adjust
, temp
,
1234 NULL_RTX
, 0, OPTAB_DIRECT
);
1236 if (target
&& !REG_P (target
))
1240 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1241 target
, 1, OPTAB_DIRECT
);
1243 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1244 target
, 1, OPTAB_DIRECT
);
1249 product_high
= operand_subword (product
, high
, 1, mode
);
1250 adjust
= expand_binop (word_mode
, add_optab
, product_high
, adjust
,
1251 NULL_RTX
, 0, OPTAB_DIRECT
);
1252 emit_move_insn (product_high
, adjust
);
1256 /* Wrapper around expand_binop which takes an rtx code to specify
1257 the operation to perform, not an optab pointer. All other
1258 arguments are the same. */
1260 expand_simple_binop (enum machine_mode mode
, enum rtx_code code
, rtx op0
,
1261 rtx op1
, rtx target
, int unsignedp
,
1262 enum optab_methods methods
)
1264 optab binop
= code_to_optab (code
);
1267 return expand_binop (mode
, binop
, op0
, op1
, target
, unsignedp
, methods
);
1270 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1271 binop. Order them according to commutative_operand_precedence and, if
1272 possible, try to put TARGET or a pseudo first. */
1274 swap_commutative_operands_with_target (rtx target
, rtx op0
, rtx op1
)
1276 int op0_prec
= commutative_operand_precedence (op0
);
1277 int op1_prec
= commutative_operand_precedence (op1
);
1279 if (op0_prec
< op1_prec
)
1282 if (op0_prec
> op1_prec
)
1285 /* With equal precedence, both orders are ok, but it is better if the
1286 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1287 if (target
== 0 || REG_P (target
))
1288 return (REG_P (op1
) && !REG_P (op0
)) || target
== op1
;
1290 return rtx_equal_p (op1
, target
);
1293 /* Return true if BINOPTAB implements a shift operation. */
1296 shift_optab_p (optab binoptab
)
1298 switch (optab_to_code (binoptab
))
1314 /* Return true if BINOPTAB implements a commutative binary operation. */
1317 commutative_optab_p (optab binoptab
)
1319 return (GET_RTX_CLASS (optab_to_code (binoptab
)) == RTX_COMM_ARITH
1320 || binoptab
== smul_widen_optab
1321 || binoptab
== umul_widen_optab
1322 || binoptab
== smul_highpart_optab
1323 || binoptab
== umul_highpart_optab
);
1326 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
1327 optimizing, and if the operand is a constant that costs more than
1328 1 instruction, force the constant into a register and return that
1329 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1332 avoid_expensive_constant (enum machine_mode mode
, optab binoptab
,
1333 int opn
, rtx x
, bool unsignedp
)
1335 bool speed
= optimize_insn_for_speed_p ();
1337 if (mode
!= VOIDmode
1340 && (rtx_cost (x
, optab_to_code (binoptab
), opn
, speed
)
1341 > set_src_cost (x
, speed
)))
1343 if (CONST_INT_P (x
))
1345 HOST_WIDE_INT intval
= trunc_int_for_mode (INTVAL (x
), mode
);
1346 if (intval
!= INTVAL (x
))
1347 x
= GEN_INT (intval
);
1350 x
= convert_modes (mode
, VOIDmode
, x
, unsignedp
);
1351 x
= force_reg (mode
, x
);
1356 /* Helper function for expand_binop: handle the case where there
1357 is an insn that directly implements the indicated operation.
1358 Returns null if this is not possible. */
1360 expand_binop_directly (enum machine_mode mode
, optab binoptab
,
1362 rtx target
, int unsignedp
, enum optab_methods methods
,
1365 enum machine_mode from_mode
= widened_mode (mode
, op0
, op1
);
1366 enum insn_code icode
= find_widening_optab_handler (binoptab
, mode
,
1368 enum machine_mode xmode0
= insn_data
[(int) icode
].operand
[1].mode
;
1369 enum machine_mode xmode1
= insn_data
[(int) icode
].operand
[2].mode
;
1370 enum machine_mode mode0
, mode1
, tmp_mode
;
1371 struct expand_operand ops
[3];
1374 rtx xop0
= op0
, xop1
= op1
;
1377 /* If it is a commutative operator and the modes would match
1378 if we would swap the operands, we can save the conversions. */
1379 commutative_p
= commutative_optab_p (binoptab
);
1381 && GET_MODE (xop0
) != xmode0
&& GET_MODE (xop1
) != xmode1
1382 && GET_MODE (xop0
) == xmode1
&& GET_MODE (xop1
) == xmode1
)
1389 /* If we are optimizing, force expensive constants into a register. */
1390 xop0
= avoid_expensive_constant (xmode0
, binoptab
, 0, xop0
, unsignedp
);
1391 if (!shift_optab_p (binoptab
))
1392 xop1
= avoid_expensive_constant (xmode1
, binoptab
, 1, xop1
, unsignedp
);
1394 /* In case the insn wants input operands in modes different from
1395 those of the actual operands, convert the operands. It would
1396 seem that we don't need to convert CONST_INTs, but we do, so
1397 that they're properly zero-extended, sign-extended or truncated
1400 mode0
= GET_MODE (xop0
) != VOIDmode
? GET_MODE (xop0
) : mode
;
1401 if (xmode0
!= VOIDmode
&& xmode0
!= mode0
)
1403 xop0
= convert_modes (xmode0
, mode0
, xop0
, unsignedp
);
1407 mode1
= GET_MODE (xop1
) != VOIDmode
? GET_MODE (xop1
) : mode
;
1408 if (xmode1
!= VOIDmode
&& xmode1
!= mode1
)
1410 xop1
= convert_modes (xmode1
, mode1
, xop1
, unsignedp
);
1414 /* If operation is commutative,
1415 try to make the first operand a register.
1416 Even better, try to make it the same as the target.
1417 Also try to make the last operand a constant. */
1419 && swap_commutative_operands_with_target (target
, xop0
, xop1
))
1426 /* Now, if insn's predicates don't allow our operands, put them into
1429 if (binoptab
== vec_pack_trunc_optab
1430 || binoptab
== vec_pack_usat_optab
1431 || binoptab
== vec_pack_ssat_optab
1432 || binoptab
== vec_pack_ufix_trunc_optab
1433 || binoptab
== vec_pack_sfix_trunc_optab
)
1435 /* The mode of the result is different then the mode of the
1437 tmp_mode
= insn_data
[(int) icode
].operand
[0].mode
;
1438 if (GET_MODE_NUNITS (tmp_mode
) != 2 * GET_MODE_NUNITS (mode
))
1440 delete_insns_since (last
);
1447 create_output_operand (&ops
[0], target
, tmp_mode
);
1448 create_input_operand (&ops
[1], xop0
, mode0
);
1449 create_input_operand (&ops
[2], xop1
, mode1
);
1450 pat
= maybe_gen_insn (icode
, 3, ops
);
1453 /* If PAT is composed of more than one insn, try to add an appropriate
1454 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1455 operand, call expand_binop again, this time without a target. */
1456 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
1457 && ! add_equal_note (pat
, ops
[0].value
, optab_to_code (binoptab
),
1458 ops
[1].value
, ops
[2].value
))
1460 delete_insns_since (last
);
1461 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
1462 unsignedp
, methods
);
1466 return ops
[0].value
;
1468 delete_insns_since (last
);
1472 /* Generate code to perform an operation specified by BINOPTAB
1473 on operands OP0 and OP1, with result having machine-mode MODE.
1475 UNSIGNEDP is for the case where we have to widen the operands
1476 to perform the operation. It says to use zero-extension.
1478 If TARGET is nonzero, the value
1479 is generated there, if it is convenient to do so.
1480 In all cases an rtx is returned for the locus of the value;
1481 this may or may not be TARGET. */
1484 expand_binop (enum machine_mode mode
, optab binoptab
, rtx op0
, rtx op1
,
1485 rtx target
, int unsignedp
, enum optab_methods methods
)
1487 enum optab_methods next_methods
1488 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
1489 ? OPTAB_WIDEN
: methods
);
1490 enum mode_class mclass
;
1491 enum machine_mode wider_mode
;
1494 rtx entry_last
= get_last_insn ();
1497 mclass
= GET_MODE_CLASS (mode
);
1499 /* If subtracting an integer constant, convert this into an addition of
1500 the negated constant. */
1502 if (binoptab
== sub_optab
&& CONST_INT_P (op1
))
1504 op1
= negate_rtx (mode
, op1
);
1505 binoptab
= add_optab
;
1508 /* Record where to delete back to if we backtrack. */
1509 last
= get_last_insn ();
1511 /* If we can do it with a three-operand insn, do so. */
1513 if (methods
!= OPTAB_MUST_WIDEN
1514 && find_widening_optab_handler (binoptab
, mode
,
1515 widened_mode (mode
, op0
, op1
), 1)
1516 != CODE_FOR_nothing
)
1518 temp
= expand_binop_directly (mode
, binoptab
, op0
, op1
, target
,
1519 unsignedp
, methods
, last
);
1524 /* If we were trying to rotate, and that didn't work, try rotating
1525 the other direction before falling back to shifts and bitwise-or. */
1526 if (((binoptab
== rotl_optab
1527 && optab_handler (rotr_optab
, mode
) != CODE_FOR_nothing
)
1528 || (binoptab
== rotr_optab
1529 && optab_handler (rotl_optab
, mode
) != CODE_FOR_nothing
))
1530 && mclass
== MODE_INT
)
1532 optab otheroptab
= (binoptab
== rotl_optab
? rotr_optab
: rotl_optab
);
1534 unsigned int bits
= GET_MODE_PRECISION (mode
);
1536 if (CONST_INT_P (op1
))
1537 newop1
= GEN_INT (bits
- INTVAL (op1
));
1538 else if (targetm
.shift_truncation_mask (mode
) == bits
- 1)
1539 newop1
= negate_rtx (GET_MODE (op1
), op1
);
1541 newop1
= expand_binop (GET_MODE (op1
), sub_optab
,
1542 GEN_INT (bits
), op1
,
1543 NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1545 temp
= expand_binop_directly (mode
, otheroptab
, op0
, newop1
,
1546 target
, unsignedp
, methods
, last
);
1551 /* If this is a multiply, see if we can do a widening operation that
1552 takes operands of this mode and makes a wider mode. */
1554 if (binoptab
== smul_optab
1555 && GET_MODE_2XWIDER_MODE (mode
) != VOIDmode
1556 && (widening_optab_handler ((unsignedp
? umul_widen_optab
1557 : smul_widen_optab
),
1558 GET_MODE_2XWIDER_MODE (mode
), mode
)
1559 != CODE_FOR_nothing
))
1561 temp
= expand_binop (GET_MODE_2XWIDER_MODE (mode
),
1562 unsignedp
? umul_widen_optab
: smul_widen_optab
,
1563 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1567 if (GET_MODE_CLASS (mode
) == MODE_INT
1568 && TRULY_NOOP_TRUNCATION_MODES_P (mode
, GET_MODE (temp
)))
1569 return gen_lowpart (mode
, temp
);
1571 return convert_to_mode (mode
, temp
, unsignedp
);
1575 /* If this is a vector shift by a scalar, see if we can do a vector
1576 shift by a vector. If so, broadcast the scalar into a vector. */
1577 if (mclass
== MODE_VECTOR_INT
)
1579 optab otheroptab
= unknown_optab
;
1581 if (binoptab
== ashl_optab
)
1582 otheroptab
= vashl_optab
;
1583 else if (binoptab
== ashr_optab
)
1584 otheroptab
= vashr_optab
;
1585 else if (binoptab
== lshr_optab
)
1586 otheroptab
= vlshr_optab
;
1587 else if (binoptab
== rotl_optab
)
1588 otheroptab
= vrotl_optab
;
1589 else if (binoptab
== rotr_optab
)
1590 otheroptab
= vrotr_optab
;
1592 if (otheroptab
&& optab_handler (otheroptab
, mode
) != CODE_FOR_nothing
)
1594 rtx vop1
= expand_vector_broadcast (mode
, op1
);
1597 temp
= expand_binop_directly (mode
, otheroptab
, op0
, vop1
,
1598 target
, unsignedp
, methods
, last
);
1605 /* Look for a wider mode of the same class for which we think we
1606 can open-code the operation. Check for a widening multiply at the
1607 wider mode as well. */
1609 if (CLASS_HAS_WIDER_MODES_P (mclass
)
1610 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
1611 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
1612 wider_mode
!= VOIDmode
;
1613 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1615 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
1616 || (binoptab
== smul_optab
1617 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
1618 && (find_widening_optab_handler ((unsignedp
1620 : smul_widen_optab
),
1621 GET_MODE_WIDER_MODE (wider_mode
),
1623 != CODE_FOR_nothing
)))
1625 rtx xop0
= op0
, xop1
= op1
;
1628 /* For certain integer operations, we need not actually extend
1629 the narrow operands, as long as we will truncate
1630 the results to the same narrowness. */
1632 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1633 || binoptab
== xor_optab
1634 || binoptab
== add_optab
|| binoptab
== sub_optab
1635 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1636 && mclass
== MODE_INT
)
1639 xop0
= avoid_expensive_constant (mode
, binoptab
, 0,
1641 if (binoptab
!= ashl_optab
)
1642 xop1
= avoid_expensive_constant (mode
, binoptab
, 1,
1646 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
1648 /* The second operand of a shift must always be extended. */
1649 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1650 no_extend
&& binoptab
!= ashl_optab
);
1652 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1653 unsignedp
, OPTAB_DIRECT
);
1656 if (mclass
!= MODE_INT
1657 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
1660 target
= gen_reg_rtx (mode
);
1661 convert_move (target
, temp
, 0);
1665 return gen_lowpart (mode
, temp
);
1668 delete_insns_since (last
);
1672 /* If operation is commutative,
1673 try to make the first operand a register.
1674 Even better, try to make it the same as the target.
1675 Also try to make the last operand a constant. */
1676 if (commutative_optab_p (binoptab
)
1677 && swap_commutative_operands_with_target (target
, op0
, op1
))
1684 /* These can be done a word at a time. */
1685 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
1686 && mclass
== MODE_INT
1687 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1688 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1693 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1694 won't be accurate, so use a new target. */
1698 || !valid_multiword_target_p (target
))
1699 target
= gen_reg_rtx (mode
);
1703 /* Do the actual arithmetic. */
1704 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1706 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1707 rtx x
= expand_binop (word_mode
, binoptab
,
1708 operand_subword_force (op0
, i
, mode
),
1709 operand_subword_force (op1
, i
, mode
),
1710 target_piece
, unsignedp
, next_methods
);
1715 if (target_piece
!= x
)
1716 emit_move_insn (target_piece
, x
);
1719 insns
= get_insns ();
1722 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
1729 /* Synthesize double word shifts from single word shifts. */
1730 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
1731 || binoptab
== ashr_optab
)
1732 && mclass
== MODE_INT
1733 && (CONST_INT_P (op1
) || optimize_insn_for_speed_p ())
1734 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1735 && GET_MODE_PRECISION (mode
) == GET_MODE_BITSIZE (mode
)
1736 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
1737 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1738 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1740 unsigned HOST_WIDE_INT shift_mask
, double_shift_mask
;
1741 enum machine_mode op1_mode
;
1743 double_shift_mask
= targetm
.shift_truncation_mask (mode
);
1744 shift_mask
= targetm
.shift_truncation_mask (word_mode
);
1745 op1_mode
= GET_MODE (op1
) != VOIDmode
? GET_MODE (op1
) : word_mode
;
1747 /* Apply the truncation to constant shifts. */
1748 if (double_shift_mask
> 0 && CONST_INT_P (op1
))
1749 op1
= GEN_INT (INTVAL (op1
) & double_shift_mask
);
1751 if (op1
== CONST0_RTX (op1_mode
))
1754 /* Make sure that this is a combination that expand_doubleword_shift
1755 can handle. See the comments there for details. */
1756 if (double_shift_mask
== 0
1757 || (shift_mask
== BITS_PER_WORD
- 1
1758 && double_shift_mask
== BITS_PER_WORD
* 2 - 1))
1761 rtx into_target
, outof_target
;
1762 rtx into_input
, outof_input
;
1763 int left_shift
, outof_word
;
1765 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1766 won't be accurate, so use a new target. */
1770 || !valid_multiword_target_p (target
))
1771 target
= gen_reg_rtx (mode
);
1775 /* OUTOF_* is the word we are shifting bits away from, and
1776 INTO_* is the word that we are shifting bits towards, thus
1777 they differ depending on the direction of the shift and
1778 WORDS_BIG_ENDIAN. */
1780 left_shift
= binoptab
== ashl_optab
;
1781 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1783 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1784 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1786 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1787 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1789 if (expand_doubleword_shift (op1_mode
, binoptab
,
1790 outof_input
, into_input
, op1
,
1791 outof_target
, into_target
,
1792 unsignedp
, next_methods
, shift_mask
))
1794 insns
= get_insns ();
1804 /* Synthesize double word rotates from single word shifts. */
1805 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
1806 && mclass
== MODE_INT
1807 && CONST_INT_P (op1
)
1808 && GET_MODE_PRECISION (mode
) == 2 * BITS_PER_WORD
1809 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1810 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1813 rtx into_target
, outof_target
;
1814 rtx into_input
, outof_input
;
1816 int shift_count
, left_shift
, outof_word
;
1818 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1819 won't be accurate, so use a new target. Do this also if target is not
1820 a REG, first because having a register instead may open optimization
1821 opportunities, and second because if target and op0 happen to be MEMs
1822 designating the same location, we would risk clobbering it too early
1823 in the code sequence we generate below. */
1828 || !valid_multiword_target_p (target
))
1829 target
= gen_reg_rtx (mode
);
1833 shift_count
= INTVAL (op1
);
1835 /* OUTOF_* is the word we are shifting bits away from, and
1836 INTO_* is the word that we are shifting bits towards, thus
1837 they differ depending on the direction of the shift and
1838 WORDS_BIG_ENDIAN. */
1840 left_shift
= (binoptab
== rotl_optab
);
1841 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1843 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1844 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1846 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1847 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1849 if (shift_count
== BITS_PER_WORD
)
1851 /* This is just a word swap. */
1852 emit_move_insn (outof_target
, into_input
);
1853 emit_move_insn (into_target
, outof_input
);
1858 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1859 rtx first_shift_count
, second_shift_count
;
1860 optab reverse_unsigned_shift
, unsigned_shift
;
1862 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1863 ? lshr_optab
: ashl_optab
);
1865 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1866 ? ashl_optab
: lshr_optab
);
1868 if (shift_count
> BITS_PER_WORD
)
1870 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
1871 second_shift_count
= GEN_INT (2 * BITS_PER_WORD
- shift_count
);
1875 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
1876 second_shift_count
= GEN_INT (shift_count
);
1879 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1880 outof_input
, first_shift_count
,
1881 NULL_RTX
, unsignedp
, next_methods
);
1882 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1883 into_input
, second_shift_count
,
1884 NULL_RTX
, unsignedp
, next_methods
);
1886 if (into_temp1
!= 0 && into_temp2
!= 0)
1887 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1888 into_target
, unsignedp
, next_methods
);
1892 if (inter
!= 0 && inter
!= into_target
)
1893 emit_move_insn (into_target
, inter
);
1895 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1896 into_input
, first_shift_count
,
1897 NULL_RTX
, unsignedp
, next_methods
);
1898 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1899 outof_input
, second_shift_count
,
1900 NULL_RTX
, unsignedp
, next_methods
);
1902 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1903 inter
= expand_binop (word_mode
, ior_optab
,
1904 outof_temp1
, outof_temp2
,
1905 outof_target
, unsignedp
, next_methods
);
1907 if (inter
!= 0 && inter
!= outof_target
)
1908 emit_move_insn (outof_target
, inter
);
1911 insns
= get_insns ();
1921 /* These can be done a word at a time by propagating carries. */
1922 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1923 && mclass
== MODE_INT
1924 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
1925 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1928 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1929 const unsigned int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
1930 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1931 rtx xop0
, xop1
, xtarget
;
1933 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1934 value is one of those, use it. Otherwise, use 1 since it is the
1935 one easiest to get. */
1936 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1937 int normalizep
= STORE_FLAG_VALUE
;
1942 /* Prepare the operands. */
1943 xop0
= force_reg (mode
, op0
);
1944 xop1
= force_reg (mode
, op1
);
1946 xtarget
= gen_reg_rtx (mode
);
1948 if (target
== 0 || !REG_P (target
) || !valid_multiword_target_p (target
))
1951 /* Indicate for flow that the entire target reg is being set. */
1953 emit_clobber (xtarget
);
1955 /* Do the actual arithmetic. */
1956 for (i
= 0; i
< nwords
; i
++)
1958 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
1959 rtx target_piece
= operand_subword (xtarget
, index
, 1, mode
);
1960 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
1961 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
1964 /* Main add/subtract of the input operands. */
1965 x
= expand_binop (word_mode
, binoptab
,
1966 op0_piece
, op1_piece
,
1967 target_piece
, unsignedp
, next_methods
);
1973 /* Store carry from main add/subtract. */
1974 carry_out
= gen_reg_rtx (word_mode
);
1975 carry_out
= emit_store_flag_force (carry_out
,
1976 (binoptab
== add_optab
1979 word_mode
, 1, normalizep
);
1986 /* Add/subtract previous carry to main result. */
1987 newx
= expand_binop (word_mode
,
1988 normalizep
== 1 ? binoptab
: otheroptab
,
1990 NULL_RTX
, 1, next_methods
);
1994 /* Get out carry from adding/subtracting carry in. */
1995 rtx carry_tmp
= gen_reg_rtx (word_mode
);
1996 carry_tmp
= emit_store_flag_force (carry_tmp
,
1997 (binoptab
== add_optab
2000 word_mode
, 1, normalizep
);
2002 /* Logical-ior the two poss. carry together. */
2003 carry_out
= expand_binop (word_mode
, ior_optab
,
2004 carry_out
, carry_tmp
,
2005 carry_out
, 0, next_methods
);
2009 emit_move_insn (target_piece
, newx
);
2013 if (x
!= target_piece
)
2014 emit_move_insn (target_piece
, x
);
2017 carry_in
= carry_out
;
2020 if (i
== GET_MODE_BITSIZE (mode
) / (unsigned) BITS_PER_WORD
)
2022 if (optab_handler (mov_optab
, mode
) != CODE_FOR_nothing
2023 || ! rtx_equal_p (target
, xtarget
))
2025 rtx temp
= emit_move_insn (target
, xtarget
);
2027 set_dst_reg_note (temp
, REG_EQUAL
,
2028 gen_rtx_fmt_ee (optab_to_code (binoptab
),
2029 mode
, copy_rtx (xop0
),
2040 delete_insns_since (last
);
2043 /* Attempt to synthesize double word multiplies using a sequence of word
2044 mode multiplications. We first attempt to generate a sequence using a
2045 more efficient unsigned widening multiply, and if that fails we then
2046 try using a signed widening multiply. */
2048 if (binoptab
== smul_optab
2049 && mclass
== MODE_INT
2050 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
2051 && optab_handler (smul_optab
, word_mode
) != CODE_FOR_nothing
2052 && optab_handler (add_optab
, word_mode
) != CODE_FOR_nothing
)
2054 rtx product
= NULL_RTX
;
2055 if (widening_optab_handler (umul_widen_optab
, mode
, word_mode
)
2056 != CODE_FOR_nothing
)
2058 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
2061 delete_insns_since (last
);
2064 if (product
== NULL_RTX
2065 && widening_optab_handler (smul_widen_optab
, mode
, word_mode
)
2066 != CODE_FOR_nothing
)
2068 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
2071 delete_insns_since (last
);
2074 if (product
!= NULL_RTX
)
2076 if (optab_handler (mov_optab
, mode
) != CODE_FOR_nothing
)
2078 temp
= emit_move_insn (target
? target
: product
, product
);
2079 set_dst_reg_note (temp
,
2081 gen_rtx_fmt_ee (MULT
, mode
,
2084 target
? target
: product
);
2090 /* It can't be open-coded in this mode.
2091 Use a library call if one is available and caller says that's ok. */
2093 libfunc
= optab_libfunc (binoptab
, mode
);
2095 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
2099 enum machine_mode op1_mode
= mode
;
2104 if (shift_optab_p (binoptab
))
2106 op1_mode
= targetm
.libgcc_shift_count_mode ();
2107 /* Specify unsigned here,
2108 since negative shift counts are meaningless. */
2109 op1x
= convert_to_mode (op1_mode
, op1
, 1);
2112 if (GET_MODE (op0
) != VOIDmode
2113 && GET_MODE (op0
) != mode
)
2114 op0
= convert_to_mode (mode
, op0
, unsignedp
);
2116 /* Pass 1 for NO_QUEUE so we don't lose any increments
2117 if the libcall is cse'd or moved. */
2118 value
= emit_library_call_value (libfunc
,
2119 NULL_RTX
, LCT_CONST
, mode
, 2,
2120 op0
, mode
, op1x
, op1_mode
);
2122 insns
= get_insns ();
2125 target
= gen_reg_rtx (mode
);
2126 emit_libcall_block_1 (insns
, target
, value
,
2127 gen_rtx_fmt_ee (optab_to_code (binoptab
),
2129 trapv_binoptab_p (binoptab
));
2134 delete_insns_since (last
);
2136 /* It can't be done in this mode. Can we do it in a wider mode? */
2138 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
2139 || methods
== OPTAB_MUST_WIDEN
))
2141 /* Caller says, don't even try. */
2142 delete_insns_since (entry_last
);
2146 /* Compute the value of METHODS to pass to recursive calls.
2147 Don't allow widening to be tried recursively. */
2149 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
2151 /* Look for a wider mode of the same class for which it appears we can do
2154 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2156 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2157 wider_mode
!= VOIDmode
;
2158 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2160 if (find_widening_optab_handler (binoptab
, wider_mode
, mode
, 1)
2162 || (methods
== OPTAB_LIB
2163 && optab_libfunc (binoptab
, wider_mode
)))
2165 rtx xop0
= op0
, xop1
= op1
;
2168 /* For certain integer operations, we need not actually extend
2169 the narrow operands, as long as we will truncate
2170 the results to the same narrowness. */
2172 if ((binoptab
== ior_optab
|| binoptab
== and_optab
2173 || binoptab
== xor_optab
2174 || binoptab
== add_optab
|| binoptab
== sub_optab
2175 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
2176 && mclass
== MODE_INT
)
2179 xop0
= widen_operand (xop0
, wider_mode
, mode
,
2180 unsignedp
, no_extend
);
2182 /* The second operand of a shift must always be extended. */
2183 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
2184 no_extend
&& binoptab
!= ashl_optab
);
2186 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
2187 unsignedp
, methods
);
2190 if (mclass
!= MODE_INT
2191 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
2194 target
= gen_reg_rtx (mode
);
2195 convert_move (target
, temp
, 0);
2199 return gen_lowpart (mode
, temp
);
2202 delete_insns_since (last
);
2207 delete_insns_since (entry_last
);
2211 /* Expand a binary operator which has both signed and unsigned forms.
2212 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2215 If we widen unsigned operands, we may use a signed wider operation instead
2216 of an unsigned wider operation, since the result would be the same. */
2219 sign_expand_binop (enum machine_mode mode
, optab uoptab
, optab soptab
,
2220 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
2221 enum optab_methods methods
)
2224 optab direct_optab
= unsignedp
? uoptab
: soptab
;
2227 /* Do it without widening, if possible. */
2228 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
2229 unsignedp
, OPTAB_DIRECT
);
2230 if (temp
|| methods
== OPTAB_DIRECT
)
2233 /* Try widening to a signed int. Disable any direct use of any
2234 signed insn in the current mode. */
2235 save_enable
= swap_optab_enable (soptab
, mode
, false);
2237 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
2238 unsignedp
, OPTAB_WIDEN
);
2240 /* For unsigned operands, try widening to an unsigned int. */
2241 if (!temp
&& unsignedp
)
2242 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
2243 unsignedp
, OPTAB_WIDEN
);
2244 if (temp
|| methods
== OPTAB_WIDEN
)
2247 /* Use the right width libcall if that exists. */
2248 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
2249 unsignedp
, OPTAB_LIB
);
2250 if (temp
|| methods
== OPTAB_LIB
)
2253 /* Must widen and use a libcall, use either signed or unsigned. */
2254 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
2255 unsignedp
, methods
);
2256 if (!temp
&& unsignedp
)
2257 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
2258 unsignedp
, methods
);
2261 /* Undo the fiddling above. */
2263 swap_optab_enable (soptab
, mode
, true);
2267 /* Generate code to perform an operation specified by UNOPPTAB
2268 on operand OP0, with two results to TARG0 and TARG1.
2269 We assume that the order of the operands for the instruction
2270 is TARG0, TARG1, OP0.
2272 Either TARG0 or TARG1 may be zero, but what that means is that
2273 the result is not actually wanted. We will generate it into
2274 a dummy pseudo-reg and discard it. They may not both be zero.
2276 Returns 1 if this operation can be performed; 0 if not. */
2279 expand_twoval_unop (optab unoptab
, rtx op0
, rtx targ0
, rtx targ1
,
2282 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2283 enum mode_class mclass
;
2284 enum machine_mode wider_mode
;
2285 rtx entry_last
= get_last_insn ();
2288 mclass
= GET_MODE_CLASS (mode
);
2291 targ0
= gen_reg_rtx (mode
);
2293 targ1
= gen_reg_rtx (mode
);
2295 /* Record where to go back to if we fail. */
2296 last
= get_last_insn ();
2298 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
2300 struct expand_operand ops
[3];
2301 enum insn_code icode
= optab_handler (unoptab
, mode
);
2303 create_fixed_operand (&ops
[0], targ0
);
2304 create_fixed_operand (&ops
[1], targ1
);
2305 create_convert_operand_from (&ops
[2], op0
, mode
, unsignedp
);
2306 if (maybe_expand_insn (icode
, 3, ops
))
2310 /* It can't be done in this mode. Can we do it in a wider mode? */
2312 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2314 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2315 wider_mode
!= VOIDmode
;
2316 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2318 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2320 rtx t0
= gen_reg_rtx (wider_mode
);
2321 rtx t1
= gen_reg_rtx (wider_mode
);
2322 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2324 if (expand_twoval_unop (unoptab
, cop0
, t0
, t1
, unsignedp
))
2326 convert_move (targ0
, t0
, unsignedp
);
2327 convert_move (targ1
, t1
, unsignedp
);
2331 delete_insns_since (last
);
2336 delete_insns_since (entry_last
);
2340 /* Generate code to perform an operation specified by BINOPTAB
2341 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2342 We assume that the order of the operands for the instruction
2343 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2344 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2346 Either TARG0 or TARG1 may be zero, but what that means is that
2347 the result is not actually wanted. We will generate it into
2348 a dummy pseudo-reg and discard it. They may not both be zero.
2350 Returns 1 if this operation can be performed; 0 if not. */
2353 expand_twoval_binop (optab binoptab
, rtx op0
, rtx op1
, rtx targ0
, rtx targ1
,
2356 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2357 enum mode_class mclass
;
2358 enum machine_mode wider_mode
;
2359 rtx entry_last
= get_last_insn ();
2362 mclass
= GET_MODE_CLASS (mode
);
2365 targ0
= gen_reg_rtx (mode
);
2367 targ1
= gen_reg_rtx (mode
);
2369 /* Record where to go back to if we fail. */
2370 last
= get_last_insn ();
2372 if (optab_handler (binoptab
, mode
) != CODE_FOR_nothing
)
2374 struct expand_operand ops
[4];
2375 enum insn_code icode
= optab_handler (binoptab
, mode
);
2376 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2377 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2378 rtx xop0
= op0
, xop1
= op1
;
2380 /* If we are optimizing, force expensive constants into a register. */
2381 xop0
= avoid_expensive_constant (mode0
, binoptab
, 0, xop0
, unsignedp
);
2382 xop1
= avoid_expensive_constant (mode1
, binoptab
, 1, xop1
, unsignedp
);
2384 create_fixed_operand (&ops
[0], targ0
);
2385 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
2386 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
2387 create_fixed_operand (&ops
[3], targ1
);
2388 if (maybe_expand_insn (icode
, 4, ops
))
2390 delete_insns_since (last
);
2393 /* It can't be done in this mode. Can we do it in a wider mode? */
2395 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2397 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2398 wider_mode
!= VOIDmode
;
2399 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2401 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
)
2403 rtx t0
= gen_reg_rtx (wider_mode
);
2404 rtx t1
= gen_reg_rtx (wider_mode
);
2405 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2406 rtx cop1
= convert_modes (wider_mode
, mode
, op1
, unsignedp
);
2408 if (expand_twoval_binop (binoptab
, cop0
, cop1
,
2411 convert_move (targ0
, t0
, unsignedp
);
2412 convert_move (targ1
, t1
, unsignedp
);
2416 delete_insns_since (last
);
2421 delete_insns_since (entry_last
);
2425 /* Expand the two-valued library call indicated by BINOPTAB, but
2426 preserve only one of the values. If TARG0 is non-NULL, the first
2427 value is placed into TARG0; otherwise the second value is placed
2428 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2429 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2430 This routine assumes that the value returned by the library call is
2431 as if the return value was of an integral mode twice as wide as the
2432 mode of OP0. Returns 1 if the call was successful. */
2435 expand_twoval_binop_libfunc (optab binoptab
, rtx op0
, rtx op1
,
2436 rtx targ0
, rtx targ1
, enum rtx_code code
)
2438 enum machine_mode mode
;
2439 enum machine_mode libval_mode
;
2444 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2445 gcc_assert (!targ0
!= !targ1
);
2447 mode
= GET_MODE (op0
);
2448 libfunc
= optab_libfunc (binoptab
, mode
);
2452 /* The value returned by the library function will have twice as
2453 many bits as the nominal MODE. */
2454 libval_mode
= smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode
),
2457 libval
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
2461 /* Get the part of VAL containing the value that we want. */
2462 libval
= simplify_gen_subreg (mode
, libval
, libval_mode
,
2463 targ0
? 0 : GET_MODE_SIZE (mode
));
2464 insns
= get_insns ();
2466 /* Move the into the desired location. */
2467 emit_libcall_block (insns
, targ0
? targ0
: targ1
, libval
,
2468 gen_rtx_fmt_ee (code
, mode
, op0
, op1
));
2474 /* Wrapper around expand_unop which takes an rtx code to specify
2475 the operation to perform, not an optab pointer. All other
2476 arguments are the same. */
2478 expand_simple_unop (enum machine_mode mode
, enum rtx_code code
, rtx op0
,
2479 rtx target
, int unsignedp
)
2481 optab unop
= code_to_optab (code
);
2484 return expand_unop (mode
, unop
, op0
, target
, unsignedp
);
2490 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2492 A similar operation can be used for clrsb. UNOPTAB says which operation
2493 we are trying to expand. */
2495 widen_leading (enum machine_mode mode
, rtx op0
, rtx target
, optab unoptab
)
2497 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2498 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2500 enum machine_mode wider_mode
;
2501 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2502 wider_mode
!= VOIDmode
;
2503 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2505 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2507 rtx xop0
, temp
, last
;
2509 last
= get_last_insn ();
2512 target
= gen_reg_rtx (mode
);
2513 xop0
= widen_operand (op0
, wider_mode
, mode
,
2514 unoptab
!= clrsb_optab
, false);
2515 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2516 unoptab
!= clrsb_optab
);
2518 temp
= expand_binop (wider_mode
, sub_optab
, temp
,
2519 GEN_INT (GET_MODE_PRECISION (wider_mode
)
2520 - GET_MODE_PRECISION (mode
)),
2521 target
, true, OPTAB_DIRECT
);
2523 delete_insns_since (last
);
2532 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2533 quantities, choosing which based on whether the high word is nonzero. */
2535 expand_doubleword_clz (enum machine_mode mode
, rtx op0
, rtx target
)
2537 rtx xop0
= force_reg (mode
, op0
);
2538 rtx subhi
= gen_highpart (word_mode
, xop0
);
2539 rtx sublo
= gen_lowpart (word_mode
, xop0
);
2540 rtx hi0_label
= gen_label_rtx ();
2541 rtx after_label
= gen_label_rtx ();
2542 rtx seq
, temp
, result
;
2544 /* If we were not given a target, use a word_mode register, not a
2545 'mode' register. The result will fit, and nobody is expecting
2546 anything bigger (the return type of __builtin_clz* is int). */
2548 target
= gen_reg_rtx (word_mode
);
2550 /* In any case, write to a word_mode scratch in both branches of the
2551 conditional, so we can ensure there is a single move insn setting
2552 'target' to tag a REG_EQUAL note on. */
2553 result
= gen_reg_rtx (word_mode
);
2557 /* If the high word is not equal to zero,
2558 then clz of the full value is clz of the high word. */
2559 emit_cmp_and_jump_insns (subhi
, CONST0_RTX (word_mode
), EQ
, 0,
2560 word_mode
, true, hi0_label
);
2562 temp
= expand_unop_direct (word_mode
, clz_optab
, subhi
, result
, true);
2567 convert_move (result
, temp
, true);
2569 emit_jump_insn (gen_jump (after_label
));
2572 /* Else clz of the full value is clz of the low word plus the number
2573 of bits in the high word. */
2574 emit_label (hi0_label
);
2576 temp
= expand_unop_direct (word_mode
, clz_optab
, sublo
, 0, true);
2579 temp
= expand_binop (word_mode
, add_optab
, temp
,
2580 GEN_INT (GET_MODE_BITSIZE (word_mode
)),
2581 result
, true, OPTAB_DIRECT
);
2585 convert_move (result
, temp
, true);
2587 emit_label (after_label
);
2588 convert_move (target
, result
, true);
2593 add_equal_note (seq
, target
, CLZ
, xop0
, 0);
2605 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2607 widen_bswap (enum machine_mode mode
, rtx op0
, rtx target
)
2609 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2610 enum machine_mode wider_mode
;
2613 if (!CLASS_HAS_WIDER_MODES_P (mclass
))
2616 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2617 wider_mode
!= VOIDmode
;
2618 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2619 if (optab_handler (bswap_optab
, wider_mode
) != CODE_FOR_nothing
)
2624 last
= get_last_insn ();
2626 x
= widen_operand (op0
, wider_mode
, mode
, true, true);
2627 x
= expand_unop (wider_mode
, bswap_optab
, x
, NULL_RTX
, true);
2629 gcc_assert (GET_MODE_PRECISION (wider_mode
) == GET_MODE_BITSIZE (wider_mode
)
2630 && GET_MODE_PRECISION (mode
) == GET_MODE_BITSIZE (mode
));
2632 x
= expand_shift (RSHIFT_EXPR
, wider_mode
, x
,
2633 GET_MODE_BITSIZE (wider_mode
)
2634 - GET_MODE_BITSIZE (mode
),
2640 target
= gen_reg_rtx (mode
);
2641 emit_move_insn (target
, gen_lowpart (mode
, x
));
2644 delete_insns_since (last
);
2649 /* Try calculating bswap as two bswaps of two word-sized operands. */
2652 expand_doubleword_bswap (enum machine_mode mode
, rtx op
, rtx target
)
2656 t1
= expand_unop (word_mode
, bswap_optab
,
2657 operand_subword_force (op
, 0, mode
), NULL_RTX
, true);
2658 t0
= expand_unop (word_mode
, bswap_optab
,
2659 operand_subword_force (op
, 1, mode
), NULL_RTX
, true);
2661 if (target
== 0 || !valid_multiword_target_p (target
))
2662 target
= gen_reg_rtx (mode
);
2664 emit_clobber (target
);
2665 emit_move_insn (operand_subword (target
, 0, 1, mode
), t0
);
2666 emit_move_insn (operand_subword (target
, 1, 1, mode
), t1
);
2671 /* Try calculating (parity x) as (and (popcount x) 1), where
2672 popcount can also be done in a wider mode. */
2674 expand_parity (enum machine_mode mode
, rtx op0
, rtx target
)
2676 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2677 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2679 enum machine_mode wider_mode
;
2680 for (wider_mode
= mode
; wider_mode
!= VOIDmode
;
2681 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2683 if (optab_handler (popcount_optab
, wider_mode
) != CODE_FOR_nothing
)
2685 rtx xop0
, temp
, last
;
2687 last
= get_last_insn ();
2690 target
= gen_reg_rtx (mode
);
2691 xop0
= widen_operand (op0
, wider_mode
, mode
, true, false);
2692 temp
= expand_unop (wider_mode
, popcount_optab
, xop0
, NULL_RTX
,
2695 temp
= expand_binop (wider_mode
, and_optab
, temp
, const1_rtx
,
2696 target
, true, OPTAB_DIRECT
);
2698 delete_insns_since (last
);
2707 /* Try calculating ctz(x) as K - clz(x & -x) ,
2708 where K is GET_MODE_PRECISION(mode) - 1.
2710 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2711 don't have to worry about what the hardware does in that case. (If
2712 the clz instruction produces the usual value at 0, which is K, the
2713 result of this code sequence will be -1; expand_ffs, below, relies
2714 on this. It might be nice to have it be K instead, for consistency
2715 with the (very few) processors that provide a ctz with a defined
2716 value, but that would take one more instruction, and it would be
2717 less convenient for expand_ffs anyway. */
2720 expand_ctz (enum machine_mode mode
, rtx op0
, rtx target
)
2724 if (optab_handler (clz_optab
, mode
) == CODE_FOR_nothing
)
2729 temp
= expand_unop_direct (mode
, neg_optab
, op0
, NULL_RTX
, true);
2731 temp
= expand_binop (mode
, and_optab
, op0
, temp
, NULL_RTX
,
2732 true, OPTAB_DIRECT
);
2734 temp
= expand_unop_direct (mode
, clz_optab
, temp
, NULL_RTX
, true);
2736 temp
= expand_binop (mode
, sub_optab
, GEN_INT (GET_MODE_PRECISION (mode
) - 1),
2738 true, OPTAB_DIRECT
);
2748 add_equal_note (seq
, temp
, CTZ
, op0
, 0);
2754 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2755 else with the sequence used by expand_clz.
2757 The ffs builtin promises to return zero for a zero value and ctz/clz
2758 may have an undefined value in that case. If they do not give us a
2759 convenient value, we have to generate a test and branch. */
2761 expand_ffs (enum machine_mode mode
, rtx op0
, rtx target
)
2763 HOST_WIDE_INT val
= 0;
2764 bool defined_at_zero
= false;
2767 if (optab_handler (ctz_optab
, mode
) != CODE_FOR_nothing
)
2771 temp
= expand_unop_direct (mode
, ctz_optab
, op0
, 0, true);
2775 defined_at_zero
= (CTZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2);
2777 else if (optab_handler (clz_optab
, mode
) != CODE_FOR_nothing
)
2780 temp
= expand_ctz (mode
, op0
, 0);
2784 if (CLZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2)
2786 defined_at_zero
= true;
2787 val
= (GET_MODE_PRECISION (mode
) - 1) - val
;
2793 if (defined_at_zero
&& val
== -1)
2794 /* No correction needed at zero. */;
2797 /* We don't try to do anything clever with the situation found
2798 on some processors (eg Alpha) where ctz(0:mode) ==
2799 bitsize(mode). If someone can think of a way to send N to -1
2800 and leave alone all values in the range 0..N-1 (where N is a
2801 power of two), cheaper than this test-and-branch, please add it.
2803 The test-and-branch is done after the operation itself, in case
2804 the operation sets condition codes that can be recycled for this.
2805 (This is true on i386, for instance.) */
2807 rtx nonzero_label
= gen_label_rtx ();
2808 emit_cmp_and_jump_insns (op0
, CONST0_RTX (mode
), NE
, 0,
2809 mode
, true, nonzero_label
);
2811 convert_move (temp
, GEN_INT (-1), false);
2812 emit_label (nonzero_label
);
2815 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2816 to produce a value in the range 0..bitsize. */
2817 temp
= expand_binop (mode
, add_optab
, temp
, GEN_INT (1),
2818 target
, false, OPTAB_DIRECT
);
2825 add_equal_note (seq
, temp
, FFS
, op0
, 0);
2834 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2835 conditions, VAL may already be a SUBREG against which we cannot generate
2836 a further SUBREG. In this case, we expect forcing the value into a
2837 register will work around the situation. */
2840 lowpart_subreg_maybe_copy (enum machine_mode omode
, rtx val
,
2841 enum machine_mode imode
)
2844 ret
= lowpart_subreg (omode
, val
, imode
);
2847 val
= force_reg (imode
, val
);
2848 ret
= lowpart_subreg (omode
, val
, imode
);
2849 gcc_assert (ret
!= NULL
);
2854 /* Expand a floating point absolute value or negation operation via a
2855 logical operation on the sign bit. */
2858 expand_absneg_bit (enum rtx_code code
, enum machine_mode mode
,
2859 rtx op0
, rtx target
)
2861 const struct real_format
*fmt
;
2862 int bitpos
, word
, nwords
, i
;
2863 enum machine_mode imode
;
2867 /* The format has to have a simple sign bit. */
2868 fmt
= REAL_MODE_FORMAT (mode
);
2872 bitpos
= fmt
->signbit_rw
;
2876 /* Don't create negative zeros if the format doesn't support them. */
2877 if (code
== NEG
&& !fmt
->has_signed_zero
)
2880 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
2882 imode
= int_mode_for_mode (mode
);
2883 if (imode
== BLKmode
)
2892 if (FLOAT_WORDS_BIG_ENDIAN
)
2893 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
2895 word
= bitpos
/ BITS_PER_WORD
;
2896 bitpos
= bitpos
% BITS_PER_WORD
;
2897 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
2900 mask
= double_int_zero
.set_bit (bitpos
);
2906 || (nwords
> 1 && !valid_multiword_target_p (target
)))
2907 target
= gen_reg_rtx (mode
);
2913 for (i
= 0; i
< nwords
; ++i
)
2915 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
2916 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
2920 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2922 immed_double_int_const (mask
, imode
),
2923 targ_piece
, 1, OPTAB_LIB_WIDEN
);
2924 if (temp
!= targ_piece
)
2925 emit_move_insn (targ_piece
, temp
);
2928 emit_move_insn (targ_piece
, op0_piece
);
2931 insns
= get_insns ();
2938 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2939 gen_lowpart (imode
, op0
),
2940 immed_double_int_const (mask
, imode
),
2941 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
2942 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
2944 set_dst_reg_note (get_last_insn (), REG_EQUAL
,
2945 gen_rtx_fmt_e (code
, mode
, copy_rtx (op0
)),
2952 /* As expand_unop, but will fail rather than attempt the operation in a
2953 different mode or with a libcall. */
2955 expand_unop_direct (enum machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
2958 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
2960 struct expand_operand ops
[2];
2961 enum insn_code icode
= optab_handler (unoptab
, mode
);
2962 rtx last
= get_last_insn ();
2965 create_output_operand (&ops
[0], target
, mode
);
2966 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
2967 pat
= maybe_gen_insn (icode
, 2, ops
);
2970 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
2971 && ! add_equal_note (pat
, ops
[0].value
, optab_to_code (unoptab
),
2972 ops
[1].value
, NULL_RTX
))
2974 delete_insns_since (last
);
2975 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
2980 return ops
[0].value
;
2986 /* Generate code to perform an operation specified by UNOPTAB
2987 on operand OP0, with result having machine-mode MODE.
2989 UNSIGNEDP is for the case where we have to widen the operands
2990 to perform the operation. It says to use zero-extension.
2992 If TARGET is nonzero, the value
2993 is generated there, if it is convenient to do so.
2994 In all cases an rtx is returned for the locus of the value;
2995 this may or may not be TARGET. */
2998 expand_unop (enum machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
3001 enum mode_class mclass
= GET_MODE_CLASS (mode
);
3002 enum machine_mode wider_mode
;
3006 temp
= expand_unop_direct (mode
, unoptab
, op0
, target
, unsignedp
);
3010 /* It can't be done in this mode. Can we open-code it in a wider mode? */
3012 /* Widening (or narrowing) clz needs special treatment. */
3013 if (unoptab
== clz_optab
)
3015 temp
= widen_leading (mode
, op0
, target
, unoptab
);
3019 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
3020 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
3022 temp
= expand_doubleword_clz (mode
, op0
, target
);
3030 if (unoptab
== clrsb_optab
)
3032 temp
= widen_leading (mode
, op0
, target
, unoptab
);
3038 /* Widening (or narrowing) bswap needs special treatment. */
3039 if (unoptab
== bswap_optab
)
3041 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
3042 or ROTATERT. First try these directly; if this fails, then try the
3043 obvious pair of shifts with allowed widening, as this will probably
3044 be always more efficient than the other fallback methods. */
3047 rtx last
, temp1
, temp2
;
3049 if (optab_handler (rotl_optab
, mode
) != CODE_FOR_nothing
)
3051 temp
= expand_binop (mode
, rotl_optab
, op0
, GEN_INT (8), target
,
3052 unsignedp
, OPTAB_DIRECT
);
3057 if (optab_handler (rotr_optab
, mode
) != CODE_FOR_nothing
)
3059 temp
= expand_binop (mode
, rotr_optab
, op0
, GEN_INT (8), target
,
3060 unsignedp
, OPTAB_DIRECT
);
3065 last
= get_last_insn ();
3067 temp1
= expand_binop (mode
, ashl_optab
, op0
, GEN_INT (8), NULL_RTX
,
3068 unsignedp
, OPTAB_WIDEN
);
3069 temp2
= expand_binop (mode
, lshr_optab
, op0
, GEN_INT (8), NULL_RTX
,
3070 unsignedp
, OPTAB_WIDEN
);
3073 temp
= expand_binop (mode
, ior_optab
, temp1
, temp2
, target
,
3074 unsignedp
, OPTAB_WIDEN
);
3079 delete_insns_since (last
);
3082 temp
= widen_bswap (mode
, op0
, target
);
3086 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
3087 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
3089 temp
= expand_doubleword_bswap (mode
, op0
, target
);
3097 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3098 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
3099 wider_mode
!= VOIDmode
;
3100 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3102 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
3105 rtx last
= get_last_insn ();
3107 /* For certain operations, we need not actually extend
3108 the narrow operand, as long as we will truncate the
3109 results to the same narrowness. */
3111 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3112 (unoptab
== neg_optab
3113 || unoptab
== one_cmpl_optab
)
3114 && mclass
== MODE_INT
);
3116 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3121 if (mclass
!= MODE_INT
3122 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
3125 target
= gen_reg_rtx (mode
);
3126 convert_move (target
, temp
, 0);
3130 return gen_lowpart (mode
, temp
);
3133 delete_insns_since (last
);
3137 /* These can be done a word at a time. */
3138 if (unoptab
== one_cmpl_optab
3139 && mclass
== MODE_INT
3140 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
3141 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
3146 if (target
== 0 || target
== op0
|| !valid_multiword_target_p (target
))
3147 target
= gen_reg_rtx (mode
);
3151 /* Do the actual arithmetic. */
3152 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
3154 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
3155 rtx x
= expand_unop (word_mode
, unoptab
,
3156 operand_subword_force (op0
, i
, mode
),
3157 target_piece
, unsignedp
);
3159 if (target_piece
!= x
)
3160 emit_move_insn (target_piece
, x
);
3163 insns
= get_insns ();
3170 if (optab_to_code (unoptab
) == NEG
)
3172 /* Try negating floating point values by flipping the sign bit. */
3173 if (SCALAR_FLOAT_MODE_P (mode
))
3175 temp
= expand_absneg_bit (NEG
, mode
, op0
, target
);
3180 /* If there is no negation pattern, and we have no negative zero,
3181 try subtracting from zero. */
3182 if (!HONOR_SIGNED_ZEROS (mode
))
3184 temp
= expand_binop (mode
, (unoptab
== negv_optab
3185 ? subv_optab
: sub_optab
),
3186 CONST0_RTX (mode
), op0
, target
,
3187 unsignedp
, OPTAB_DIRECT
);
3193 /* Try calculating parity (x) as popcount (x) % 2. */
3194 if (unoptab
== parity_optab
)
3196 temp
= expand_parity (mode
, op0
, target
);
3201 /* Try implementing ffs (x) in terms of clz (x). */
3202 if (unoptab
== ffs_optab
)
3204 temp
= expand_ffs (mode
, op0
, target
);
3209 /* Try implementing ctz (x) in terms of clz (x). */
3210 if (unoptab
== ctz_optab
)
3212 temp
= expand_ctz (mode
, op0
, target
);
3218 /* Now try a library call in this mode. */
3219 libfunc
= optab_libfunc (unoptab
, mode
);
3225 enum machine_mode outmode
= mode
;
3227 /* All of these functions return small values. Thus we choose to
3228 have them return something that isn't a double-word. */
3229 if (unoptab
== ffs_optab
|| unoptab
== clz_optab
|| unoptab
== ctz_optab
3230 || unoptab
== clrsb_optab
|| unoptab
== popcount_optab
3231 || unoptab
== parity_optab
)
3233 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node
),
3234 optab_libfunc (unoptab
, mode
)));
3238 /* Pass 1 for NO_QUEUE so we don't lose any increments
3239 if the libcall is cse'd or moved. */
3240 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, outmode
,
3242 insns
= get_insns ();
3245 target
= gen_reg_rtx (outmode
);
3246 eq_value
= gen_rtx_fmt_e (optab_to_code (unoptab
), mode
, op0
);
3247 if (GET_MODE_SIZE (outmode
) < GET_MODE_SIZE (mode
))
3248 eq_value
= simplify_gen_unary (TRUNCATE
, outmode
, eq_value
, mode
);
3249 else if (GET_MODE_SIZE (outmode
) > GET_MODE_SIZE (mode
))
3250 eq_value
= simplify_gen_unary (ZERO_EXTEND
, outmode
, eq_value
, mode
);
3251 emit_libcall_block_1 (insns
, target
, value
, eq_value
,
3252 trapv_unoptab_p (unoptab
));
3257 /* It can't be done in this mode. Can we do it in a wider mode? */
3259 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3261 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
3262 wider_mode
!= VOIDmode
;
3263 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3265 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
3266 || optab_libfunc (unoptab
, wider_mode
))
3269 rtx last
= get_last_insn ();
3271 /* For certain operations, we need not actually extend
3272 the narrow operand, as long as we will truncate the
3273 results to the same narrowness. */
3274 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3275 (unoptab
== neg_optab
3276 || unoptab
== one_cmpl_optab
3277 || unoptab
== bswap_optab
)
3278 && mclass
== MODE_INT
);
3280 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3283 /* If we are generating clz using wider mode, adjust the
3284 result. Similarly for clrsb. */
3285 if ((unoptab
== clz_optab
|| unoptab
== clrsb_optab
)
3287 temp
= expand_binop (wider_mode
, sub_optab
, temp
,
3288 GEN_INT (GET_MODE_PRECISION (wider_mode
)
3289 - GET_MODE_PRECISION (mode
)),
3290 target
, true, OPTAB_DIRECT
);
3292 /* Likewise for bswap. */
3293 if (unoptab
== bswap_optab
&& temp
!= 0)
3295 gcc_assert (GET_MODE_PRECISION (wider_mode
)
3296 == GET_MODE_BITSIZE (wider_mode
)
3297 && GET_MODE_PRECISION (mode
)
3298 == GET_MODE_BITSIZE (mode
));
3300 temp
= expand_shift (RSHIFT_EXPR
, wider_mode
, temp
,
3301 GET_MODE_BITSIZE (wider_mode
)
3302 - GET_MODE_BITSIZE (mode
),
3308 if (mclass
!= MODE_INT
)
3311 target
= gen_reg_rtx (mode
);
3312 convert_move (target
, temp
, 0);
3316 return gen_lowpart (mode
, temp
);
3319 delete_insns_since (last
);
3324 /* One final attempt at implementing negation via subtraction,
3325 this time allowing widening of the operand. */
3326 if (optab_to_code (unoptab
) == NEG
&& !HONOR_SIGNED_ZEROS (mode
))
3329 temp
= expand_binop (mode
,
3330 unoptab
== negv_optab
? subv_optab
: sub_optab
,
3331 CONST0_RTX (mode
), op0
,
3332 target
, unsignedp
, OPTAB_LIB_WIDEN
);
3340 /* Emit code to compute the absolute value of OP0, with result to
3341 TARGET if convenient. (TARGET may be 0.) The return value says
3342 where the result actually is to be found.
3344 MODE is the mode of the operand; the mode of the result is
3345 different but can be deduced from MODE.
3350 expand_abs_nojump (enum machine_mode mode
, rtx op0
, rtx target
,
3351 int result_unsignedp
)
3356 result_unsignedp
= 1;
3358 /* First try to do it with a special abs instruction. */
3359 temp
= expand_unop (mode
, result_unsignedp
? abs_optab
: absv_optab
,
3364 /* For floating point modes, try clearing the sign bit. */
3365 if (SCALAR_FLOAT_MODE_P (mode
))
3367 temp
= expand_absneg_bit (ABS
, mode
, op0
, target
);
3372 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3373 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
3374 && !HONOR_SIGNED_ZEROS (mode
))
3376 rtx last
= get_last_insn ();
3378 temp
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, 0);
3380 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3386 delete_insns_since (last
);
3389 /* If this machine has expensive jumps, we can do integer absolute
3390 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3391 where W is the width of MODE. */
3393 if (GET_MODE_CLASS (mode
) == MODE_INT
3394 && BRANCH_COST (optimize_insn_for_speed_p (),
3397 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
3398 GET_MODE_PRECISION (mode
) - 1,
3401 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
3404 temp
= expand_binop (mode
, result_unsignedp
? sub_optab
: subv_optab
,
3405 temp
, extended
, target
, 0, OPTAB_LIB_WIDEN
);
3415 expand_abs (enum machine_mode mode
, rtx op0
, rtx target
,
3416 int result_unsignedp
, int safe
)
3421 result_unsignedp
= 1;
3423 temp
= expand_abs_nojump (mode
, op0
, target
, result_unsignedp
);
3427 /* If that does not win, use conditional jump and negate. */
3429 /* It is safe to use the target if it is the same
3430 as the source if this is also a pseudo register */
3431 if (op0
== target
&& REG_P (op0
)
3432 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
3435 op1
= gen_label_rtx ();
3436 if (target
== 0 || ! safe
3437 || GET_MODE (target
) != mode
3438 || (MEM_P (target
) && MEM_VOLATILE_P (target
))
3440 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
3441 target
= gen_reg_rtx (mode
);
3443 emit_move_insn (target
, op0
);
3446 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
3447 NULL_RTX
, NULL_RTX
, op1
, -1);
3449 op0
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3452 emit_move_insn (target
, op0
);
3458 /* Emit code to compute the one's complement absolute value of OP0
3459 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3460 (TARGET may be NULL_RTX.) The return value says where the result
3461 actually is to be found.
3463 MODE is the mode of the operand; the mode of the result is
3464 different but can be deduced from MODE. */
3467 expand_one_cmpl_abs_nojump (enum machine_mode mode
, rtx op0
, rtx target
)
3471 /* Not applicable for floating point modes. */
3472 if (FLOAT_MODE_P (mode
))
3475 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3476 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
)
3478 rtx last
= get_last_insn ();
3480 temp
= expand_unop (mode
, one_cmpl_optab
, op0
, NULL_RTX
, 0);
3482 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3488 delete_insns_since (last
);
3491 /* If this machine has expensive jumps, we can do one's complement
3492 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3494 if (GET_MODE_CLASS (mode
) == MODE_INT
3495 && BRANCH_COST (optimize_insn_for_speed_p (),
3498 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
3499 GET_MODE_PRECISION (mode
) - 1,
3502 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
3512 /* A subroutine of expand_copysign, perform the copysign operation using the
3513 abs and neg primitives advertised to exist on the target. The assumption
3514 is that we have a split register file, and leaving op0 in fp registers,
3515 and not playing with subregs so much, will help the register allocator. */
3518 expand_copysign_absneg (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3519 int bitpos
, bool op0_is_abs
)
3521 enum machine_mode imode
;
3522 enum insn_code icode
;
3528 /* Check if the back end provides an insn that handles signbit for the
3530 icode
= optab_handler (signbit_optab
, mode
);
3531 if (icode
!= CODE_FOR_nothing
)
3533 imode
= insn_data
[(int) icode
].operand
[0].mode
;
3534 sign
= gen_reg_rtx (imode
);
3535 emit_unop_insn (icode
, sign
, op1
, UNKNOWN
);
3541 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3543 imode
= int_mode_for_mode (mode
);
3544 if (imode
== BLKmode
)
3546 op1
= gen_lowpart (imode
, op1
);
3553 if (FLOAT_WORDS_BIG_ENDIAN
)
3554 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3556 word
= bitpos
/ BITS_PER_WORD
;
3557 bitpos
= bitpos
% BITS_PER_WORD
;
3558 op1
= operand_subword_force (op1
, word
, mode
);
3561 mask
= double_int_zero
.set_bit (bitpos
);
3563 sign
= expand_binop (imode
, and_optab
, op1
,
3564 immed_double_int_const (mask
, imode
),
3565 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3570 op0
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
3577 if (target
== NULL_RTX
)
3578 target
= copy_to_reg (op0
);
3580 emit_move_insn (target
, op0
);
3583 label
= gen_label_rtx ();
3584 emit_cmp_and_jump_insns (sign
, const0_rtx
, EQ
, NULL_RTX
, imode
, 1, label
);
3586 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3587 op0
= simplify_unary_operation (NEG
, mode
, op0
, mode
);
3589 op0
= expand_unop (mode
, neg_optab
, op0
, target
, 0);
3591 emit_move_insn (target
, op0
);
3599 /* A subroutine of expand_copysign, perform the entire copysign operation
3600 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3601 is true if op0 is known to have its sign bit clear. */
3604 expand_copysign_bit (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3605 int bitpos
, bool op0_is_abs
)
3607 enum machine_mode imode
;
3609 int word
, nwords
, i
;
3612 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3614 imode
= int_mode_for_mode (mode
);
3615 if (imode
== BLKmode
)
3624 if (FLOAT_WORDS_BIG_ENDIAN
)
3625 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3627 word
= bitpos
/ BITS_PER_WORD
;
3628 bitpos
= bitpos
% BITS_PER_WORD
;
3629 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
3632 mask
= double_int_zero
.set_bit (bitpos
);
3637 || (nwords
> 1 && !valid_multiword_target_p (target
)))
3638 target
= gen_reg_rtx (mode
);
3644 for (i
= 0; i
< nwords
; ++i
)
3646 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
3647 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
3653 = expand_binop (imode
, and_optab
, op0_piece
,
3654 immed_double_int_const (~mask
, imode
),
3655 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3657 op1
= expand_binop (imode
, and_optab
,
3658 operand_subword_force (op1
, i
, mode
),
3659 immed_double_int_const (mask
, imode
),
3660 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3662 temp
= expand_binop (imode
, ior_optab
, op0_piece
, op1
,
3663 targ_piece
, 1, OPTAB_LIB_WIDEN
);
3664 if (temp
!= targ_piece
)
3665 emit_move_insn (targ_piece
, temp
);
3668 emit_move_insn (targ_piece
, op0_piece
);
3671 insns
= get_insns ();
3678 op1
= expand_binop (imode
, and_optab
, gen_lowpart (imode
, op1
),
3679 immed_double_int_const (mask
, imode
),
3680 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3682 op0
= gen_lowpart (imode
, op0
);
3684 op0
= expand_binop (imode
, and_optab
, op0
,
3685 immed_double_int_const (~mask
, imode
),
3686 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3688 temp
= expand_binop (imode
, ior_optab
, op0
, op1
,
3689 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3690 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3696 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3697 scalar floating point mode. Return NULL if we do not know how to
3698 expand the operation inline. */
3701 expand_copysign (rtx op0
, rtx op1
, rtx target
)
3703 enum machine_mode mode
= GET_MODE (op0
);
3704 const struct real_format
*fmt
;
3708 gcc_assert (SCALAR_FLOAT_MODE_P (mode
));
3709 gcc_assert (GET_MODE (op1
) == mode
);
3711 /* First try to do it with a special instruction. */
3712 temp
= expand_binop (mode
, copysign_optab
, op0
, op1
,
3713 target
, 0, OPTAB_DIRECT
);
3717 fmt
= REAL_MODE_FORMAT (mode
);
3718 if (fmt
== NULL
|| !fmt
->has_signed_zero
)
3722 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3724 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0
)))
3725 op0
= simplify_unary_operation (ABS
, mode
, op0
, mode
);
3729 if (fmt
->signbit_ro
>= 0
3730 && (CONST_DOUBLE_AS_FLOAT_P (op0
)
3731 || (optab_handler (neg_optab
, mode
) != CODE_FOR_nothing
3732 && optab_handler (abs_optab
, mode
) != CODE_FOR_nothing
)))
3734 temp
= expand_copysign_absneg (mode
, op0
, op1
, target
,
3735 fmt
->signbit_ro
, op0_is_abs
);
3740 if (fmt
->signbit_rw
< 0)
3742 return expand_copysign_bit (mode
, op0
, op1
, target
,
3743 fmt
->signbit_rw
, op0_is_abs
);
3746 /* Generate an instruction whose insn-code is INSN_CODE,
3747 with two operands: an output TARGET and an input OP0.
3748 TARGET *must* be nonzero, and the output is always stored there.
3749 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3750 the value that is stored into TARGET.
3752 Return false if expansion failed. */
3755 maybe_emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
,
3758 struct expand_operand ops
[2];
3761 create_output_operand (&ops
[0], target
, GET_MODE (target
));
3762 create_input_operand (&ops
[1], op0
, GET_MODE (op0
));
3763 pat
= maybe_gen_insn (icode
, 2, ops
);
3767 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
&& code
!= UNKNOWN
)
3768 add_equal_note (pat
, ops
[0].value
, code
, ops
[1].value
, NULL_RTX
);
3772 if (ops
[0].value
!= target
)
3773 emit_move_insn (target
, ops
[0].value
);
3776 /* Generate an instruction whose insn-code is INSN_CODE,
3777 with two operands: an output TARGET and an input OP0.
3778 TARGET *must* be nonzero, and the output is always stored there.
3779 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3780 the value that is stored into TARGET. */
3783 emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
, enum rtx_code code
)
3785 bool ok
= maybe_emit_unop_insn (icode
, target
, op0
, code
);
3789 struct no_conflict_data
3791 rtx target
, first
, insn
;
3795 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3796 the currently examined clobber / store has to stay in the list of
3797 insns that constitute the actual libcall block. */
3799 no_conflict_move_test (rtx dest
, const_rtx set
, void *p0
)
3801 struct no_conflict_data
*p
= (struct no_conflict_data
*) p0
;
3803 /* If this inns directly contributes to setting the target, it must stay. */
3804 if (reg_overlap_mentioned_p (p
->target
, dest
))
3805 p
->must_stay
= true;
3806 /* If we haven't committed to keeping any other insns in the list yet,
3807 there is nothing more to check. */
3808 else if (p
->insn
== p
->first
)
3810 /* If this insn sets / clobbers a register that feeds one of the insns
3811 already in the list, this insn has to stay too. */
3812 else if (reg_overlap_mentioned_p (dest
, PATTERN (p
->first
))
3813 || (CALL_P (p
->first
) && (find_reg_fusage (p
->first
, USE
, dest
)))
3814 || reg_used_between_p (dest
, p
->first
, p
->insn
)
3815 /* Likewise if this insn depends on a register set by a previous
3816 insn in the list, or if it sets a result (presumably a hard
3817 register) that is set or clobbered by a previous insn.
3818 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3819 SET_DEST perform the former check on the address, and the latter
3820 check on the MEM. */
3821 || (GET_CODE (set
) == SET
3822 && (modified_in_p (SET_SRC (set
), p
->first
)
3823 || modified_in_p (SET_DEST (set
), p
->first
)
3824 || modified_between_p (SET_SRC (set
), p
->first
, p
->insn
)
3825 || modified_between_p (SET_DEST (set
), p
->first
, p
->insn
))))
3826 p
->must_stay
= true;
3830 /* Emit code to make a call to a constant function or a library call.
3832 INSNS is a list containing all insns emitted in the call.
3833 These insns leave the result in RESULT. Our block is to copy RESULT
3834 to TARGET, which is logically equivalent to EQUIV.
3836 We first emit any insns that set a pseudo on the assumption that these are
3837 loading constants into registers; doing so allows them to be safely cse'ed
3838 between blocks. Then we emit all the other insns in the block, followed by
3839 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3840 note with an operand of EQUIV. */
3843 emit_libcall_block_1 (rtx insns
, rtx target
, rtx result
, rtx equiv
,
3844 bool equiv_may_trap
)
3846 rtx final_dest
= target
;
3847 rtx next
, last
, insn
;
3849 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3850 into a MEM later. Protect the libcall block from this change. */
3851 if (! REG_P (target
) || REG_USERVAR_P (target
))
3852 target
= gen_reg_rtx (GET_MODE (target
));
3854 /* If we're using non-call exceptions, a libcall corresponding to an
3855 operation that may trap may also trap. */
3856 /* ??? See the comment in front of make_reg_eh_region_note. */
3857 if (cfun
->can_throw_non_call_exceptions
3858 && (equiv_may_trap
|| may_trap_p (equiv
)))
3860 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3863 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
3866 int lp_nr
= INTVAL (XEXP (note
, 0));
3867 if (lp_nr
== 0 || lp_nr
== INT_MIN
)
3868 remove_note (insn
, note
);
3874 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3875 reg note to indicate that this call cannot throw or execute a nonlocal
3876 goto (unless there is already a REG_EH_REGION note, in which case
3878 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3880 make_reg_eh_region_note_nothrow_nononlocal (insn
);
3883 /* First emit all insns that set pseudos. Remove them from the list as
3884 we go. Avoid insns that set pseudos which were referenced in previous
3885 insns. These can be generated by move_by_pieces, for example,
3886 to update an address. Similarly, avoid insns that reference things
3887 set in previous insns. */
3889 for (insn
= insns
; insn
; insn
= next
)
3891 rtx set
= single_set (insn
);
3893 next
= NEXT_INSN (insn
);
3895 if (set
!= 0 && REG_P (SET_DEST (set
))
3896 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
)
3898 struct no_conflict_data data
;
3900 data
.target
= const0_rtx
;
3904 note_stores (PATTERN (insn
), no_conflict_move_test
, &data
);
3905 if (! data
.must_stay
)
3907 if (PREV_INSN (insn
))
3908 NEXT_INSN (PREV_INSN (insn
)) = next
;
3913 PREV_INSN (next
) = PREV_INSN (insn
);
3919 /* Some ports use a loop to copy large arguments onto the stack.
3920 Don't move anything outside such a loop. */
3925 /* Write the remaining insns followed by the final copy. */
3926 for (insn
= insns
; insn
; insn
= next
)
3928 next
= NEXT_INSN (insn
);
3933 last
= emit_move_insn (target
, result
);
3934 set_dst_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
), target
);
3936 if (final_dest
!= target
)
3937 emit_move_insn (final_dest
, target
);
3941 emit_libcall_block (rtx insns
, rtx target
, rtx result
, rtx equiv
)
3943 emit_libcall_block_1 (insns
, target
, result
, equiv
, false);
3946 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3947 PURPOSE describes how this comparison will be used. CODE is the rtx
3948 comparison code we will be using.
3950 ??? Actually, CODE is slightly weaker than that. A target is still
3951 required to implement all of the normal bcc operations, but not
3952 required to implement all (or any) of the unordered bcc operations. */
3955 can_compare_p (enum rtx_code code
, enum machine_mode mode
,
3956 enum can_compare_purpose purpose
)
3959 test
= gen_rtx_fmt_ee (code
, mode
, const0_rtx
, const0_rtx
);
3962 enum insn_code icode
;
3964 if (purpose
== ccp_jump
3965 && (icode
= optab_handler (cbranch_optab
, mode
)) != CODE_FOR_nothing
3966 && insn_operand_matches (icode
, 0, test
))
3968 if (purpose
== ccp_store_flag
3969 && (icode
= optab_handler (cstore_optab
, mode
)) != CODE_FOR_nothing
3970 && insn_operand_matches (icode
, 1, test
))
3972 if (purpose
== ccp_cmov
3973 && optab_handler (cmov_optab
, mode
) != CODE_FOR_nothing
)
3976 mode
= GET_MODE_WIDER_MODE (mode
);
3977 PUT_MODE (test
, mode
);
3979 while (mode
!= VOIDmode
);
3984 /* This function is called when we are going to emit a compare instruction that
3985 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3987 *PMODE is the mode of the inputs (in case they are const_int).
3988 *PUNSIGNEDP nonzero says that the operands are unsigned;
3989 this matters if they need to be widened (as given by METHODS).
3991 If they have mode BLKmode, then SIZE specifies the size of both operands.
3993 This function performs all the setup necessary so that the caller only has
3994 to emit a single comparison insn. This setup can involve doing a BLKmode
3995 comparison or emitting a library call to perform the comparison if no insn
3996 is available to handle it.
3997 The values which are passed in through pointers can be modified; the caller
3998 should perform the comparison on the modified values. Constant
3999 comparisons must have already been folded. */
4002 prepare_cmp_insn (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4003 int unsignedp
, enum optab_methods methods
,
4004 rtx
*ptest
, enum machine_mode
*pmode
)
4006 enum machine_mode mode
= *pmode
;
4008 enum machine_mode cmp_mode
;
4009 enum mode_class mclass
;
4011 /* The other methods are not needed. */
4012 gcc_assert (methods
== OPTAB_DIRECT
|| methods
== OPTAB_WIDEN
4013 || methods
== OPTAB_LIB_WIDEN
);
4015 /* If we are optimizing, force expensive constants into a register. */
4016 if (CONSTANT_P (x
) && optimize
4017 && (rtx_cost (x
, COMPARE
, 0, optimize_insn_for_speed_p ())
4018 > COSTS_N_INSNS (1)))
4019 x
= force_reg (mode
, x
);
4021 if (CONSTANT_P (y
) && optimize
4022 && (rtx_cost (y
, COMPARE
, 1, optimize_insn_for_speed_p ())
4023 > COSTS_N_INSNS (1)))
4024 y
= force_reg (mode
, y
);
4027 /* Make sure if we have a canonical comparison. The RTL
4028 documentation states that canonical comparisons are required only
4029 for targets which have cc0. */
4030 gcc_assert (!CONSTANT_P (x
) || CONSTANT_P (y
));
4033 /* Don't let both operands fail to indicate the mode. */
4034 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
4035 x
= force_reg (mode
, x
);
4036 if (mode
== VOIDmode
)
4037 mode
= GET_MODE (x
) != VOIDmode
? GET_MODE (x
) : GET_MODE (y
);
4039 /* Handle all BLKmode compares. */
4041 if (mode
== BLKmode
)
4043 enum machine_mode result_mode
;
4044 enum insn_code cmp_code
;
4049 = GEN_INT (MIN (MEM_ALIGN (x
), MEM_ALIGN (y
)) / BITS_PER_UNIT
);
4053 /* Try to use a memory block compare insn - either cmpstr
4054 or cmpmem will do. */
4055 for (cmp_mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
4056 cmp_mode
!= VOIDmode
;
4057 cmp_mode
= GET_MODE_WIDER_MODE (cmp_mode
))
4059 cmp_code
= direct_optab_handler (cmpmem_optab
, cmp_mode
);
4060 if (cmp_code
== CODE_FOR_nothing
)
4061 cmp_code
= direct_optab_handler (cmpstr_optab
, cmp_mode
);
4062 if (cmp_code
== CODE_FOR_nothing
)
4063 cmp_code
= direct_optab_handler (cmpstrn_optab
, cmp_mode
);
4064 if (cmp_code
== CODE_FOR_nothing
)
4067 /* Must make sure the size fits the insn's mode. */
4068 if ((CONST_INT_P (size
)
4069 && INTVAL (size
) >= (1 << GET_MODE_BITSIZE (cmp_mode
)))
4070 || (GET_MODE_BITSIZE (GET_MODE (size
))
4071 > GET_MODE_BITSIZE (cmp_mode
)))
4074 result_mode
= insn_data
[cmp_code
].operand
[0].mode
;
4075 result
= gen_reg_rtx (result_mode
);
4076 size
= convert_to_mode (cmp_mode
, size
, 1);
4077 emit_insn (GEN_FCN (cmp_code
) (result
, x
, y
, size
, opalign
));
4079 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, result
, const0_rtx
);
4080 *pmode
= result_mode
;
4084 if (methods
!= OPTAB_LIB
&& methods
!= OPTAB_LIB_WIDEN
)
4087 /* Otherwise call a library function, memcmp. */
4088 libfunc
= memcmp_libfunc
;
4089 length_type
= sizetype
;
4090 result_mode
= TYPE_MODE (integer_type_node
);
4091 cmp_mode
= TYPE_MODE (length_type
);
4092 size
= convert_to_mode (TYPE_MODE (length_type
), size
,
4093 TYPE_UNSIGNED (length_type
));
4095 result
= emit_library_call_value (libfunc
, 0, LCT_PURE
,
4103 methods
= OPTAB_LIB_WIDEN
;
4107 /* Don't allow operands to the compare to trap, as that can put the
4108 compare and branch in different basic blocks. */
4109 if (cfun
->can_throw_non_call_exceptions
)
4112 x
= force_reg (mode
, x
);
4114 y
= force_reg (mode
, y
);
4117 if (GET_MODE_CLASS (mode
) == MODE_CC
)
4119 gcc_assert (can_compare_p (comparison
, CCmode
, ccp_jump
));
4120 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
4124 mclass
= GET_MODE_CLASS (mode
);
4125 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
4129 enum insn_code icode
;
4130 icode
= optab_handler (cbranch_optab
, cmp_mode
);
4131 if (icode
!= CODE_FOR_nothing
4132 && insn_operand_matches (icode
, 0, test
))
4134 rtx last
= get_last_insn ();
4135 rtx op0
= prepare_operand (icode
, x
, 1, mode
, cmp_mode
, unsignedp
);
4136 rtx op1
= prepare_operand (icode
, y
, 2, mode
, cmp_mode
, unsignedp
);
4138 && insn_operand_matches (icode
, 1, op0
)
4139 && insn_operand_matches (icode
, 2, op1
))
4141 XEXP (test
, 0) = op0
;
4142 XEXP (test
, 1) = op1
;
4147 delete_insns_since (last
);
4150 if (methods
== OPTAB_DIRECT
|| !CLASS_HAS_WIDER_MODES_P (mclass
))
4152 cmp_mode
= GET_MODE_WIDER_MODE (cmp_mode
);
4154 while (cmp_mode
!= VOIDmode
);
4156 if (methods
!= OPTAB_LIB_WIDEN
)
4159 if (!SCALAR_FLOAT_MODE_P (mode
))
4162 enum machine_mode ret_mode
;
4164 /* Handle a libcall just for the mode we are using. */
4165 libfunc
= optab_libfunc (cmp_optab
, mode
);
4166 gcc_assert (libfunc
);
4168 /* If we want unsigned, and this mode has a distinct unsigned
4169 comparison routine, use that. */
4172 rtx ulibfunc
= optab_libfunc (ucmp_optab
, mode
);
4177 ret_mode
= targetm
.libgcc_cmp_return_mode ();
4178 result
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4179 ret_mode
, 2, x
, mode
, y
, mode
);
4181 /* There are two kinds of comparison routines. Biased routines
4182 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4183 of gcc expect that the comparison operation is equivalent
4184 to the modified comparison. For signed comparisons compare the
4185 result against 1 in the biased case, and zero in the unbiased
4186 case. For unsigned comparisons always compare against 1 after
4187 biasing the unbiased result by adding 1. This gives us a way to
4189 The comparisons in the fixed-point helper library are always
4194 if (!TARGET_LIB_INT_CMP_BIASED
&& !ALL_FIXED_POINT_MODE_P (mode
))
4197 x
= plus_constant (ret_mode
, result
, 1);
4203 prepare_cmp_insn (x
, y
, comparison
, NULL_RTX
, unsignedp
, methods
,
4207 prepare_float_lib_cmp (x
, y
, comparison
, ptest
, pmode
);
4215 /* Before emitting an insn with code ICODE, make sure that X, which is going
4216 to be used for operand OPNUM of the insn, is converted from mode MODE to
4217 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4218 that it is accepted by the operand predicate. Return the new value. */
4221 prepare_operand (enum insn_code icode
, rtx x
, int opnum
, enum machine_mode mode
,
4222 enum machine_mode wider_mode
, int unsignedp
)
4224 if (mode
!= wider_mode
)
4225 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
4227 if (!insn_operand_matches (icode
, opnum
, x
))
4229 if (reload_completed
)
4231 x
= copy_to_mode_reg (insn_data
[(int) icode
].operand
[opnum
].mode
, x
);
4237 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4238 we can do the branch. */
4241 emit_cmp_and_jump_insn_1 (rtx test
, enum machine_mode mode
, rtx label
, int prob
)
4243 enum machine_mode optab_mode
;
4244 enum mode_class mclass
;
4245 enum insn_code icode
;
4248 mclass
= GET_MODE_CLASS (mode
);
4249 optab_mode
= (mclass
== MODE_CC
) ? CCmode
: mode
;
4250 icode
= optab_handler (cbranch_optab
, optab_mode
);
4252 gcc_assert (icode
!= CODE_FOR_nothing
);
4253 gcc_assert (insn_operand_matches (icode
, 0, test
));
4254 insn
= emit_jump_insn (GEN_FCN (icode
) (test
, XEXP (test
, 0),
4255 XEXP (test
, 1), label
));
4257 && profile_status
!= PROFILE_ABSENT
4260 && any_condjump_p (insn
)
4261 && !find_reg_note (insn
, REG_BR_PROB
, 0))
4262 add_reg_note (insn
, REG_BR_PROB
, GEN_INT (prob
));
4265 /* Generate code to compare X with Y so that the condition codes are
4266 set and to jump to LABEL if the condition is true. If X is a
4267 constant and Y is not a constant, then the comparison is swapped to
4268 ensure that the comparison RTL has the canonical form.
4270 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4271 need to be widened. UNSIGNEDP is also used to select the proper
4272 branch condition code.
4274 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4276 MODE is the mode of the inputs (in case they are const_int).
4278 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4279 It will be potentially converted into an unsigned variant based on
4280 UNSIGNEDP to select a proper jump instruction.
4282 PROB is the probability of jumping to LABEL. */
4285 emit_cmp_and_jump_insns (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4286 enum machine_mode mode
, int unsignedp
, rtx label
,
4289 rtx op0
= x
, op1
= y
;
4292 /* Swap operands and condition to ensure canonical RTL. */
4293 if (swap_commutative_operands_p (x
, y
)
4294 && can_compare_p (swap_condition (comparison
), mode
, ccp_jump
))
4297 comparison
= swap_condition (comparison
);
4300 /* If OP0 is still a constant, then both X and Y must be constants
4301 or the opposite comparison is not supported. Force X into a register
4302 to create canonical RTL. */
4303 if (CONSTANT_P (op0
))
4304 op0
= force_reg (mode
, op0
);
4307 comparison
= unsigned_condition (comparison
);
4309 prepare_cmp_insn (op0
, op1
, comparison
, size
, unsignedp
, OPTAB_LIB_WIDEN
,
4311 emit_cmp_and_jump_insn_1 (test
, mode
, label
, prob
);
4315 /* Emit a library call comparison between floating point X and Y.
4316 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4319 prepare_float_lib_cmp (rtx x
, rtx y
, enum rtx_code comparison
,
4320 rtx
*ptest
, enum machine_mode
*pmode
)
4322 enum rtx_code swapped
= swap_condition (comparison
);
4323 enum rtx_code reversed
= reverse_condition_maybe_unordered (comparison
);
4324 enum machine_mode orig_mode
= GET_MODE (x
);
4325 enum machine_mode mode
, cmp_mode
;
4326 rtx true_rtx
, false_rtx
;
4327 rtx value
, target
, insns
, equiv
;
4329 bool reversed_p
= false;
4330 cmp_mode
= targetm
.libgcc_cmp_return_mode ();
4332 for (mode
= orig_mode
;
4334 mode
= GET_MODE_WIDER_MODE (mode
))
4336 if (code_to_optab (comparison
)
4337 && (libfunc
= optab_libfunc (code_to_optab (comparison
), mode
)))
4340 if (code_to_optab (swapped
)
4341 && (libfunc
= optab_libfunc (code_to_optab (swapped
), mode
)))
4344 tmp
= x
; x
= y
; y
= tmp
;
4345 comparison
= swapped
;
4349 if (code_to_optab (reversed
)
4350 && (libfunc
= optab_libfunc (code_to_optab (reversed
), mode
)))
4352 comparison
= reversed
;
4358 gcc_assert (mode
!= VOIDmode
);
4360 if (mode
!= orig_mode
)
4362 x
= convert_to_mode (mode
, x
, 0);
4363 y
= convert_to_mode (mode
, y
, 0);
4366 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4367 the RTL. The allows the RTL optimizers to delete the libcall if the
4368 condition can be determined at compile-time. */
4369 if (comparison
== UNORDERED
4370 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4372 true_rtx
= const_true_rtx
;
4373 false_rtx
= const0_rtx
;
4380 true_rtx
= const0_rtx
;
4381 false_rtx
= const_true_rtx
;
4385 true_rtx
= const_true_rtx
;
4386 false_rtx
= const0_rtx
;
4390 true_rtx
= const1_rtx
;
4391 false_rtx
= const0_rtx
;
4395 true_rtx
= const0_rtx
;
4396 false_rtx
= constm1_rtx
;
4400 true_rtx
= constm1_rtx
;
4401 false_rtx
= const0_rtx
;
4405 true_rtx
= const0_rtx
;
4406 false_rtx
= const1_rtx
;
4414 if (comparison
== UNORDERED
)
4416 rtx temp
= simplify_gen_relational (NE
, cmp_mode
, mode
, x
, x
);
4417 equiv
= simplify_gen_relational (NE
, cmp_mode
, mode
, y
, y
);
4418 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4419 temp
, const_true_rtx
, equiv
);
4423 equiv
= simplify_gen_relational (comparison
, cmp_mode
, mode
, x
, y
);
4424 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4425 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4426 equiv
, true_rtx
, false_rtx
);
4430 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4431 cmp_mode
, 2, x
, mode
, y
, mode
);
4432 insns
= get_insns ();
4435 target
= gen_reg_rtx (cmp_mode
);
4436 emit_libcall_block (insns
, target
, value
, equiv
);
4438 if (comparison
== UNORDERED
4439 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
)
4441 *ptest
= gen_rtx_fmt_ee (reversed_p
? EQ
: NE
, VOIDmode
, target
, false_rtx
);
4443 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, target
, const0_rtx
);
4448 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4451 emit_indirect_jump (rtx loc
)
4453 struct expand_operand ops
[1];
4455 create_address_operand (&ops
[0], loc
);
4456 expand_jump_insn (CODE_FOR_indirect_jump
, 1, ops
);
4460 #ifdef HAVE_conditional_move
4462 /* Emit a conditional move instruction if the machine supports one for that
4463 condition and machine mode.
4465 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4466 the mode to use should they be constants. If it is VOIDmode, they cannot
4469 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4470 should be stored there. MODE is the mode to use should they be constants.
4471 If it is VOIDmode, they cannot both be constants.
4473 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4474 is not supported. */
4477 emit_conditional_move (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4478 enum machine_mode cmode
, rtx op2
, rtx op3
,
4479 enum machine_mode mode
, int unsignedp
)
4481 rtx tem
, comparison
, last
;
4482 enum insn_code icode
;
4483 enum rtx_code reversed
;
4485 /* If one operand is constant, make it the second one. Only do this
4486 if the other operand is not constant as well. */
4488 if (swap_commutative_operands_p (op0
, op1
))
4493 code
= swap_condition (code
);
4496 /* get_condition will prefer to generate LT and GT even if the old
4497 comparison was against zero, so undo that canonicalization here since
4498 comparisons against zero are cheaper. */
4499 if (code
== LT
&& op1
== const1_rtx
)
4500 code
= LE
, op1
= const0_rtx
;
4501 else if (code
== GT
&& op1
== constm1_rtx
)
4502 code
= GE
, op1
= const0_rtx
;
4504 if (cmode
== VOIDmode
)
4505 cmode
= GET_MODE (op0
);
4507 if (swap_commutative_operands_p (op2
, op3
)
4508 && ((reversed
= reversed_comparison_code_parts (code
, op0
, op1
, NULL
))
4517 if (mode
== VOIDmode
)
4518 mode
= GET_MODE (op2
);
4520 icode
= direct_optab_handler (movcc_optab
, mode
);
4522 if (icode
== CODE_FOR_nothing
)
4526 target
= gen_reg_rtx (mode
);
4528 code
= unsignedp
? unsigned_condition (code
) : code
;
4529 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4531 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4532 return NULL and let the caller figure out how best to deal with this
4534 if (!COMPARISON_P (comparison
))
4537 do_pending_stack_adjust ();
4538 last
= get_last_insn ();
4539 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4540 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4541 &comparison
, &cmode
);
4544 struct expand_operand ops
[4];
4546 create_output_operand (&ops
[0], target
, mode
);
4547 create_fixed_operand (&ops
[1], comparison
);
4548 create_input_operand (&ops
[2], op2
, mode
);
4549 create_input_operand (&ops
[3], op3
, mode
);
4550 if (maybe_expand_insn (icode
, 4, ops
))
4552 if (ops
[0].value
!= target
)
4553 convert_move (target
, ops
[0].value
, false);
4557 delete_insns_since (last
);
4561 /* Return nonzero if a conditional move of mode MODE is supported.
4563 This function is for combine so it can tell whether an insn that looks
4564 like a conditional move is actually supported by the hardware. If we
4565 guess wrong we lose a bit on optimization, but that's it. */
4566 /* ??? sparc64 supports conditionally moving integers values based on fp
4567 comparisons, and vice versa. How do we handle them? */
4570 can_conditionally_move_p (enum machine_mode mode
)
4572 if (direct_optab_handler (movcc_optab
, mode
) != CODE_FOR_nothing
)
4578 #endif /* HAVE_conditional_move */
4580 /* Emit a conditional addition instruction if the machine supports one for that
4581 condition and machine mode.
4583 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4584 the mode to use should they be constants. If it is VOIDmode, they cannot
4587 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4588 should be stored there. MODE is the mode to use should they be constants.
4589 If it is VOIDmode, they cannot both be constants.
4591 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4592 is not supported. */
4595 emit_conditional_add (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4596 enum machine_mode cmode
, rtx op2
, rtx op3
,
4597 enum machine_mode mode
, int unsignedp
)
4599 rtx tem
, comparison
, last
;
4600 enum insn_code icode
;
4602 /* If one operand is constant, make it the second one. Only do this
4603 if the other operand is not constant as well. */
4605 if (swap_commutative_operands_p (op0
, op1
))
4610 code
= swap_condition (code
);
4613 /* get_condition will prefer to generate LT and GT even if the old
4614 comparison was against zero, so undo that canonicalization here since
4615 comparisons against zero are cheaper. */
4616 if (code
== LT
&& op1
== const1_rtx
)
4617 code
= LE
, op1
= const0_rtx
;
4618 else if (code
== GT
&& op1
== constm1_rtx
)
4619 code
= GE
, op1
= const0_rtx
;
4621 if (cmode
== VOIDmode
)
4622 cmode
= GET_MODE (op0
);
4624 if (mode
== VOIDmode
)
4625 mode
= GET_MODE (op2
);
4627 icode
= optab_handler (addcc_optab
, mode
);
4629 if (icode
== CODE_FOR_nothing
)
4633 target
= gen_reg_rtx (mode
);
4635 code
= unsignedp
? unsigned_condition (code
) : code
;
4636 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4638 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4639 return NULL and let the caller figure out how best to deal with this
4641 if (!COMPARISON_P (comparison
))
4644 do_pending_stack_adjust ();
4645 last
= get_last_insn ();
4646 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4647 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4648 &comparison
, &cmode
);
4651 struct expand_operand ops
[4];
4653 create_output_operand (&ops
[0], target
, mode
);
4654 create_fixed_operand (&ops
[1], comparison
);
4655 create_input_operand (&ops
[2], op2
, mode
);
4656 create_input_operand (&ops
[3], op3
, mode
);
4657 if (maybe_expand_insn (icode
, 4, ops
))
4659 if (ops
[0].value
!= target
)
4660 convert_move (target
, ops
[0].value
, false);
4664 delete_insns_since (last
);
4668 /* These functions attempt to generate an insn body, rather than
4669 emitting the insn, but if the gen function already emits them, we
4670 make no attempt to turn them back into naked patterns. */
4672 /* Generate and return an insn body to add Y to X. */
4675 gen_add2_insn (rtx x
, rtx y
)
4677 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (x
));
4679 gcc_assert (insn_operand_matches (icode
, 0, x
));
4680 gcc_assert (insn_operand_matches (icode
, 1, x
));
4681 gcc_assert (insn_operand_matches (icode
, 2, y
));
4683 return GEN_FCN (icode
) (x
, x
, y
);
4686 /* Generate and return an insn body to add r1 and c,
4687 storing the result in r0. */
4690 gen_add3_insn (rtx r0
, rtx r1
, rtx c
)
4692 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (r0
));
4694 if (icode
== CODE_FOR_nothing
4695 || !insn_operand_matches (icode
, 0, r0
)
4696 || !insn_operand_matches (icode
, 1, r1
)
4697 || !insn_operand_matches (icode
, 2, c
))
4700 return GEN_FCN (icode
) (r0
, r1
, c
);
4704 have_add2_insn (rtx x
, rtx y
)
4706 enum insn_code icode
;
4708 gcc_assert (GET_MODE (x
) != VOIDmode
);
4710 icode
= optab_handler (add_optab
, GET_MODE (x
));
4712 if (icode
== CODE_FOR_nothing
)
4715 if (!insn_operand_matches (icode
, 0, x
)
4716 || !insn_operand_matches (icode
, 1, x
)
4717 || !insn_operand_matches (icode
, 2, y
))
4723 /* Generate and return an insn body to subtract Y from X. */
4726 gen_sub2_insn (rtx x
, rtx y
)
4728 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (x
));
4730 gcc_assert (insn_operand_matches (icode
, 0, x
));
4731 gcc_assert (insn_operand_matches (icode
, 1, x
));
4732 gcc_assert (insn_operand_matches (icode
, 2, y
));
4734 return GEN_FCN (icode
) (x
, x
, y
);
4737 /* Generate and return an insn body to subtract r1 and c,
4738 storing the result in r0. */
4741 gen_sub3_insn (rtx r0
, rtx r1
, rtx c
)
4743 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (r0
));
4745 if (icode
== CODE_FOR_nothing
4746 || !insn_operand_matches (icode
, 0, r0
)
4747 || !insn_operand_matches (icode
, 1, r1
)
4748 || !insn_operand_matches (icode
, 2, c
))
4751 return GEN_FCN (icode
) (r0
, r1
, c
);
4755 have_sub2_insn (rtx x
, rtx y
)
4757 enum insn_code icode
;
4759 gcc_assert (GET_MODE (x
) != VOIDmode
);
4761 icode
= optab_handler (sub_optab
, GET_MODE (x
));
4763 if (icode
== CODE_FOR_nothing
)
4766 if (!insn_operand_matches (icode
, 0, x
)
4767 || !insn_operand_matches (icode
, 1, x
)
4768 || !insn_operand_matches (icode
, 2, y
))
4774 /* Generate the body of an instruction to copy Y into X.
4775 It may be a list of insns, if one insn isn't enough. */
4778 gen_move_insn (rtx x
, rtx y
)
4783 emit_move_insn_1 (x
, y
);
4789 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4790 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4791 no such operation exists, CODE_FOR_nothing will be returned. */
4794 can_extend_p (enum machine_mode to_mode
, enum machine_mode from_mode
,
4798 #ifdef HAVE_ptr_extend
4800 return CODE_FOR_ptr_extend
;
4803 tab
= unsignedp
? zext_optab
: sext_optab
;
4804 return convert_optab_handler (tab
, to_mode
, from_mode
);
4807 /* Generate the body of an insn to extend Y (with mode MFROM)
4808 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4811 gen_extend_insn (rtx x
, rtx y
, enum machine_mode mto
,
4812 enum machine_mode mfrom
, int unsignedp
)
4814 enum insn_code icode
= can_extend_p (mto
, mfrom
, unsignedp
);
4815 return GEN_FCN (icode
) (x
, y
);
4818 /* can_fix_p and can_float_p say whether the target machine
4819 can directly convert a given fixed point type to
4820 a given floating point type, or vice versa.
4821 The returned value is the CODE_FOR_... value to use,
4822 or CODE_FOR_nothing if these modes cannot be directly converted.
4824 *TRUNCP_PTR is set to 1 if it is necessary to output
4825 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4827 static enum insn_code
4828 can_fix_p (enum machine_mode fixmode
, enum machine_mode fltmode
,
4829 int unsignedp
, int *truncp_ptr
)
4832 enum insn_code icode
;
4834 tab
= unsignedp
? ufixtrunc_optab
: sfixtrunc_optab
;
4835 icode
= convert_optab_handler (tab
, fixmode
, fltmode
);
4836 if (icode
!= CODE_FOR_nothing
)
4842 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4843 for this to work. We need to rework the fix* and ftrunc* patterns
4844 and documentation. */
4845 tab
= unsignedp
? ufix_optab
: sfix_optab
;
4846 icode
= convert_optab_handler (tab
, fixmode
, fltmode
);
4847 if (icode
!= CODE_FOR_nothing
4848 && optab_handler (ftrunc_optab
, fltmode
) != CODE_FOR_nothing
)
4855 return CODE_FOR_nothing
;
4859 can_float_p (enum machine_mode fltmode
, enum machine_mode fixmode
,
4864 tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
4865 return convert_optab_handler (tab
, fltmode
, fixmode
);
4868 /* Function supportable_convert_operation
4870 Check whether an operation represented by the code CODE is a
4871 convert operation that is supported by the target platform in
4872 vector form (i.e., when operating on arguments of type VECTYPE_IN
4873 producing a result of type VECTYPE_OUT).
4875 Convert operations we currently support directly are FIX_TRUNC and FLOAT.
4876 This function checks if these operations are supported
4877 by the target platform either directly (via vector tree-codes), or via
4881 - CODE1 is code of vector operation to be used when
4882 vectorizing the operation, if available.
4883 - DECL is decl of target builtin functions to be used
4884 when vectorizing the operation, if available. In this case,
4885 CODE1 is CALL_EXPR. */
4888 supportable_convert_operation (enum tree_code code
,
4889 tree vectype_out
, tree vectype_in
,
4890 tree
*decl
, enum tree_code
*code1
)
4892 enum machine_mode m1
,m2
;
4895 m1
= TYPE_MODE (vectype_out
);
4896 m2
= TYPE_MODE (vectype_in
);
4898 /* First check if we can done conversion directly. */
4899 if ((code
== FIX_TRUNC_EXPR
4900 && can_fix_p (m1
,m2
,TYPE_UNSIGNED (vectype_out
), &truncp
)
4901 != CODE_FOR_nothing
)
4902 || (code
== FLOAT_EXPR
4903 && can_float_p (m1
,m2
,TYPE_UNSIGNED (vectype_in
))
4904 != CODE_FOR_nothing
))
4910 /* Now check for builtin. */
4911 if (targetm
.vectorize
.builtin_conversion
4912 && targetm
.vectorize
.builtin_conversion (code
, vectype_out
, vectype_in
))
4915 *decl
= targetm
.vectorize
.builtin_conversion (code
, vectype_out
, vectype_in
);
4922 /* Generate code to convert FROM to floating point
4923 and store in TO. FROM must be fixed point and not VOIDmode.
4924 UNSIGNEDP nonzero means regard FROM as unsigned.
4925 Normally this is done by correcting the final value
4926 if it is negative. */
4929 expand_float (rtx to
, rtx from
, int unsignedp
)
4931 enum insn_code icode
;
4933 enum machine_mode fmode
, imode
;
4934 bool can_do_signed
= false;
4936 /* Crash now, because we won't be able to decide which mode to use. */
4937 gcc_assert (GET_MODE (from
) != VOIDmode
);
4939 /* Look for an insn to do the conversion. Do it in the specified
4940 modes if possible; otherwise convert either input, output or both to
4941 wider mode. If the integer mode is wider than the mode of FROM,
4942 we can do the conversion signed even if the input is unsigned. */
4944 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
4945 fmode
= GET_MODE_WIDER_MODE (fmode
))
4946 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
4947 imode
= GET_MODE_WIDER_MODE (imode
))
4949 int doing_unsigned
= unsignedp
;
4951 if (fmode
!= GET_MODE (to
)
4952 && significand_size (fmode
) < GET_MODE_PRECISION (GET_MODE (from
)))
4955 icode
= can_float_p (fmode
, imode
, unsignedp
);
4956 if (icode
== CODE_FOR_nothing
&& unsignedp
)
4958 enum insn_code scode
= can_float_p (fmode
, imode
, 0);
4959 if (scode
!= CODE_FOR_nothing
)
4960 can_do_signed
= true;
4961 if (imode
!= GET_MODE (from
))
4962 icode
= scode
, doing_unsigned
= 0;
4965 if (icode
!= CODE_FOR_nothing
)
4967 if (imode
!= GET_MODE (from
))
4968 from
= convert_to_mode (imode
, from
, unsignedp
);
4970 if (fmode
!= GET_MODE (to
))
4971 target
= gen_reg_rtx (fmode
);
4973 emit_unop_insn (icode
, target
, from
,
4974 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
4977 convert_move (to
, target
, 0);
4982 /* Unsigned integer, and no way to convert directly. Convert as signed,
4983 then unconditionally adjust the result. */
4984 if (unsignedp
&& can_do_signed
)
4986 rtx label
= gen_label_rtx ();
4988 REAL_VALUE_TYPE offset
;
4990 /* Look for a usable floating mode FMODE wider than the source and at
4991 least as wide as the target. Using FMODE will avoid rounding woes
4992 with unsigned values greater than the signed maximum value. */
4994 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
4995 fmode
= GET_MODE_WIDER_MODE (fmode
))
4996 if (GET_MODE_PRECISION (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
4997 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
5000 if (fmode
== VOIDmode
)
5002 /* There is no such mode. Pretend the target is wide enough. */
5003 fmode
= GET_MODE (to
);
5005 /* Avoid double-rounding when TO is narrower than FROM. */
5006 if ((significand_size (fmode
) + 1)
5007 < GET_MODE_PRECISION (GET_MODE (from
)))
5010 rtx neglabel
= gen_label_rtx ();
5012 /* Don't use TARGET if it isn't a register, is a hard register,
5013 or is the wrong mode. */
5015 || REGNO (target
) < FIRST_PSEUDO_REGISTER
5016 || GET_MODE (target
) != fmode
)
5017 target
= gen_reg_rtx (fmode
);
5019 imode
= GET_MODE (from
);
5020 do_pending_stack_adjust ();
5022 /* Test whether the sign bit is set. */
5023 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
5026 /* The sign bit is not set. Convert as signed. */
5027 expand_float (target
, from
, 0);
5028 emit_jump_insn (gen_jump (label
));
5031 /* The sign bit is set.
5032 Convert to a usable (positive signed) value by shifting right
5033 one bit, while remembering if a nonzero bit was shifted
5034 out; i.e., compute (from & 1) | (from >> 1). */
5036 emit_label (neglabel
);
5037 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
5038 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5039 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, 1, NULL_RTX
, 1);
5040 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
5042 expand_float (target
, temp
, 0);
5044 /* Multiply by 2 to undo the shift above. */
5045 temp
= expand_binop (fmode
, add_optab
, target
, target
,
5046 target
, 0, OPTAB_LIB_WIDEN
);
5048 emit_move_insn (target
, temp
);
5050 do_pending_stack_adjust ();
5056 /* If we are about to do some arithmetic to correct for an
5057 unsigned operand, do it in a pseudo-register. */
5059 if (GET_MODE (to
) != fmode
5060 || !REG_P (to
) || REGNO (to
) < FIRST_PSEUDO_REGISTER
)
5061 target
= gen_reg_rtx (fmode
);
5063 /* Convert as signed integer to floating. */
5064 expand_float (target
, from
, 0);
5066 /* If FROM is negative (and therefore TO is negative),
5067 correct its value by 2**bitwidth. */
5069 do_pending_stack_adjust ();
5070 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
),
5074 real_2expN (&offset
, GET_MODE_PRECISION (GET_MODE (from
)), fmode
);
5075 temp
= expand_binop (fmode
, add_optab
, target
,
5076 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
5077 target
, 0, OPTAB_LIB_WIDEN
);
5079 emit_move_insn (target
, temp
);
5081 do_pending_stack_adjust ();
5086 /* No hardware instruction available; call a library routine. */
5091 convert_optab tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
5093 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
5094 from
= convert_to_mode (SImode
, from
, unsignedp
);
5096 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5097 gcc_assert (libfunc
);
5101 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5102 GET_MODE (to
), 1, from
,
5104 insns
= get_insns ();
5107 emit_libcall_block (insns
, target
, value
,
5108 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FLOAT
: FLOAT
,
5109 GET_MODE (to
), from
));
5114 /* Copy result to requested destination
5115 if we have been computing in a temp location. */
5119 if (GET_MODE (target
) == GET_MODE (to
))
5120 emit_move_insn (to
, target
);
5122 convert_move (to
, target
, 0);
5126 /* Generate code to convert FROM to fixed point and store in TO. FROM
5127 must be floating point. */
5130 expand_fix (rtx to
, rtx from
, int unsignedp
)
5132 enum insn_code icode
;
5134 enum machine_mode fmode
, imode
;
5137 /* We first try to find a pair of modes, one real and one integer, at
5138 least as wide as FROM and TO, respectively, in which we can open-code
5139 this conversion. If the integer mode is wider than the mode of TO,
5140 we can do the conversion either signed or unsigned. */
5142 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5143 fmode
= GET_MODE_WIDER_MODE (fmode
))
5144 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
5145 imode
= GET_MODE_WIDER_MODE (imode
))
5147 int doing_unsigned
= unsignedp
;
5149 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
5150 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
5151 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
5153 if (icode
!= CODE_FOR_nothing
)
5155 rtx last
= get_last_insn ();
5156 if (fmode
!= GET_MODE (from
))
5157 from
= convert_to_mode (fmode
, from
, 0);
5161 rtx temp
= gen_reg_rtx (GET_MODE (from
));
5162 from
= expand_unop (GET_MODE (from
), ftrunc_optab
, from
,
5166 if (imode
!= GET_MODE (to
))
5167 target
= gen_reg_rtx (imode
);
5169 if (maybe_emit_unop_insn (icode
, target
, from
,
5170 doing_unsigned
? UNSIGNED_FIX
: FIX
))
5173 convert_move (to
, target
, unsignedp
);
5176 delete_insns_since (last
);
5180 /* For an unsigned conversion, there is one more way to do it.
5181 If we have a signed conversion, we generate code that compares
5182 the real value to the largest representable positive number. If if
5183 is smaller, the conversion is done normally. Otherwise, subtract
5184 one plus the highest signed number, convert, and add it back.
5186 We only need to check all real modes, since we know we didn't find
5187 anything with a wider integer mode.
5189 This code used to extend FP value into mode wider than the destination.
5190 This is needed for decimal float modes which cannot accurately
5191 represent one plus the highest signed number of the same size, but
5192 not for binary modes. Consider, for instance conversion from SFmode
5195 The hot path through the code is dealing with inputs smaller than 2^63
5196 and doing just the conversion, so there is no bits to lose.
5198 In the other path we know the value is positive in the range 2^63..2^64-1
5199 inclusive. (as for other input overflow happens and result is undefined)
5200 So we know that the most important bit set in mantissa corresponds to
5201 2^63. The subtraction of 2^63 should not generate any rounding as it
5202 simply clears out that bit. The rest is trivial. */
5204 if (unsignedp
&& GET_MODE_PRECISION (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
5205 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5206 fmode
= GET_MODE_WIDER_MODE (fmode
))
5207 if (CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0, &must_trunc
)
5208 && (!DECIMAL_FLOAT_MODE_P (fmode
)
5209 || GET_MODE_BITSIZE (fmode
) > GET_MODE_PRECISION (GET_MODE (to
))))
5212 REAL_VALUE_TYPE offset
;
5213 rtx limit
, lab1
, lab2
, insn
;
5215 bitsize
= GET_MODE_PRECISION (GET_MODE (to
));
5216 real_2expN (&offset
, bitsize
- 1, fmode
);
5217 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
5218 lab1
= gen_label_rtx ();
5219 lab2
= gen_label_rtx ();
5221 if (fmode
!= GET_MODE (from
))
5222 from
= convert_to_mode (fmode
, from
, 0);
5224 /* See if we need to do the subtraction. */
5225 do_pending_stack_adjust ();
5226 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
),
5229 /* If not, do the signed "fix" and branch around fixup code. */
5230 expand_fix (to
, from
, 0);
5231 emit_jump_insn (gen_jump (lab2
));
5234 /* Otherwise, subtract 2**(N-1), convert to signed number,
5235 then add 2**(N-1). Do the addition using XOR since this
5236 will often generate better code. */
5238 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
5239 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
5240 expand_fix (to
, target
, 0);
5241 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
5243 ((HOST_WIDE_INT
) 1 << (bitsize
- 1),
5245 to
, 1, OPTAB_LIB_WIDEN
);
5248 emit_move_insn (to
, target
);
5252 if (optab_handler (mov_optab
, GET_MODE (to
)) != CODE_FOR_nothing
)
5254 /* Make a place for a REG_NOTE and add it. */
5255 insn
= emit_move_insn (to
, to
);
5256 set_dst_reg_note (insn
, REG_EQUAL
,
5257 gen_rtx_fmt_e (UNSIGNED_FIX
, GET_MODE (to
),
5265 /* We can't do it with an insn, so use a library call. But first ensure
5266 that the mode of TO is at least as wide as SImode, since those are the
5267 only library calls we know about. */
5269 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
5271 target
= gen_reg_rtx (SImode
);
5273 expand_fix (target
, from
, unsignedp
);
5281 convert_optab tab
= unsignedp
? ufix_optab
: sfix_optab
;
5282 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5283 gcc_assert (libfunc
);
5287 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5288 GET_MODE (to
), 1, from
,
5290 insns
= get_insns ();
5293 emit_libcall_block (insns
, target
, value
,
5294 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
5295 GET_MODE (to
), from
));
5300 if (GET_MODE (to
) == GET_MODE (target
))
5301 emit_move_insn (to
, target
);
5303 convert_move (to
, target
, 0);
5307 /* Generate code to convert FROM or TO a fixed-point.
5308 If UINTP is true, either TO or FROM is an unsigned integer.
5309 If SATP is true, we need to saturate the result. */
5312 expand_fixed_convert (rtx to
, rtx from
, int uintp
, int satp
)
5314 enum machine_mode to_mode
= GET_MODE (to
);
5315 enum machine_mode from_mode
= GET_MODE (from
);
5317 enum rtx_code this_code
;
5318 enum insn_code code
;
5322 if (to_mode
== from_mode
)
5324 emit_move_insn (to
, from
);
5330 tab
= satp
? satfractuns_optab
: fractuns_optab
;
5331 this_code
= satp
? UNSIGNED_SAT_FRACT
: UNSIGNED_FRACT_CONVERT
;
5335 tab
= satp
? satfract_optab
: fract_optab
;
5336 this_code
= satp
? SAT_FRACT
: FRACT_CONVERT
;
5338 code
= convert_optab_handler (tab
, to_mode
, from_mode
);
5339 if (code
!= CODE_FOR_nothing
)
5341 emit_unop_insn (code
, to
, from
, this_code
);
5345 libfunc
= convert_optab_libfunc (tab
, to_mode
, from_mode
);
5346 gcc_assert (libfunc
);
5349 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, to_mode
,
5350 1, from
, from_mode
);
5351 insns
= get_insns ();
5354 emit_libcall_block (insns
, to
, value
,
5355 gen_rtx_fmt_e (optab_to_code (tab
), to_mode
, from
));
5358 /* Generate code to convert FROM to fixed point and store in TO. FROM
5359 must be floating point, TO must be signed. Use the conversion optab
5360 TAB to do the conversion. */
5363 expand_sfix_optab (rtx to
, rtx from
, convert_optab tab
)
5365 enum insn_code icode
;
5367 enum machine_mode fmode
, imode
;
5369 /* We first try to find a pair of modes, one real and one integer, at
5370 least as wide as FROM and TO, respectively, in which we can open-code
5371 this conversion. If the integer mode is wider than the mode of TO,
5372 we can do the conversion either signed or unsigned. */
5374 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5375 fmode
= GET_MODE_WIDER_MODE (fmode
))
5376 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
5377 imode
= GET_MODE_WIDER_MODE (imode
))
5379 icode
= convert_optab_handler (tab
, imode
, fmode
);
5380 if (icode
!= CODE_FOR_nothing
)
5382 rtx last
= get_last_insn ();
5383 if (fmode
!= GET_MODE (from
))
5384 from
= convert_to_mode (fmode
, from
, 0);
5386 if (imode
!= GET_MODE (to
))
5387 target
= gen_reg_rtx (imode
);
5389 if (!maybe_emit_unop_insn (icode
, target
, from
, UNKNOWN
))
5391 delete_insns_since (last
);
5395 convert_move (to
, target
, 0);
5403 /* Report whether we have an instruction to perform the operation
5404 specified by CODE on operands of mode MODE. */
5406 have_insn_for (enum rtx_code code
, enum machine_mode mode
)
5408 return (code_to_optab (code
)
5409 && (optab_handler (code_to_optab (code
), mode
)
5410 != CODE_FOR_nothing
));
5413 /* Initialize the libfunc fields of an entire group of entries in some
5414 optab. Each entry is set equal to a string consisting of a leading
5415 pair of underscores followed by a generic operation name followed by
5416 a mode name (downshifted to lowercase) followed by a single character
5417 representing the number of operands for the given operation (which is
5418 usually one of the characters '2', '3', or '4').
5420 OPTABLE is the table in which libfunc fields are to be initialized.
5421 OPNAME is the generic (string) name of the operation.
5422 SUFFIX is the character which specifies the number of operands for
5423 the given generic operation.
5424 MODE is the mode to generate for.
5428 gen_libfunc (optab optable
, const char *opname
, int suffix
,
5429 enum machine_mode mode
)
5431 unsigned opname_len
= strlen (opname
);
5432 const char *mname
= GET_MODE_NAME (mode
);
5433 unsigned mname_len
= strlen (mname
);
5434 int prefix_len
= targetm
.libfunc_gnu_prefix
? 6 : 2;
5435 int len
= prefix_len
+ opname_len
+ mname_len
+ 1 + 1;
5436 char *libfunc_name
= XALLOCAVEC (char, len
);
5443 if (targetm
.libfunc_gnu_prefix
)
5450 for (q
= opname
; *q
; )
5452 for (q
= mname
; *q
; q
++)
5453 *p
++ = TOLOWER (*q
);
5457 set_optab_libfunc (optable
, mode
,
5458 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5461 /* Like gen_libfunc, but verify that integer operation is involved. */
5464 gen_int_libfunc (optab optable
, const char *opname
, char suffix
,
5465 enum machine_mode mode
)
5467 int maxsize
= 2 * BITS_PER_WORD
;
5469 if (GET_MODE_CLASS (mode
) != MODE_INT
)
5471 if (maxsize
< LONG_LONG_TYPE_SIZE
)
5472 maxsize
= LONG_LONG_TYPE_SIZE
;
5473 if (GET_MODE_CLASS (mode
) != MODE_INT
5474 || mode
< word_mode
|| GET_MODE_BITSIZE (mode
) > maxsize
)
5476 gen_libfunc (optable
, opname
, suffix
, mode
);
5479 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */
5482 gen_fp_libfunc (optab optable
, const char *opname
, char suffix
,
5483 enum machine_mode mode
)
5487 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5488 gen_libfunc (optable
, opname
, suffix
, mode
);
5489 if (DECIMAL_FLOAT_MODE_P (mode
))
5491 dec_opname
= XALLOCAVEC (char, sizeof (DECIMAL_PREFIX
) + strlen (opname
));
5492 /* For BID support, change the name to have either a bid_ or dpd_ prefix
5493 depending on the low level floating format used. */
5494 memcpy (dec_opname
, DECIMAL_PREFIX
, sizeof (DECIMAL_PREFIX
) - 1);
5495 strcpy (dec_opname
+ sizeof (DECIMAL_PREFIX
) - 1, opname
);
5496 gen_libfunc (optable
, dec_opname
, suffix
, mode
);
5500 /* Like gen_libfunc, but verify that fixed-point operation is involved. */
5503 gen_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5504 enum machine_mode mode
)
5506 if (!ALL_FIXED_POINT_MODE_P (mode
))
5508 gen_libfunc (optable
, opname
, suffix
, mode
);
5511 /* Like gen_libfunc, but verify that signed fixed-point operation is
5515 gen_signed_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5516 enum machine_mode mode
)
5518 if (!SIGNED_FIXED_POINT_MODE_P (mode
))
5520 gen_libfunc (optable
, opname
, suffix
, mode
);
5523 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
5527 gen_unsigned_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5528 enum machine_mode mode
)
5530 if (!UNSIGNED_FIXED_POINT_MODE_P (mode
))
5532 gen_libfunc (optable
, opname
, suffix
, mode
);
5535 /* Like gen_libfunc, but verify that FP or INT operation is involved. */
5538 gen_int_fp_libfunc (optab optable
, const char *name
, char suffix
,
5539 enum machine_mode mode
)
5541 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5542 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5543 if (INTEGRAL_MODE_P (mode
))
5544 gen_int_libfunc (optable
, name
, suffix
, mode
);
5547 /* Like gen_libfunc, but verify that FP or INT operation is involved
5548 and add 'v' suffix for integer operation. */
5551 gen_intv_fp_libfunc (optab optable
, const char *name
, char suffix
,
5552 enum machine_mode mode
)
5554 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5555 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5556 if (GET_MODE_CLASS (mode
) == MODE_INT
)
5558 int len
= strlen (name
);
5559 char *v_name
= XALLOCAVEC (char, len
+ 2);
5560 strcpy (v_name
, name
);
5562 v_name
[len
+ 1] = 0;
5563 gen_int_libfunc (optable
, v_name
, suffix
, mode
);
5567 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
5571 gen_int_fp_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5572 enum machine_mode mode
)
5574 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5575 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5576 if (INTEGRAL_MODE_P (mode
))
5577 gen_int_libfunc (optable
, name
, suffix
, mode
);
5578 if (ALL_FIXED_POINT_MODE_P (mode
))
5579 gen_fixed_libfunc (optable
, name
, suffix
, mode
);
5582 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
5586 gen_int_fp_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5587 enum machine_mode mode
)
5589 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5590 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5591 if (INTEGRAL_MODE_P (mode
))
5592 gen_int_libfunc (optable
, name
, suffix
, mode
);
5593 if (SIGNED_FIXED_POINT_MODE_P (mode
))
5594 gen_signed_fixed_libfunc (optable
, name
, suffix
, mode
);
5597 /* Like gen_libfunc, but verify that INT or FIXED operation is
5601 gen_int_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5602 enum machine_mode mode
)
5604 if (INTEGRAL_MODE_P (mode
))
5605 gen_int_libfunc (optable
, name
, suffix
, mode
);
5606 if (ALL_FIXED_POINT_MODE_P (mode
))
5607 gen_fixed_libfunc (optable
, name
, suffix
, mode
);
5610 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
5614 gen_int_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5615 enum machine_mode mode
)
5617 if (INTEGRAL_MODE_P (mode
))
5618 gen_int_libfunc (optable
, name
, suffix
, mode
);
5619 if (SIGNED_FIXED_POINT_MODE_P (mode
))
5620 gen_signed_fixed_libfunc (optable
, name
, suffix
, mode
);
5623 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
5627 gen_int_unsigned_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5628 enum machine_mode mode
)
5630 if (INTEGRAL_MODE_P (mode
))
5631 gen_int_libfunc (optable
, name
, suffix
, mode
);
5632 if (UNSIGNED_FIXED_POINT_MODE_P (mode
))
5633 gen_unsigned_fixed_libfunc (optable
, name
, suffix
, mode
);
5636 /* Initialize the libfunc fields of an entire group of entries of an
5637 inter-mode-class conversion optab. The string formation rules are
5638 similar to the ones for init_libfuncs, above, but instead of having
5639 a mode name and an operand count these functions have two mode names
5640 and no operand count. */
5643 gen_interclass_conv_libfunc (convert_optab tab
,
5645 enum machine_mode tmode
,
5646 enum machine_mode fmode
)
5648 size_t opname_len
= strlen (opname
);
5649 size_t mname_len
= 0;
5651 const char *fname
, *tname
;
5653 int prefix_len
= targetm
.libfunc_gnu_prefix
? 6 : 2;
5654 char *libfunc_name
, *suffix
;
5655 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
5658 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5659 depends on which underlying decimal floating point format is used. */
5660 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
5662 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
5664 nondec_name
= XALLOCAVEC (char, prefix_len
+ opname_len
+ mname_len
+ 1 + 1);
5665 nondec_name
[0] = '_';
5666 nondec_name
[1] = '_';
5667 if (targetm
.libfunc_gnu_prefix
)
5669 nondec_name
[2] = 'g';
5670 nondec_name
[3] = 'n';
5671 nondec_name
[4] = 'u';
5672 nondec_name
[5] = '_';
5675 memcpy (&nondec_name
[prefix_len
], opname
, opname_len
);
5676 nondec_suffix
= nondec_name
+ opname_len
+ prefix_len
;
5678 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 1);
5681 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
5682 memcpy (&dec_name
[2+dec_len
], opname
, opname_len
);
5683 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
5685 fname
= GET_MODE_NAME (fmode
);
5686 tname
= GET_MODE_NAME (tmode
);
5688 if (DECIMAL_FLOAT_MODE_P(fmode
) || DECIMAL_FLOAT_MODE_P(tmode
))
5690 libfunc_name
= dec_name
;
5691 suffix
= dec_suffix
;
5695 libfunc_name
= nondec_name
;
5696 suffix
= nondec_suffix
;
5700 for (q
= fname
; *q
; p
++, q
++)
5702 for (q
= tname
; *q
; p
++, q
++)
5707 set_conv_libfunc (tab
, tmode
, fmode
,
5708 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5711 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5712 int->fp conversion. */
5715 gen_int_to_fp_conv_libfunc (convert_optab tab
,
5717 enum machine_mode tmode
,
5718 enum machine_mode fmode
)
5720 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
5722 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
5724 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5727 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
5731 gen_ufloat_conv_libfunc (convert_optab tab
,
5732 const char *opname ATTRIBUTE_UNUSED
,
5733 enum machine_mode tmode
,
5734 enum machine_mode fmode
)
5736 if (DECIMAL_FLOAT_MODE_P (tmode
))
5737 gen_int_to_fp_conv_libfunc (tab
, "floatuns", tmode
, fmode
);
5739 gen_int_to_fp_conv_libfunc (tab
, "floatun", tmode
, fmode
);
5742 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5743 fp->int conversion. */
5746 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab
,
5748 enum machine_mode tmode
,
5749 enum machine_mode fmode
)
5751 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
5753 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
)
5755 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5758 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5759 fp->int conversion with no decimal floating point involved. */
5762 gen_fp_to_int_conv_libfunc (convert_optab tab
,
5764 enum machine_mode tmode
,
5765 enum machine_mode fmode
)
5767 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
5769 if (GET_MODE_CLASS (tmode
) != MODE_INT
)
5771 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5774 /* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
5775 The string formation rules are
5776 similar to the ones for init_libfunc, above. */
5779 gen_intraclass_conv_libfunc (convert_optab tab
, const char *opname
,
5780 enum machine_mode tmode
, enum machine_mode fmode
)
5782 size_t opname_len
= strlen (opname
);
5783 size_t mname_len
= 0;
5785 const char *fname
, *tname
;
5787 int prefix_len
= targetm
.libfunc_gnu_prefix
? 6 : 2;
5788 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
5789 char *libfunc_name
, *suffix
;
5792 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5793 depends on which underlying decimal floating point format is used. */
5794 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
5796 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
5798 nondec_name
= XALLOCAVEC (char, 2 + opname_len
+ mname_len
+ 1 + 1);
5799 nondec_name
[0] = '_';
5800 nondec_name
[1] = '_';
5801 if (targetm
.libfunc_gnu_prefix
)
5803 nondec_name
[2] = 'g';
5804 nondec_name
[3] = 'n';
5805 nondec_name
[4] = 'u';
5806 nondec_name
[5] = '_';
5808 memcpy (&nondec_name
[prefix_len
], opname
, opname_len
);
5809 nondec_suffix
= nondec_name
+ opname_len
+ prefix_len
;
5811 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 1);
5814 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
5815 memcpy (&dec_name
[2 + dec_len
], opname
, opname_len
);
5816 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
5818 fname
= GET_MODE_NAME (fmode
);
5819 tname
= GET_MODE_NAME (tmode
);
5821 if (DECIMAL_FLOAT_MODE_P(fmode
) || DECIMAL_FLOAT_MODE_P(tmode
))
5823 libfunc_name
= dec_name
;
5824 suffix
= dec_suffix
;
5828 libfunc_name
= nondec_name
;
5829 suffix
= nondec_suffix
;
5833 for (q
= fname
; *q
; p
++, q
++)
5835 for (q
= tname
; *q
; p
++, q
++)
5841 set_conv_libfunc (tab
, tmode
, fmode
,
5842 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5845 /* Pick proper libcall for trunc_optab. We need to chose if we do
5846 truncation or extension and interclass or intraclass. */
5849 gen_trunc_conv_libfunc (convert_optab tab
,
5851 enum machine_mode tmode
,
5852 enum machine_mode fmode
)
5854 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
5856 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
5861 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (fmode
))
5862 || (GET_MODE_CLASS (fmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (tmode
)))
5863 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5865 if (GET_MODE_PRECISION (fmode
) <= GET_MODE_PRECISION (tmode
))
5868 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
5869 && GET_MODE_CLASS (fmode
) == MODE_FLOAT
)
5870 || (DECIMAL_FLOAT_MODE_P (fmode
) && DECIMAL_FLOAT_MODE_P (tmode
)))
5871 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5874 /* Pick proper libcall for extend_optab. We need to chose if we do
5875 truncation or extension and interclass or intraclass. */
5878 gen_extend_conv_libfunc (convert_optab tab
,
5879 const char *opname ATTRIBUTE_UNUSED
,
5880 enum machine_mode tmode
,
5881 enum machine_mode fmode
)
5883 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
5885 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
5890 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (fmode
))
5891 || (GET_MODE_CLASS (fmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (tmode
)))
5892 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5894 if (GET_MODE_PRECISION (fmode
) > GET_MODE_PRECISION (tmode
))
5897 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
5898 && GET_MODE_CLASS (fmode
) == MODE_FLOAT
)
5899 || (DECIMAL_FLOAT_MODE_P (fmode
) && DECIMAL_FLOAT_MODE_P (tmode
)))
5900 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5903 /* Pick proper libcall for fract_optab. We need to chose if we do
5904 interclass or intraclass. */
5907 gen_fract_conv_libfunc (convert_optab tab
,
5909 enum machine_mode tmode
,
5910 enum machine_mode fmode
)
5914 if (!(ALL_FIXED_POINT_MODE_P (tmode
) || ALL_FIXED_POINT_MODE_P (fmode
)))
5917 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
5918 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5920 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5923 /* Pick proper libcall for fractuns_optab. */
5926 gen_fractuns_conv_libfunc (convert_optab tab
,
5928 enum machine_mode tmode
,
5929 enum machine_mode fmode
)
5933 /* One mode must be a fixed-point mode, and the other must be an integer
5935 if (!((ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
)
5936 || (ALL_FIXED_POINT_MODE_P (fmode
)
5937 && GET_MODE_CLASS (tmode
) == MODE_INT
)))
5940 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5943 /* Pick proper libcall for satfract_optab. We need to chose if we do
5944 interclass or intraclass. */
5947 gen_satfract_conv_libfunc (convert_optab tab
,
5949 enum machine_mode tmode
,
5950 enum machine_mode fmode
)
5954 /* TMODE must be a fixed-point mode. */
5955 if (!ALL_FIXED_POINT_MODE_P (tmode
))
5958 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
5959 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5961 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5964 /* Pick proper libcall for satfractuns_optab. */
5967 gen_satfractuns_conv_libfunc (convert_optab tab
,
5969 enum machine_mode tmode
,
5970 enum machine_mode fmode
)
5974 /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
5975 if (!(ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
))
5978 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5981 /* A table of previously-created libfuncs, hashed by name. */
5982 static GTY ((param_is (union tree_node
))) htab_t libfunc_decls
;
5984 /* Hashtable callbacks for libfunc_decls. */
5987 libfunc_decl_hash (const void *entry
)
5989 return IDENTIFIER_HASH_VALUE (DECL_NAME ((const_tree
) entry
));
5993 libfunc_decl_eq (const void *entry1
, const void *entry2
)
5995 return DECL_NAME ((const_tree
) entry1
) == (const_tree
) entry2
;
5998 /* Build a decl for a libfunc named NAME. */
6001 build_libfunc_function (const char *name
)
6003 tree decl
= build_decl (UNKNOWN_LOCATION
, FUNCTION_DECL
,
6004 get_identifier (name
),
6005 build_function_type (integer_type_node
, NULL_TREE
));
6006 /* ??? We don't have any type information except for this is
6007 a function. Pretend this is "int foo()". */
6008 DECL_ARTIFICIAL (decl
) = 1;
6009 DECL_EXTERNAL (decl
) = 1;
6010 TREE_PUBLIC (decl
) = 1;
6011 gcc_assert (DECL_ASSEMBLER_NAME (decl
));
6013 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
6014 are the flags assigned by targetm.encode_section_info. */
6015 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl
), 0), NULL
);
6021 init_one_libfunc (const char *name
)
6027 if (libfunc_decls
== NULL
)
6028 libfunc_decls
= htab_create_ggc (37, libfunc_decl_hash
,
6029 libfunc_decl_eq
, NULL
);
6031 /* See if we have already created a libfunc decl for this function. */
6032 id
= get_identifier (name
);
6033 hash
= IDENTIFIER_HASH_VALUE (id
);
6034 slot
= htab_find_slot_with_hash (libfunc_decls
, id
, hash
, INSERT
);
6035 decl
= (tree
) *slot
;
6038 /* Create a new decl, so that it can be passed to
6039 targetm.encode_section_info. */
6040 decl
= build_libfunc_function (name
);
6043 return XEXP (DECL_RTL (decl
), 0);
6046 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */
6049 set_user_assembler_libfunc (const char *name
, const char *asmspec
)
6055 id
= get_identifier (name
);
6056 hash
= IDENTIFIER_HASH_VALUE (id
);
6057 slot
= htab_find_slot_with_hash (libfunc_decls
, id
, hash
, NO_INSERT
);
6059 decl
= (tree
) *slot
;
6060 set_user_assembler_name (decl
, asmspec
);
6061 return XEXP (DECL_RTL (decl
), 0);
6064 /* Call this to reset the function entry for one optab (OPTABLE) in mode
6065 MODE to NAME, which should be either 0 or a string constant. */
6067 set_optab_libfunc (optab op
, enum machine_mode mode
, const char *name
)
6070 struct libfunc_entry e
;
6071 struct libfunc_entry
**slot
;
6078 val
= init_one_libfunc (name
);
6081 slot
= (struct libfunc_entry
**) htab_find_slot (libfunc_hash
, &e
, INSERT
);
6083 *slot
= ggc_alloc_libfunc_entry ();
6085 (*slot
)->mode1
= mode
;
6086 (*slot
)->mode2
= VOIDmode
;
6087 (*slot
)->libfunc
= val
;
6090 /* Call this to reset the function entry for one conversion optab
6091 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
6092 either 0 or a string constant. */
6094 set_conv_libfunc (convert_optab optab
, enum machine_mode tmode
,
6095 enum machine_mode fmode
, const char *name
)
6098 struct libfunc_entry e
;
6099 struct libfunc_entry
**slot
;
6106 val
= init_one_libfunc (name
);
6109 slot
= (struct libfunc_entry
**) htab_find_slot (libfunc_hash
, &e
, INSERT
);
6111 *slot
= ggc_alloc_libfunc_entry ();
6112 (*slot
)->op
= optab
;
6113 (*slot
)->mode1
= tmode
;
6114 (*slot
)->mode2
= fmode
;
6115 (*slot
)->libfunc
= val
;
6118 /* Call this to initialize the contents of the optabs
6119 appropriately for the current target machine. */
6125 htab_empty (libfunc_hash
);
6127 libfunc_hash
= htab_create_ggc (10, hash_libfunc
, eq_libfunc
, NULL
);
6129 /* Fill in the optabs with the insns we support. */
6132 /* The ffs function operates on `int'. Fall back on it if we do not
6133 have a libgcc2 function for that width. */
6134 if (INT_TYPE_SIZE
< BITS_PER_WORD
)
6135 set_optab_libfunc (ffs_optab
, mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0),
6138 /* Explicitly initialize the bswap libfuncs since we need them to be
6139 valid for things other than word_mode. */
6140 if (targetm
.libfunc_gnu_prefix
)
6142 set_optab_libfunc (bswap_optab
, SImode
, "__gnu_bswapsi2");
6143 set_optab_libfunc (bswap_optab
, DImode
, "__gnu_bswapdi2");
6147 set_optab_libfunc (bswap_optab
, SImode
, "__bswapsi2");
6148 set_optab_libfunc (bswap_optab
, DImode
, "__bswapdi2");
6151 /* Use cabs for double complex abs, since systems generally have cabs.
6152 Don't define any libcall for float complex, so that cabs will be used. */
6153 if (complex_double_type_node
)
6154 set_optab_libfunc (abs_optab
, TYPE_MODE (complex_double_type_node
),
6157 abort_libfunc
= init_one_libfunc ("abort");
6158 memcpy_libfunc
= init_one_libfunc ("memcpy");
6159 memmove_libfunc
= init_one_libfunc ("memmove");
6160 memcmp_libfunc
= init_one_libfunc ("memcmp");
6161 memset_libfunc
= init_one_libfunc ("memset");
6162 setbits_libfunc
= init_one_libfunc ("__setbits");
6164 #ifndef DONT_USE_BUILTIN_SETJMP
6165 setjmp_libfunc
= init_one_libfunc ("__builtin_setjmp");
6166 longjmp_libfunc
= init_one_libfunc ("__builtin_longjmp");
6168 setjmp_libfunc
= init_one_libfunc ("setjmp");
6169 longjmp_libfunc
= init_one_libfunc ("longjmp");
6171 unwind_sjlj_register_libfunc
= init_one_libfunc ("_Unwind_SjLj_Register");
6172 unwind_sjlj_unregister_libfunc
6173 = init_one_libfunc ("_Unwind_SjLj_Unregister");
6175 /* For function entry/exit instrumentation. */
6176 profile_function_entry_libfunc
6177 = init_one_libfunc ("__cyg_profile_func_enter");
6178 profile_function_exit_libfunc
6179 = init_one_libfunc ("__cyg_profile_func_exit");
6181 gcov_flush_libfunc
= init_one_libfunc ("__gcov_flush");
6183 /* Allow the target to add more libcalls or rename some, etc. */
6184 targetm
.init_libfuncs ();
6187 /* A helper function for init_sync_libfuncs. Using the basename BASE,
6188 install libfuncs into TAB for BASE_N for 1 <= N <= MAX. */
6191 init_sync_libfuncs_1 (optab tab
, const char *base
, int max
)
6193 enum machine_mode mode
;
6195 size_t len
= strlen (base
);
6198 gcc_assert (max
<= 8);
6199 gcc_assert (len
+ 3 < sizeof (buf
));
6201 memcpy (buf
, base
, len
);
6204 buf
[len
+ 2] = '\0';
6207 for (i
= 1; i
<= max
; i
*= 2)
6209 buf
[len
+ 1] = '0' + i
;
6210 set_optab_libfunc (tab
, mode
, buf
);
6211 mode
= GET_MODE_2XWIDER_MODE (mode
);
6216 init_sync_libfuncs (int max
)
6218 if (!flag_sync_libcalls
)
6221 init_sync_libfuncs_1 (sync_compare_and_swap_optab
,
6222 "__sync_val_compare_and_swap", max
);
6223 init_sync_libfuncs_1 (sync_lock_test_and_set_optab
,
6224 "__sync_lock_test_and_set", max
);
6226 init_sync_libfuncs_1 (sync_old_add_optab
, "__sync_fetch_and_add", max
);
6227 init_sync_libfuncs_1 (sync_old_sub_optab
, "__sync_fetch_and_sub", max
);
6228 init_sync_libfuncs_1 (sync_old_ior_optab
, "__sync_fetch_and_or", max
);
6229 init_sync_libfuncs_1 (sync_old_and_optab
, "__sync_fetch_and_and", max
);
6230 init_sync_libfuncs_1 (sync_old_xor_optab
, "__sync_fetch_and_xor", max
);
6231 init_sync_libfuncs_1 (sync_old_nand_optab
, "__sync_fetch_and_nand", max
);
6233 init_sync_libfuncs_1 (sync_new_add_optab
, "__sync_add_and_fetch", max
);
6234 init_sync_libfuncs_1 (sync_new_sub_optab
, "__sync_sub_and_fetch", max
);
6235 init_sync_libfuncs_1 (sync_new_ior_optab
, "__sync_or_and_fetch", max
);
6236 init_sync_libfuncs_1 (sync_new_and_optab
, "__sync_and_and_fetch", max
);
6237 init_sync_libfuncs_1 (sync_new_xor_optab
, "__sync_xor_and_fetch", max
);
6238 init_sync_libfuncs_1 (sync_new_nand_optab
, "__sync_nand_and_fetch", max
);
6241 /* Print information about the current contents of the optabs on
6245 debug_optab_libfuncs (void)
6249 /* Dump the arithmetic optabs. */
6250 for (i
= FIRST_NORM_OPTAB
; i
<= LAST_NORMLIB_OPTAB
; ++i
)
6251 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
6253 rtx l
= optab_libfunc ((optab
) i
, (enum machine_mode
) j
);
6256 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
6257 fprintf (stderr
, "%s\t%s:\t%s\n",
6258 GET_RTX_NAME (optab_to_code ((optab
) i
)),
6264 /* Dump the conversion optabs. */
6265 for (i
= FIRST_CONV_OPTAB
; i
<= LAST_CONVLIB_OPTAB
; ++i
)
6266 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
6267 for (k
= 0; k
< NUM_MACHINE_MODES
; ++k
)
6269 rtx l
= convert_optab_libfunc ((optab
) i
, (enum machine_mode
) j
,
6270 (enum machine_mode
) k
);
6273 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
6274 fprintf (stderr
, "%s\t%s\t%s:\t%s\n",
6275 GET_RTX_NAME (optab_to_code ((optab
) i
)),
6284 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6285 CODE. Return 0 on failure. */
6288 gen_cond_trap (enum rtx_code code
, rtx op1
, rtx op2
, rtx tcode
)
6290 enum machine_mode mode
= GET_MODE (op1
);
6291 enum insn_code icode
;
6295 if (mode
== VOIDmode
)
6298 icode
= optab_handler (ctrap_optab
, mode
);
6299 if (icode
== CODE_FOR_nothing
)
6302 /* Some targets only accept a zero trap code. */
6303 if (!insn_operand_matches (icode
, 3, tcode
))
6306 do_pending_stack_adjust ();
6308 prepare_cmp_insn (op1
, op2
, code
, NULL_RTX
, false, OPTAB_DIRECT
,
6313 insn
= GEN_FCN (icode
) (trap_rtx
, XEXP (trap_rtx
, 0), XEXP (trap_rtx
, 1),
6316 /* If that failed, then give up. */
6324 insn
= get_insns ();
6329 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6330 or unsigned operation code. */
6332 static enum rtx_code
6333 get_rtx_code (enum tree_code tcode
, bool unsignedp
)
6345 code
= unsignedp
? LTU
: LT
;
6348 code
= unsignedp
? LEU
: LE
;
6351 code
= unsignedp
? GTU
: GT
;
6354 code
= unsignedp
? GEU
: GE
;
6357 case UNORDERED_EXPR
:
6388 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6389 unsigned operators. Do not generate compare instruction. */
6392 vector_compare_rtx (enum tree_code tcode
, tree t_op0
, tree t_op1
,
6393 bool unsignedp
, enum insn_code icode
)
6395 struct expand_operand ops
[2];
6396 rtx rtx_op0
, rtx_op1
;
6397 enum rtx_code rcode
= get_rtx_code (tcode
, unsignedp
);
6399 gcc_assert (TREE_CODE_CLASS (tcode
) == tcc_comparison
);
6401 /* Expand operands. */
6402 rtx_op0
= expand_expr (t_op0
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op0
)),
6404 rtx_op1
= expand_expr (t_op1
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op1
)),
6407 create_input_operand (&ops
[0], rtx_op0
, GET_MODE (rtx_op0
));
6408 create_input_operand (&ops
[1], rtx_op1
, GET_MODE (rtx_op1
));
6409 if (!maybe_legitimize_operands (icode
, 4, 2, ops
))
6411 return gen_rtx_fmt_ee (rcode
, VOIDmode
, ops
[0].value
, ops
[1].value
);
6414 /* Return true if VEC_PERM_EXPR can be expanded using SIMD extensions
6415 of the CPU. SEL may be NULL, which stands for an unknown constant. */
6418 can_vec_perm_p (enum machine_mode mode
, bool variable
,
6419 const unsigned char *sel
)
6421 enum machine_mode qimode
;
6423 /* If the target doesn't implement a vector mode for the vector type,
6424 then no operations are supported. */
6425 if (!VECTOR_MODE_P (mode
))
6430 if (direct_optab_handler (vec_perm_const_optab
, mode
) != CODE_FOR_nothing
6432 || targetm
.vectorize
.vec_perm_const_ok
== NULL
6433 || targetm
.vectorize
.vec_perm_const_ok (mode
, sel
)))
6437 if (direct_optab_handler (vec_perm_optab
, mode
) != CODE_FOR_nothing
)
6440 /* We allow fallback to a QI vector mode, and adjust the mask. */
6441 if (GET_MODE_INNER (mode
) == QImode
)
6443 qimode
= mode_for_vector (QImode
, GET_MODE_SIZE (mode
));
6444 if (!VECTOR_MODE_P (qimode
))
6447 /* ??? For completeness, we ought to check the QImode version of
6448 vec_perm_const_optab. But all users of this implicit lowering
6449 feature implement the variable vec_perm_optab. */
6450 if (direct_optab_handler (vec_perm_optab
, qimode
) == CODE_FOR_nothing
)
6453 /* In order to support the lowering of variable permutations,
6454 we need to support shifts and adds. */
6457 if (GET_MODE_UNIT_SIZE (mode
) > 2
6458 && optab_handler (ashl_optab
, mode
) == CODE_FOR_nothing
6459 && optab_handler (vashl_optab
, mode
) == CODE_FOR_nothing
)
6461 if (optab_handler (add_optab
, qimode
) == CODE_FOR_nothing
)
6468 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
6471 expand_vec_perm_1 (enum insn_code icode
, rtx target
,
6472 rtx v0
, rtx v1
, rtx sel
)
6474 enum machine_mode tmode
= GET_MODE (target
);
6475 enum machine_mode smode
= GET_MODE (sel
);
6476 struct expand_operand ops
[4];
6478 create_output_operand (&ops
[0], target
, tmode
);
6479 create_input_operand (&ops
[3], sel
, smode
);
6481 /* Make an effort to preserve v0 == v1. The target expander is able to
6482 rely on this to determine if we're permuting a single input operand. */
6483 if (rtx_equal_p (v0
, v1
))
6485 if (!insn_operand_matches (icode
, 1, v0
))
6486 v0
= force_reg (tmode
, v0
);
6487 gcc_checking_assert (insn_operand_matches (icode
, 1, v0
));
6488 gcc_checking_assert (insn_operand_matches (icode
, 2, v0
));
6490 create_fixed_operand (&ops
[1], v0
);
6491 create_fixed_operand (&ops
[2], v0
);
6495 create_input_operand (&ops
[1], v0
, tmode
);
6496 create_input_operand (&ops
[2], v1
, tmode
);
6499 if (maybe_expand_insn (icode
, 4, ops
))
6500 return ops
[0].value
;
6504 /* Generate instructions for vec_perm optab given its mode
6505 and three operands. */
6508 expand_vec_perm (enum machine_mode mode
, rtx v0
, rtx v1
, rtx sel
, rtx target
)
6510 enum insn_code icode
;
6511 enum machine_mode qimode
;
6512 unsigned int i
, w
, e
, u
;
6513 rtx tmp
, sel_qi
= NULL
;
6516 if (!target
|| GET_MODE (target
) != mode
)
6517 target
= gen_reg_rtx (mode
);
6519 w
= GET_MODE_SIZE (mode
);
6520 e
= GET_MODE_NUNITS (mode
);
6521 u
= GET_MODE_UNIT_SIZE (mode
);
6523 /* Set QIMODE to a different vector mode with byte elements.
6524 If no such mode, or if MODE already has byte elements, use VOIDmode. */
6526 if (GET_MODE_INNER (mode
) != QImode
)
6528 qimode
= mode_for_vector (QImode
, w
);
6529 if (!VECTOR_MODE_P (qimode
))
6533 /* If the input is a constant, expand it specially. */
6534 gcc_assert (GET_MODE_CLASS (GET_MODE (sel
)) == MODE_VECTOR_INT
);
6535 if (GET_CODE (sel
) == CONST_VECTOR
)
6537 icode
= direct_optab_handler (vec_perm_const_optab
, mode
);
6538 if (icode
!= CODE_FOR_nothing
)
6540 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
6545 /* Fall back to a constant byte-based permutation. */
6546 if (qimode
!= VOIDmode
)
6548 vec
= rtvec_alloc (w
);
6549 for (i
= 0; i
< e
; ++i
)
6551 unsigned int j
, this_e
;
6553 this_e
= INTVAL (CONST_VECTOR_ELT (sel
, i
));
6554 this_e
&= 2 * e
- 1;
6557 for (j
= 0; j
< u
; ++j
)
6558 RTVEC_ELT (vec
, i
* u
+ j
) = GEN_INT (this_e
+ j
);
6560 sel_qi
= gen_rtx_CONST_VECTOR (qimode
, vec
);
6562 icode
= direct_optab_handler (vec_perm_const_optab
, qimode
);
6563 if (icode
!= CODE_FOR_nothing
)
6565 tmp
= expand_vec_perm_1 (icode
, gen_lowpart (qimode
, target
),
6566 gen_lowpart (qimode
, v0
),
6567 gen_lowpart (qimode
, v1
), sel_qi
);
6569 return gen_lowpart (mode
, tmp
);
6574 /* Otherwise expand as a fully variable permuation. */
6575 icode
= direct_optab_handler (vec_perm_optab
, mode
);
6576 if (icode
!= CODE_FOR_nothing
)
6578 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
6583 /* As a special case to aid several targets, lower the element-based
6584 permutation to a byte-based permutation and try again. */
6585 if (qimode
== VOIDmode
)
6587 icode
= direct_optab_handler (vec_perm_optab
, qimode
);
6588 if (icode
== CODE_FOR_nothing
)
6593 /* Multiply each element by its byte size. */
6594 enum machine_mode selmode
= GET_MODE (sel
);
6596 sel
= expand_simple_binop (selmode
, PLUS
, sel
, sel
,
6597 sel
, 0, OPTAB_DIRECT
);
6599 sel
= expand_simple_binop (selmode
, ASHIFT
, sel
,
6600 GEN_INT (exact_log2 (u
)),
6601 sel
, 0, OPTAB_DIRECT
);
6602 gcc_assert (sel
!= NULL
);
6604 /* Broadcast the low byte each element into each of its bytes. */
6605 vec
= rtvec_alloc (w
);
6606 for (i
= 0; i
< w
; ++i
)
6608 int this_e
= i
/ u
* u
;
6609 if (BYTES_BIG_ENDIAN
)
6611 RTVEC_ELT (vec
, i
) = GEN_INT (this_e
);
6613 tmp
= gen_rtx_CONST_VECTOR (qimode
, vec
);
6614 sel
= gen_lowpart (qimode
, sel
);
6615 sel
= expand_vec_perm (qimode
, sel
, sel
, tmp
, NULL
);
6616 gcc_assert (sel
!= NULL
);
6618 /* Add the byte offset to each byte element. */
6619 /* Note that the definition of the indicies here is memory ordering,
6620 so there should be no difference between big and little endian. */
6621 vec
= rtvec_alloc (w
);
6622 for (i
= 0; i
< w
; ++i
)
6623 RTVEC_ELT (vec
, i
) = GEN_INT (i
% u
);
6624 tmp
= gen_rtx_CONST_VECTOR (qimode
, vec
);
6625 sel_qi
= expand_simple_binop (qimode
, PLUS
, sel
, tmp
,
6626 sel
, 0, OPTAB_DIRECT
);
6627 gcc_assert (sel_qi
!= NULL
);
6630 tmp
= expand_vec_perm_1 (icode
, gen_lowpart (qimode
, target
),
6631 gen_lowpart (qimode
, v0
),
6632 gen_lowpart (qimode
, v1
), sel_qi
);
6634 tmp
= gen_lowpart (mode
, tmp
);
6638 /* Return insn code for a conditional operator with a comparison in
6639 mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE. */
6641 static inline enum insn_code
6642 get_vcond_icode (enum machine_mode vmode
, enum machine_mode cmode
, bool uns
)
6644 enum insn_code icode
= CODE_FOR_nothing
;
6646 icode
= convert_optab_handler (vcondu_optab
, vmode
, cmode
);
6648 icode
= convert_optab_handler (vcond_optab
, vmode
, cmode
);
6652 /* Return TRUE iff, appropriate vector insns are available
6653 for vector cond expr with vector type VALUE_TYPE and a comparison
6654 with operand vector types in CMP_OP_TYPE. */
6657 expand_vec_cond_expr_p (tree value_type
, tree cmp_op_type
)
6659 enum machine_mode value_mode
= TYPE_MODE (value_type
);
6660 enum machine_mode cmp_op_mode
= TYPE_MODE (cmp_op_type
);
6661 if (GET_MODE_SIZE (value_mode
) != GET_MODE_SIZE (cmp_op_mode
)
6662 || GET_MODE_NUNITS (value_mode
) != GET_MODE_NUNITS (cmp_op_mode
)
6663 || get_vcond_icode (TYPE_MODE (value_type
), TYPE_MODE (cmp_op_type
),
6664 TYPE_UNSIGNED (cmp_op_type
)) == CODE_FOR_nothing
)
6669 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
6673 expand_vec_cond_expr (tree vec_cond_type
, tree op0
, tree op1
, tree op2
,
6676 struct expand_operand ops
[6];
6677 enum insn_code icode
;
6678 rtx comparison
, rtx_op1
, rtx_op2
;
6679 enum machine_mode mode
= TYPE_MODE (vec_cond_type
);
6680 enum machine_mode cmp_op_mode
;
6683 enum tree_code tcode
;
6685 if (COMPARISON_CLASS_P (op0
))
6687 op0a
= TREE_OPERAND (op0
, 0);
6688 op0b
= TREE_OPERAND (op0
, 1);
6689 tcode
= TREE_CODE (op0
);
6694 gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (op0
)));
6696 op0b
= build_zero_cst (TREE_TYPE (op0
));
6699 unsignedp
= TYPE_UNSIGNED (TREE_TYPE (op0a
));
6700 cmp_op_mode
= TYPE_MODE (TREE_TYPE (op0a
));
6703 gcc_assert (GET_MODE_SIZE (mode
) == GET_MODE_SIZE (cmp_op_mode
)
6704 && GET_MODE_NUNITS (mode
) == GET_MODE_NUNITS (cmp_op_mode
));
6706 icode
= get_vcond_icode (mode
, cmp_op_mode
, unsignedp
);
6707 if (icode
== CODE_FOR_nothing
)
6710 comparison
= vector_compare_rtx (tcode
, op0a
, op0b
, unsignedp
, icode
);
6711 rtx_op1
= expand_normal (op1
);
6712 rtx_op2
= expand_normal (op2
);
6714 create_output_operand (&ops
[0], target
, mode
);
6715 create_input_operand (&ops
[1], rtx_op1
, mode
);
6716 create_input_operand (&ops
[2], rtx_op2
, mode
);
6717 create_fixed_operand (&ops
[3], comparison
);
6718 create_fixed_operand (&ops
[4], XEXP (comparison
, 0));
6719 create_fixed_operand (&ops
[5], XEXP (comparison
, 1));
6720 expand_insn (icode
, 6, ops
);
6721 return ops
[0].value
;
6724 /* Return non-zero if a highpart multiply is supported of can be synthisized.
6725 For the benefit of expand_mult_highpart, the return value is 1 for direct,
6726 2 for even/odd widening, and 3 for hi/lo widening. */
6729 can_mult_highpart_p (enum machine_mode mode
, bool uns_p
)
6735 op
= uns_p
? umul_highpart_optab
: smul_highpart_optab
;
6736 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6739 /* If the mode is an integral vector, synth from widening operations. */
6740 if (GET_MODE_CLASS (mode
) != MODE_VECTOR_INT
)
6743 nunits
= GET_MODE_NUNITS (mode
);
6744 sel
= XALLOCAVEC (unsigned char, nunits
);
6746 op
= uns_p
? vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
6747 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6749 op
= uns_p
? vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
6750 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6752 for (i
= 0; i
< nunits
; ++i
)
6753 sel
[i
] = !BYTES_BIG_ENDIAN
+ (i
& ~1) + ((i
& 1) ? nunits
: 0);
6754 if (can_vec_perm_p (mode
, false, sel
))
6759 op
= uns_p
? vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
6760 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6762 op
= uns_p
? vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
6763 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6765 for (i
= 0; i
< nunits
; ++i
)
6766 sel
[i
] = 2 * i
+ (BYTES_BIG_ENDIAN
? 0 : 1);
6767 if (can_vec_perm_p (mode
, false, sel
))
6775 /* Expand a highpart multiply. */
6778 expand_mult_highpart (enum machine_mode mode
, rtx op0
, rtx op1
,
6779 rtx target
, bool uns_p
)
6781 struct expand_operand eops
[3];
6782 enum insn_code icode
;
6783 int method
, i
, nunits
;
6784 enum machine_mode wmode
;
6789 method
= can_mult_highpart_p (mode
, uns_p
);
6795 tab1
= uns_p
? umul_highpart_optab
: smul_highpart_optab
;
6796 return expand_binop (mode
, tab1
, op0
, op1
, target
, uns_p
,
6799 tab1
= uns_p
? vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
6800 tab2
= uns_p
? vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
6803 tab1
= uns_p
? vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
6804 tab2
= uns_p
? vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
6805 if (BYTES_BIG_ENDIAN
)
6816 icode
= optab_handler (tab1
, mode
);
6817 nunits
= GET_MODE_NUNITS (mode
);
6818 wmode
= insn_data
[icode
].operand
[0].mode
;
6819 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode
) == nunits
);
6820 gcc_checking_assert (GET_MODE_SIZE (wmode
) == GET_MODE_SIZE (mode
));
6822 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
6823 create_input_operand (&eops
[1], op0
, mode
);
6824 create_input_operand (&eops
[2], op1
, mode
);
6825 expand_insn (icode
, 3, eops
);
6826 m1
= gen_lowpart (mode
, eops
[0].value
);
6828 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
6829 create_input_operand (&eops
[1], op0
, mode
);
6830 create_input_operand (&eops
[2], op1
, mode
);
6831 expand_insn (optab_handler (tab2
, mode
), 3, eops
);
6832 m2
= gen_lowpart (mode
, eops
[0].value
);
6834 v
= rtvec_alloc (nunits
);
6837 for (i
= 0; i
< nunits
; ++i
)
6838 RTVEC_ELT (v
, i
) = GEN_INT (!BYTES_BIG_ENDIAN
+ (i
& ~1)
6839 + ((i
& 1) ? nunits
: 0));
6843 for (i
= 0; i
< nunits
; ++i
)
6844 RTVEC_ELT (v
, i
) = GEN_INT (2 * i
+ (BYTES_BIG_ENDIAN
? 0 : 1));
6846 perm
= gen_rtx_CONST_VECTOR (mode
, v
);
6848 return expand_vec_perm (mode
, m1
, m2
, perm
, target
);
6851 /* Return true if there is a compare_and_swap pattern. */
6854 can_compare_and_swap_p (enum machine_mode mode
, bool allow_libcall
)
6856 enum insn_code icode
;
6858 /* Check for __atomic_compare_and_swap. */
6859 icode
= direct_optab_handler (atomic_compare_and_swap_optab
, mode
);
6860 if (icode
!= CODE_FOR_nothing
)
6863 /* Check for __sync_compare_and_swap. */
6864 icode
= optab_handler (sync_compare_and_swap_optab
, mode
);
6865 if (icode
!= CODE_FOR_nothing
)
6867 if (allow_libcall
&& optab_libfunc (sync_compare_and_swap_optab
, mode
))
6870 /* No inline compare and swap. */
6874 /* Return true if an atomic exchange can be performed. */
6877 can_atomic_exchange_p (enum machine_mode mode
, bool allow_libcall
)
6879 enum insn_code icode
;
6881 /* Check for __atomic_exchange. */
6882 icode
= direct_optab_handler (atomic_exchange_optab
, mode
);
6883 if (icode
!= CODE_FOR_nothing
)
6886 /* Don't check __sync_test_and_set, as on some platforms that
6887 has reduced functionality. Targets that really do support
6888 a proper exchange should simply be updated to the __atomics. */
6890 return can_compare_and_swap_p (mode
, allow_libcall
);
6894 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
6898 find_cc_set (rtx x
, const_rtx pat
, void *data
)
6900 if (REG_P (x
) && GET_MODE_CLASS (GET_MODE (x
)) == MODE_CC
6901 && GET_CODE (pat
) == SET
)
6903 rtx
*p_cc_reg
= (rtx
*) data
;
6904 gcc_assert (!*p_cc_reg
);
6909 /* This is a helper function for the other atomic operations. This function
6910 emits a loop that contains SEQ that iterates until a compare-and-swap
6911 operation at the end succeeds. MEM is the memory to be modified. SEQ is
6912 a set of instructions that takes a value from OLD_REG as an input and
6913 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
6914 set to the current contents of MEM. After SEQ, a compare-and-swap will
6915 attempt to update MEM with NEW_REG. The function returns true when the
6916 loop was generated successfully. */
6919 expand_compare_and_swap_loop (rtx mem
, rtx old_reg
, rtx new_reg
, rtx seq
)
6921 enum machine_mode mode
= GET_MODE (mem
);
6922 rtx label
, cmp_reg
, success
, oldval
;
6924 /* The loop we want to generate looks like
6930 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
6934 Note that we only do the plain load from memory once. Subsequent
6935 iterations use the value loaded by the compare-and-swap pattern. */
6937 label
= gen_label_rtx ();
6938 cmp_reg
= gen_reg_rtx (mode
);
6940 emit_move_insn (cmp_reg
, mem
);
6942 emit_move_insn (old_reg
, cmp_reg
);
6948 if (!expand_atomic_compare_and_swap (&success
, &oldval
, mem
, old_reg
,
6949 new_reg
, false, MEMMODEL_SEQ_CST
,
6953 if (oldval
!= cmp_reg
)
6954 emit_move_insn (cmp_reg
, oldval
);
6956 /* Mark this jump predicted not taken. */
6957 emit_cmp_and_jump_insns (success
, const0_rtx
, EQ
, const0_rtx
,
6958 GET_MODE (success
), 1, label
, 0);
6963 /* This function tries to emit an atomic_exchange intruction. VAL is written
6964 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
6965 using TARGET if possible. */
6968 maybe_emit_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
6970 enum machine_mode mode
= GET_MODE (mem
);
6971 enum insn_code icode
;
6973 /* If the target supports the exchange directly, great. */
6974 icode
= direct_optab_handler (atomic_exchange_optab
, mode
);
6975 if (icode
!= CODE_FOR_nothing
)
6977 struct expand_operand ops
[4];
6979 create_output_operand (&ops
[0], target
, mode
);
6980 create_fixed_operand (&ops
[1], mem
);
6981 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6982 create_convert_operand_to (&ops
[2], val
, mode
, true);
6983 create_integer_operand (&ops
[3], model
);
6984 if (maybe_expand_insn (icode
, 4, ops
))
6985 return ops
[0].value
;
6991 /* This function tries to implement an atomic exchange operation using
6992 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
6993 The previous contents of *MEM are returned, using TARGET if possible.
6994 Since this instructionn is an acquire barrier only, stronger memory
6995 models may require additional barriers to be emitted. */
6998 maybe_emit_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
,
6999 enum memmodel model
)
7001 enum machine_mode mode
= GET_MODE (mem
);
7002 enum insn_code icode
;
7003 rtx last_insn
= get_last_insn ();
7005 icode
= optab_handler (sync_lock_test_and_set_optab
, mode
);
7007 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
7008 exists, and the memory model is stronger than acquire, add a release
7009 barrier before the instruction. */
7011 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
7012 || (model
& MEMMODEL_MASK
) == MEMMODEL_RELEASE
7013 || (model
& MEMMODEL_MASK
) == MEMMODEL_ACQ_REL
)
7014 expand_mem_thread_fence (model
);
7016 if (icode
!= CODE_FOR_nothing
)
7018 struct expand_operand ops
[3];
7019 create_output_operand (&ops
[0], target
, mode
);
7020 create_fixed_operand (&ops
[1], mem
);
7021 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7022 create_convert_operand_to (&ops
[2], val
, mode
, true);
7023 if (maybe_expand_insn (icode
, 3, ops
))
7024 return ops
[0].value
;
7027 /* If an external test-and-set libcall is provided, use that instead of
7028 any external compare-and-swap that we might get from the compare-and-
7029 swap-loop expansion later. */
7030 if (!can_compare_and_swap_p (mode
, false))
7032 rtx libfunc
= optab_libfunc (sync_lock_test_and_set_optab
, mode
);
7033 if (libfunc
!= NULL
)
7037 addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
7038 return emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
7039 mode
, 2, addr
, ptr_mode
,
7044 /* If the test_and_set can't be emitted, eliminate any barrier that might
7045 have been emitted. */
7046 delete_insns_since (last_insn
);
7050 /* This function tries to implement an atomic exchange operation using a
7051 compare_and_swap loop. VAL is written to *MEM. The previous contents of
7052 *MEM are returned, using TARGET if possible. No memory model is required
7053 since a compare_and_swap loop is seq-cst. */
7056 maybe_emit_compare_and_swap_exchange_loop (rtx target
, rtx mem
, rtx val
)
7058 enum machine_mode mode
= GET_MODE (mem
);
7060 if (can_compare_and_swap_p (mode
, true))
7062 if (!target
|| !register_operand (target
, mode
))
7063 target
= gen_reg_rtx (mode
);
7064 if (GET_MODE (val
) != VOIDmode
&& GET_MODE (val
) != mode
)
7065 val
= convert_modes (mode
, GET_MODE (val
), val
, 1);
7066 if (expand_compare_and_swap_loop (mem
, target
, val
, NULL_RTX
))
7073 /* This function tries to implement an atomic test-and-set operation
7074 using the atomic_test_and_set instruction pattern. A boolean value
7075 is returned from the operation, using TARGET if possible. */
7077 #ifndef HAVE_atomic_test_and_set
7078 #define HAVE_atomic_test_and_set 0
7079 #define CODE_FOR_atomic_test_and_set CODE_FOR_nothing
7083 maybe_emit_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
7085 enum machine_mode pat_bool_mode
;
7086 struct expand_operand ops
[3];
7088 if (!HAVE_atomic_test_and_set
)
7091 /* While we always get QImode from __atomic_test_and_set, we get
7092 other memory modes from __sync_lock_test_and_set. Note that we
7093 use no endian adjustment here. This matches the 4.6 behavior
7094 in the Sparc backend. */
7096 (insn_data
[CODE_FOR_atomic_test_and_set
].operand
[1].mode
== QImode
);
7097 if (GET_MODE (mem
) != QImode
)
7098 mem
= adjust_address_nv (mem
, QImode
, 0);
7100 pat_bool_mode
= insn_data
[CODE_FOR_atomic_test_and_set
].operand
[0].mode
;
7101 create_output_operand (&ops
[0], target
, pat_bool_mode
);
7102 create_fixed_operand (&ops
[1], mem
);
7103 create_integer_operand (&ops
[2], model
);
7105 if (maybe_expand_insn (CODE_FOR_atomic_test_and_set
, 3, ops
))
7106 return ops
[0].value
;
7110 /* This function expands the legacy _sync_lock test_and_set operation which is
7111 generally an atomic exchange. Some limited targets only allow the
7112 constant 1 to be stored. This is an ACQUIRE operation.
7114 TARGET is an optional place to stick the return value.
7115 MEM is where VAL is stored. */
7118 expand_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
)
7122 /* Try an atomic_exchange first. */
7123 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, MEMMODEL_ACQUIRE
);
7127 ret
= maybe_emit_sync_lock_test_and_set (target
, mem
, val
, MEMMODEL_ACQUIRE
);
7131 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
7135 /* If there are no other options, try atomic_test_and_set if the value
7136 being stored is 1. */
7137 if (val
== const1_rtx
)
7138 ret
= maybe_emit_atomic_test_and_set (target
, mem
, MEMMODEL_ACQUIRE
);
7143 /* This function expands the atomic test_and_set operation:
7144 atomically store a boolean TRUE into MEM and return the previous value.
7146 MEMMODEL is the memory model variant to use.
7147 TARGET is an optional place to stick the return value. */
7150 expand_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
7152 enum machine_mode mode
= GET_MODE (mem
);
7153 rtx ret
, trueval
, subtarget
;
7155 ret
= maybe_emit_atomic_test_and_set (target
, mem
, model
);
7159 /* Be binary compatible with non-default settings of trueval, and different
7160 cpu revisions. E.g. one revision may have atomic-test-and-set, but
7161 another only has atomic-exchange. */
7162 if (targetm
.atomic_test_and_set_trueval
== 1)
7164 trueval
= const1_rtx
;
7165 subtarget
= target
? target
: gen_reg_rtx (mode
);
7169 trueval
= gen_int_mode (targetm
.atomic_test_and_set_trueval
, mode
);
7170 subtarget
= gen_reg_rtx (mode
);
7173 /* Try the atomic-exchange optab... */
7174 ret
= maybe_emit_atomic_exchange (subtarget
, mem
, trueval
, model
);
7176 /* ... then an atomic-compare-and-swap loop ... */
7178 ret
= maybe_emit_compare_and_swap_exchange_loop (subtarget
, mem
, trueval
);
7180 /* ... before trying the vaguely defined legacy lock_test_and_set. */
7182 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, trueval
, model
);
7184 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
7185 things with the value 1. Thus we try again without trueval. */
7186 if (!ret
&& targetm
.atomic_test_and_set_trueval
!= 1)
7187 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, const1_rtx
, model
);
7189 /* Failing all else, assume a single threaded environment and simply
7190 perform the operation. */
7193 emit_move_insn (subtarget
, mem
);
7194 emit_move_insn (mem
, trueval
);
7198 /* Recall that have to return a boolean value; rectify if trueval
7199 is not exactly one. */
7200 if (targetm
.atomic_test_and_set_trueval
!= 1)
7201 ret
= emit_store_flag_force (target
, NE
, ret
, const0_rtx
, mode
, 0, 1);
7206 /* This function expands the atomic exchange operation:
7207 atomically store VAL in MEM and return the previous value in MEM.
7209 MEMMODEL is the memory model variant to use.
7210 TARGET is an optional place to stick the return value. */
7213 expand_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
7217 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, model
);
7219 /* Next try a compare-and-swap loop for the exchange. */
7221 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
7226 /* This function expands the atomic compare exchange operation:
7228 *PTARGET_BOOL is an optional place to store the boolean success/failure.
7229 *PTARGET_OVAL is an optional place to store the old value from memory.
7230 Both target parameters may be NULL to indicate that we do not care about
7231 that return value. Both target parameters are updated on success to
7232 the actual location of the corresponding result.
7234 MEMMODEL is the memory model variant to use.
7236 The return value of the function is true for success. */
7239 expand_atomic_compare_and_swap (rtx
*ptarget_bool
, rtx
*ptarget_oval
,
7240 rtx mem
, rtx expected
, rtx desired
,
7241 bool is_weak
, enum memmodel succ_model
,
7242 enum memmodel fail_model
)
7244 enum machine_mode mode
= GET_MODE (mem
);
7245 struct expand_operand ops
[8];
7246 enum insn_code icode
;
7247 rtx target_oval
, target_bool
= NULL_RTX
;
7250 /* Load expected into a register for the compare and swap. */
7251 if (MEM_P (expected
))
7252 expected
= copy_to_reg (expected
);
7254 /* Make sure we always have some place to put the return oldval.
7255 Further, make sure that place is distinct from the input expected,
7256 just in case we need that path down below. */
7257 if (ptarget_oval
== NULL
7258 || (target_oval
= *ptarget_oval
) == NULL
7259 || reg_overlap_mentioned_p (expected
, target_oval
))
7260 target_oval
= gen_reg_rtx (mode
);
7262 icode
= direct_optab_handler (atomic_compare_and_swap_optab
, mode
);
7263 if (icode
!= CODE_FOR_nothing
)
7265 enum machine_mode bool_mode
= insn_data
[icode
].operand
[0].mode
;
7267 /* Make sure we always have a place for the bool operand. */
7268 if (ptarget_bool
== NULL
7269 || (target_bool
= *ptarget_bool
) == NULL
7270 || GET_MODE (target_bool
) != bool_mode
)
7271 target_bool
= gen_reg_rtx (bool_mode
);
7273 /* Emit the compare_and_swap. */
7274 create_output_operand (&ops
[0], target_bool
, bool_mode
);
7275 create_output_operand (&ops
[1], target_oval
, mode
);
7276 create_fixed_operand (&ops
[2], mem
);
7277 create_convert_operand_to (&ops
[3], expected
, mode
, true);
7278 create_convert_operand_to (&ops
[4], desired
, mode
, true);
7279 create_integer_operand (&ops
[5], is_weak
);
7280 create_integer_operand (&ops
[6], succ_model
);
7281 create_integer_operand (&ops
[7], fail_model
);
7282 expand_insn (icode
, 8, ops
);
7284 /* Return success/failure. */
7285 target_bool
= ops
[0].value
;
7286 target_oval
= ops
[1].value
;
7290 /* Otherwise fall back to the original __sync_val_compare_and_swap
7291 which is always seq-cst. */
7292 icode
= optab_handler (sync_compare_and_swap_optab
, mode
);
7293 if (icode
!= CODE_FOR_nothing
)
7297 create_output_operand (&ops
[0], target_oval
, mode
);
7298 create_fixed_operand (&ops
[1], mem
);
7299 create_convert_operand_to (&ops
[2], expected
, mode
, true);
7300 create_convert_operand_to (&ops
[3], desired
, mode
, true);
7301 if (!maybe_expand_insn (icode
, 4, ops
))
7304 target_oval
= ops
[0].value
;
7306 /* If the caller isn't interested in the boolean return value,
7307 skip the computation of it. */
7308 if (ptarget_bool
== NULL
)
7311 /* Otherwise, work out if the compare-and-swap succeeded. */
7313 if (have_insn_for (COMPARE
, CCmode
))
7314 note_stores (PATTERN (get_last_insn ()), find_cc_set
, &cc_reg
);
7317 target_bool
= emit_store_flag_force (target_bool
, EQ
, cc_reg
,
7318 const0_rtx
, VOIDmode
, 0, 1);
7321 goto success_bool_from_val
;
7324 /* Also check for library support for __sync_val_compare_and_swap. */
7325 libfunc
= optab_libfunc (sync_compare_and_swap_optab
, mode
);
7326 if (libfunc
!= NULL
)
7328 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
7329 target_oval
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
7330 mode
, 3, addr
, ptr_mode
,
7331 expected
, mode
, desired
, mode
);
7333 /* Compute the boolean return value only if requested. */
7335 goto success_bool_from_val
;
7343 success_bool_from_val
:
7344 target_bool
= emit_store_flag_force (target_bool
, EQ
, target_oval
,
7345 expected
, VOIDmode
, 1, 1);
7347 /* Make sure that the oval output winds up where the caller asked. */
7349 *ptarget_oval
= target_oval
;
7351 *ptarget_bool
= target_bool
;
7355 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
7358 expand_asm_memory_barrier (void)
7362 asm_op
= gen_rtx_ASM_OPERANDS (VOIDmode
, empty_string
, empty_string
, 0,
7363 rtvec_alloc (0), rtvec_alloc (0),
7364 rtvec_alloc (0), UNKNOWN_LOCATION
);
7365 MEM_VOLATILE_P (asm_op
) = 1;
7367 clob
= gen_rtx_SCRATCH (VOIDmode
);
7368 clob
= gen_rtx_MEM (BLKmode
, clob
);
7369 clob
= gen_rtx_CLOBBER (VOIDmode
, clob
);
7371 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, asm_op
, clob
)));
7374 /* This routine will either emit the mem_thread_fence pattern or issue a
7375 sync_synchronize to generate a fence for memory model MEMMODEL. */
7377 #ifndef HAVE_mem_thread_fence
7378 # define HAVE_mem_thread_fence 0
7379 # define gen_mem_thread_fence(x) (gcc_unreachable (), NULL_RTX)
7381 #ifndef HAVE_memory_barrier
7382 # define HAVE_memory_barrier 0
7383 # define gen_memory_barrier() (gcc_unreachable (), NULL_RTX)
7387 expand_mem_thread_fence (enum memmodel model
)
7389 if (HAVE_mem_thread_fence
)
7390 emit_insn (gen_mem_thread_fence (GEN_INT (model
)));
7391 else if ((model
& MEMMODEL_MASK
) != MEMMODEL_RELAXED
)
7393 if (HAVE_memory_barrier
)
7394 emit_insn (gen_memory_barrier ());
7395 else if (synchronize_libfunc
!= NULL_RTX
)
7396 emit_library_call (synchronize_libfunc
, LCT_NORMAL
, VOIDmode
, 0);
7398 expand_asm_memory_barrier ();
7402 /* This routine will either emit the mem_signal_fence pattern or issue a
7403 sync_synchronize to generate a fence for memory model MEMMODEL. */
7405 #ifndef HAVE_mem_signal_fence
7406 # define HAVE_mem_signal_fence 0
7407 # define gen_mem_signal_fence(x) (gcc_unreachable (), NULL_RTX)
7411 expand_mem_signal_fence (enum memmodel model
)
7413 if (HAVE_mem_signal_fence
)
7414 emit_insn (gen_mem_signal_fence (GEN_INT (model
)));
7415 else if ((model
& MEMMODEL_MASK
) != MEMMODEL_RELAXED
)
7417 /* By default targets are coherent between a thread and the signal
7418 handler running on the same thread. Thus this really becomes a
7419 compiler barrier, in that stores must not be sunk past
7420 (or raised above) a given point. */
7421 expand_asm_memory_barrier ();
7425 /* This function expands the atomic load operation:
7426 return the atomically loaded value in MEM.
7428 MEMMODEL is the memory model variant to use.
7429 TARGET is an option place to stick the return value. */
7432 expand_atomic_load (rtx target
, rtx mem
, enum memmodel model
)
7434 enum machine_mode mode
= GET_MODE (mem
);
7435 enum insn_code icode
;
7437 /* If the target supports the load directly, great. */
7438 icode
= direct_optab_handler (atomic_load_optab
, mode
);
7439 if (icode
!= CODE_FOR_nothing
)
7441 struct expand_operand ops
[3];
7443 create_output_operand (&ops
[0], target
, mode
);
7444 create_fixed_operand (&ops
[1], mem
);
7445 create_integer_operand (&ops
[2], model
);
7446 if (maybe_expand_insn (icode
, 3, ops
))
7447 return ops
[0].value
;
7450 /* If the size of the object is greater than word size on this target,
7451 then we assume that a load will not be atomic. */
7452 if (GET_MODE_PRECISION (mode
) > BITS_PER_WORD
)
7454 /* Issue val = compare_and_swap (mem, 0, 0).
7455 This may cause the occasional harmless store of 0 when the value is
7456 already 0, but it seems to be OK according to the standards guys. */
7457 if (expand_atomic_compare_and_swap (NULL
, &target
, mem
, const0_rtx
,
7458 const0_rtx
, false, model
, model
))
7461 /* Otherwise there is no atomic load, leave the library call. */
7465 /* Otherwise assume loads are atomic, and emit the proper barriers. */
7466 if (!target
|| target
== const0_rtx
)
7467 target
= gen_reg_rtx (mode
);
7469 /* For SEQ_CST, emit a barrier before the load. */
7470 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
)
7471 expand_mem_thread_fence (model
);
7473 emit_move_insn (target
, mem
);
7475 /* Emit the appropriate barrier after the load. */
7476 expand_mem_thread_fence (model
);
7481 /* This function expands the atomic store operation:
7482 Atomically store VAL in MEM.
7483 MEMMODEL is the memory model variant to use.
7484 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
7485 function returns const0_rtx if a pattern was emitted. */
7488 expand_atomic_store (rtx mem
, rtx val
, enum memmodel model
, bool use_release
)
7490 enum machine_mode mode
= GET_MODE (mem
);
7491 enum insn_code icode
;
7492 struct expand_operand ops
[3];
7494 /* If the target supports the store directly, great. */
7495 icode
= direct_optab_handler (atomic_store_optab
, mode
);
7496 if (icode
!= CODE_FOR_nothing
)
7498 create_fixed_operand (&ops
[0], mem
);
7499 create_input_operand (&ops
[1], val
, mode
);
7500 create_integer_operand (&ops
[2], model
);
7501 if (maybe_expand_insn (icode
, 3, ops
))
7505 /* If using __sync_lock_release is a viable alternative, try it. */
7508 icode
= direct_optab_handler (sync_lock_release_optab
, mode
);
7509 if (icode
!= CODE_FOR_nothing
)
7511 create_fixed_operand (&ops
[0], mem
);
7512 create_input_operand (&ops
[1], const0_rtx
, mode
);
7513 if (maybe_expand_insn (icode
, 2, ops
))
7515 /* lock_release is only a release barrier. */
7516 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
)
7517 expand_mem_thread_fence (model
);
7523 /* If the size of the object is greater than word size on this target,
7524 a default store will not be atomic, Try a mem_exchange and throw away
7525 the result. If that doesn't work, don't do anything. */
7526 if (GET_MODE_PRECISION(mode
) > BITS_PER_WORD
)
7528 rtx target
= maybe_emit_atomic_exchange (NULL_RTX
, mem
, val
, model
);
7530 target
= maybe_emit_compare_and_swap_exchange_loop (NULL_RTX
, mem
, val
);
7537 /* Otherwise assume stores are atomic, and emit the proper barriers. */
7538 expand_mem_thread_fence (model
);
7540 emit_move_insn (mem
, val
);
7542 /* For SEQ_CST, also emit a barrier after the store. */
7543 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
)
7544 expand_mem_thread_fence (model
);
7550 /* Structure containing the pointers and values required to process the
7551 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
7553 struct atomic_op_functions
7555 direct_optab mem_fetch_before
;
7556 direct_optab mem_fetch_after
;
7557 direct_optab mem_no_result
;
7560 direct_optab no_result
;
7561 enum rtx_code reverse_code
;
7565 /* Fill in structure pointed to by OP with the various optab entries for an
7566 operation of type CODE. */
7569 get_atomic_op_for_code (struct atomic_op_functions
*op
, enum rtx_code code
)
7571 gcc_assert (op
!= NULL
);
7573 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
7574 in the source code during compilation, and the optab entries are not
7575 computable until runtime. Fill in the values at runtime. */
7579 op
->mem_fetch_before
= atomic_fetch_add_optab
;
7580 op
->mem_fetch_after
= atomic_add_fetch_optab
;
7581 op
->mem_no_result
= atomic_add_optab
;
7582 op
->fetch_before
= sync_old_add_optab
;
7583 op
->fetch_after
= sync_new_add_optab
;
7584 op
->no_result
= sync_add_optab
;
7585 op
->reverse_code
= MINUS
;
7588 op
->mem_fetch_before
= atomic_fetch_sub_optab
;
7589 op
->mem_fetch_after
= atomic_sub_fetch_optab
;
7590 op
->mem_no_result
= atomic_sub_optab
;
7591 op
->fetch_before
= sync_old_sub_optab
;
7592 op
->fetch_after
= sync_new_sub_optab
;
7593 op
->no_result
= sync_sub_optab
;
7594 op
->reverse_code
= PLUS
;
7597 op
->mem_fetch_before
= atomic_fetch_xor_optab
;
7598 op
->mem_fetch_after
= atomic_xor_fetch_optab
;
7599 op
->mem_no_result
= atomic_xor_optab
;
7600 op
->fetch_before
= sync_old_xor_optab
;
7601 op
->fetch_after
= sync_new_xor_optab
;
7602 op
->no_result
= sync_xor_optab
;
7603 op
->reverse_code
= XOR
;
7606 op
->mem_fetch_before
= atomic_fetch_and_optab
;
7607 op
->mem_fetch_after
= atomic_and_fetch_optab
;
7608 op
->mem_no_result
= atomic_and_optab
;
7609 op
->fetch_before
= sync_old_and_optab
;
7610 op
->fetch_after
= sync_new_and_optab
;
7611 op
->no_result
= sync_and_optab
;
7612 op
->reverse_code
= UNKNOWN
;
7615 op
->mem_fetch_before
= atomic_fetch_or_optab
;
7616 op
->mem_fetch_after
= atomic_or_fetch_optab
;
7617 op
->mem_no_result
= atomic_or_optab
;
7618 op
->fetch_before
= sync_old_ior_optab
;
7619 op
->fetch_after
= sync_new_ior_optab
;
7620 op
->no_result
= sync_ior_optab
;
7621 op
->reverse_code
= UNKNOWN
;
7624 op
->mem_fetch_before
= atomic_fetch_nand_optab
;
7625 op
->mem_fetch_after
= atomic_nand_fetch_optab
;
7626 op
->mem_no_result
= atomic_nand_optab
;
7627 op
->fetch_before
= sync_old_nand_optab
;
7628 op
->fetch_after
= sync_new_nand_optab
;
7629 op
->no_result
= sync_nand_optab
;
7630 op
->reverse_code
= UNKNOWN
;
7637 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
7638 using memory order MODEL. If AFTER is true the operation needs to return
7639 the value of *MEM after the operation, otherwise the previous value.
7640 TARGET is an optional place to place the result. The result is unused if
7642 Return the result if there is a better sequence, otherwise NULL_RTX. */
7645 maybe_optimize_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
7646 enum memmodel model
, bool after
)
7648 /* If the value is prefetched, or not used, it may be possible to replace
7649 the sequence with a native exchange operation. */
7650 if (!after
|| target
== const0_rtx
)
7652 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
7653 if (code
== AND
&& val
== const0_rtx
)
7655 if (target
== const0_rtx
)
7656 target
= gen_reg_rtx (GET_MODE (mem
));
7657 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
7660 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
7661 if (code
== IOR
&& val
== constm1_rtx
)
7663 if (target
== const0_rtx
)
7664 target
= gen_reg_rtx (GET_MODE (mem
));
7665 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
7672 /* Try to emit an instruction for a specific operation varaition.
7673 OPTAB contains the OP functions.
7674 TARGET is an optional place to return the result. const0_rtx means unused.
7675 MEM is the memory location to operate on.
7676 VAL is the value to use in the operation.
7677 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
7678 MODEL is the memory model, if used.
7679 AFTER is true if the returned result is the value after the operation. */
7682 maybe_emit_op (const struct atomic_op_functions
*optab
, rtx target
, rtx mem
,
7683 rtx val
, bool use_memmodel
, enum memmodel model
, bool after
)
7685 enum machine_mode mode
= GET_MODE (mem
);
7686 struct expand_operand ops
[4];
7687 enum insn_code icode
;
7691 /* Check to see if there is a result returned. */
7692 if (target
== const0_rtx
)
7696 icode
= direct_optab_handler (optab
->mem_no_result
, mode
);
7697 create_integer_operand (&ops
[2], model
);
7702 icode
= direct_optab_handler (optab
->no_result
, mode
);
7706 /* Otherwise, we need to generate a result. */
7711 icode
= direct_optab_handler (after
? optab
->mem_fetch_after
7712 : optab
->mem_fetch_before
, mode
);
7713 create_integer_operand (&ops
[3], model
);
7718 icode
= optab_handler (after
? optab
->fetch_after
7719 : optab
->fetch_before
, mode
);
7722 create_output_operand (&ops
[op_counter
++], target
, mode
);
7724 if (icode
== CODE_FOR_nothing
)
7727 create_fixed_operand (&ops
[op_counter
++], mem
);
7728 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7729 create_convert_operand_to (&ops
[op_counter
++], val
, mode
, true);
7731 if (maybe_expand_insn (icode
, num_ops
, ops
))
7732 return (target
== const0_rtx
? const0_rtx
: ops
[0].value
);
7738 /* This function expands an atomic fetch_OP or OP_fetch operation:
7739 TARGET is an option place to stick the return value. const0_rtx indicates
7740 the result is unused.
7741 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7742 CODE is the operation being performed (OP)
7743 MEMMODEL is the memory model variant to use.
7744 AFTER is true to return the result of the operation (OP_fetch).
7745 AFTER is false to return the value before the operation (fetch_OP).
7747 This function will *only* generate instructions if there is a direct
7748 optab. No compare and swap loops or libcalls will be generated. */
7751 expand_atomic_fetch_op_no_fallback (rtx target
, rtx mem
, rtx val
,
7752 enum rtx_code code
, enum memmodel model
,
7755 enum machine_mode mode
= GET_MODE (mem
);
7756 struct atomic_op_functions optab
;
7758 bool unused_result
= (target
== const0_rtx
);
7760 get_atomic_op_for_code (&optab
, code
);
7762 /* Check to see if there are any better instructions. */
7763 result
= maybe_optimize_fetch_op (target
, mem
, val
, code
, model
, after
);
7767 /* Check for the case where the result isn't used and try those patterns. */
7770 /* Try the memory model variant first. */
7771 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, true);
7775 /* Next try the old style withuot a memory model. */
7776 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, true);
7780 /* There is no no-result pattern, so try patterns with a result. */
7784 /* Try the __atomic version. */
7785 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, after
);
7789 /* Try the older __sync version. */
7790 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, after
);
7794 /* If the fetch value can be calculated from the other variation of fetch,
7795 try that operation. */
7796 if (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
)
7798 /* Try the __atomic version, then the older __sync version. */
7799 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, !after
);
7801 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, !after
);
7805 /* If the result isn't used, no need to do compensation code. */
7809 /* Issue compensation code. Fetch_after == fetch_before OP val.
7810 Fetch_before == after REVERSE_OP val. */
7812 code
= optab
.reverse_code
;
7815 result
= expand_simple_binop (mode
, AND
, result
, val
, NULL_RTX
,
7816 true, OPTAB_LIB_WIDEN
);
7817 result
= expand_simple_unop (mode
, NOT
, result
, target
, true);
7820 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
7821 true, OPTAB_LIB_WIDEN
);
7826 /* No direct opcode can be generated. */
7832 /* This function expands an atomic fetch_OP or OP_fetch operation:
7833 TARGET is an option place to stick the return value. const0_rtx indicates
7834 the result is unused.
7835 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7836 CODE is the operation being performed (OP)
7837 MEMMODEL is the memory model variant to use.
7838 AFTER is true to return the result of the operation (OP_fetch).
7839 AFTER is false to return the value before the operation (fetch_OP). */
7841 expand_atomic_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
7842 enum memmodel model
, bool after
)
7844 enum machine_mode mode
= GET_MODE (mem
);
7846 bool unused_result
= (target
== const0_rtx
);
7848 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, val
, code
, model
,
7854 /* Add/sub can be implemented by doing the reverse operation with -(val). */
7855 if (code
== PLUS
|| code
== MINUS
)
7858 enum rtx_code reverse
= (code
== PLUS
? MINUS
: PLUS
);
7861 tmp
= expand_simple_unop (mode
, NEG
, val
, NULL_RTX
, true);
7862 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, tmp
, reverse
,
7866 /* PLUS worked so emit the insns and return. */
7873 /* PLUS did not work, so throw away the negation code and continue. */
7877 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
7878 if (!can_compare_and_swap_p (mode
, false))
7882 enum rtx_code orig_code
= code
;
7883 struct atomic_op_functions optab
;
7885 get_atomic_op_for_code (&optab
, code
);
7886 libfunc
= optab_libfunc (after
? optab
.fetch_after
7887 : optab
.fetch_before
, mode
);
7889 && (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
))
7893 code
= optab
.reverse_code
;
7894 libfunc
= optab_libfunc (after
? optab
.fetch_before
7895 : optab
.fetch_after
, mode
);
7897 if (libfunc
!= NULL
)
7899 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
7900 result
= emit_library_call_value (libfunc
, NULL
, LCT_NORMAL
, mode
,
7901 2, addr
, ptr_mode
, val
, mode
);
7903 if (!unused_result
&& fixup
)
7904 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
7905 true, OPTAB_LIB_WIDEN
);
7909 /* We need the original code for any further attempts. */
7913 /* If nothing else has succeeded, default to a compare and swap loop. */
7914 if (can_compare_and_swap_p (mode
, true))
7917 rtx t0
= gen_reg_rtx (mode
), t1
;
7921 /* If the result is used, get a register for it. */
7924 if (!target
|| !register_operand (target
, mode
))
7925 target
= gen_reg_rtx (mode
);
7926 /* If fetch_before, copy the value now. */
7928 emit_move_insn (target
, t0
);
7931 target
= const0_rtx
;
7936 t1
= expand_simple_binop (mode
, AND
, t1
, val
, NULL_RTX
,
7937 true, OPTAB_LIB_WIDEN
);
7938 t1
= expand_simple_unop (mode
, code
, t1
, NULL_RTX
, true);
7941 t1
= expand_simple_binop (mode
, code
, t1
, val
, NULL_RTX
, true,
7944 /* For after, copy the value now. */
7945 if (!unused_result
&& after
)
7946 emit_move_insn (target
, t1
);
7947 insn
= get_insns ();
7950 if (t1
!= NULL
&& expand_compare_and_swap_loop (mem
, t0
, t1
, insn
))
7957 /* Return true if OPERAND is suitable for operand number OPNO of
7958 instruction ICODE. */
7961 insn_operand_matches (enum insn_code icode
, unsigned int opno
, rtx operand
)
7963 return (!insn_data
[(int) icode
].operand
[opno
].predicate
7964 || (insn_data
[(int) icode
].operand
[opno
].predicate
7965 (operand
, insn_data
[(int) icode
].operand
[opno
].mode
)));
7968 /* TARGET is a target of a multiword operation that we are going to
7969 implement as a series of word-mode operations. Return true if
7970 TARGET is suitable for this purpose. */
7973 valid_multiword_target_p (rtx target
)
7975 enum machine_mode mode
;
7978 mode
= GET_MODE (target
);
7979 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
+= UNITS_PER_WORD
)
7980 if (!validate_subreg (word_mode
, mode
, target
, i
))
7985 /* Like maybe_legitimize_operand, but do not change the code of the
7986 current rtx value. */
7989 maybe_legitimize_operand_same_code (enum insn_code icode
, unsigned int opno
,
7990 struct expand_operand
*op
)
7992 /* See if the operand matches in its current form. */
7993 if (insn_operand_matches (icode
, opno
, op
->value
))
7996 /* If the operand is a memory whose address has no side effects,
7997 try forcing the address into a non-virtual pseudo register.
7998 The check for side effects is important because copy_to_mode_reg
7999 cannot handle things like auto-modified addresses. */
8000 if (insn_data
[(int) icode
].operand
[opno
].allows_mem
&& MEM_P (op
->value
))
8005 addr
= XEXP (mem
, 0);
8006 if (!(REG_P (addr
) && REGNO (addr
) > LAST_VIRTUAL_REGISTER
)
8007 && !side_effects_p (addr
))
8010 enum machine_mode mode
;
8012 last
= get_last_insn ();
8013 mode
= get_address_mode (mem
);
8014 mem
= replace_equiv_address (mem
, copy_to_mode_reg (mode
, addr
));
8015 if (insn_operand_matches (icode
, opno
, mem
))
8020 delete_insns_since (last
);
8027 /* Try to make OP match operand OPNO of instruction ICODE. Return true
8028 on success, storing the new operand value back in OP. */
8031 maybe_legitimize_operand (enum insn_code icode
, unsigned int opno
,
8032 struct expand_operand
*op
)
8034 enum machine_mode mode
, imode
;
8035 bool old_volatile_ok
, result
;
8041 old_volatile_ok
= volatile_ok
;
8043 result
= maybe_legitimize_operand_same_code (icode
, opno
, op
);
8044 volatile_ok
= old_volatile_ok
;
8048 gcc_assert (mode
!= VOIDmode
);
8050 && op
->value
!= const0_rtx
8051 && GET_MODE (op
->value
) == mode
8052 && maybe_legitimize_operand_same_code (icode
, opno
, op
))
8055 op
->value
= gen_reg_rtx (mode
);
8060 gcc_assert (mode
!= VOIDmode
);
8061 gcc_assert (GET_MODE (op
->value
) == VOIDmode
8062 || GET_MODE (op
->value
) == mode
);
8063 if (maybe_legitimize_operand_same_code (icode
, opno
, op
))
8066 op
->value
= copy_to_mode_reg (mode
, op
->value
);
8069 case EXPAND_CONVERT_TO
:
8070 gcc_assert (mode
!= VOIDmode
);
8071 op
->value
= convert_to_mode (mode
, op
->value
, op
->unsigned_p
);
8074 case EXPAND_CONVERT_FROM
:
8075 if (GET_MODE (op
->value
) != VOIDmode
)
8076 mode
= GET_MODE (op
->value
);
8078 /* The caller must tell us what mode this value has. */
8079 gcc_assert (mode
!= VOIDmode
);
8081 imode
= insn_data
[(int) icode
].operand
[opno
].mode
;
8082 if (imode
!= VOIDmode
&& imode
!= mode
)
8084 op
->value
= convert_modes (imode
, mode
, op
->value
, op
->unsigned_p
);
8089 case EXPAND_ADDRESS
:
8090 gcc_assert (mode
!= VOIDmode
);
8091 op
->value
= convert_memory_address (mode
, op
->value
);
8094 case EXPAND_INTEGER
:
8095 mode
= insn_data
[(int) icode
].operand
[opno
].mode
;
8096 if (mode
!= VOIDmode
&& const_int_operand (op
->value
, mode
))
8100 return insn_operand_matches (icode
, opno
, op
->value
);
8103 /* Make OP describe an input operand that should have the same value
8104 as VALUE, after any mode conversion that the target might request.
8105 TYPE is the type of VALUE. */
8108 create_convert_operand_from_type (struct expand_operand
*op
,
8109 rtx value
, tree type
)
8111 create_convert_operand_from (op
, value
, TYPE_MODE (type
),
8112 TYPE_UNSIGNED (type
));
8115 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
8116 of instruction ICODE. Return true on success, leaving the new operand
8117 values in the OPS themselves. Emit no code on failure. */
8120 maybe_legitimize_operands (enum insn_code icode
, unsigned int opno
,
8121 unsigned int nops
, struct expand_operand
*ops
)
8126 last
= get_last_insn ();
8127 for (i
= 0; i
< nops
; i
++)
8128 if (!maybe_legitimize_operand (icode
, opno
+ i
, &ops
[i
]))
8130 delete_insns_since (last
);
8136 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
8137 as its operands. Return the instruction pattern on success,
8138 and emit any necessary set-up code. Return null and emit no
8142 maybe_gen_insn (enum insn_code icode
, unsigned int nops
,
8143 struct expand_operand
*ops
)
8145 gcc_assert (nops
== (unsigned int) insn_data
[(int) icode
].n_generator_args
);
8146 if (!maybe_legitimize_operands (icode
, 0, nops
, ops
))
8152 return GEN_FCN (icode
) (ops
[0].value
);
8154 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
);
8156 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
);
8158 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8161 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8162 ops
[3].value
, ops
[4].value
);
8164 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8165 ops
[3].value
, ops
[4].value
, ops
[5].value
);
8167 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8168 ops
[3].value
, ops
[4].value
, ops
[5].value
,
8171 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8172 ops
[3].value
, ops
[4].value
, ops
[5].value
,
8173 ops
[6].value
, ops
[7].value
);
8178 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
8179 as its operands. Return true on success and emit no code on failure. */
8182 maybe_expand_insn (enum insn_code icode
, unsigned int nops
,
8183 struct expand_operand
*ops
)
8185 rtx pat
= maybe_gen_insn (icode
, nops
, ops
);
8194 /* Like maybe_expand_insn, but for jumps. */
8197 maybe_expand_jump_insn (enum insn_code icode
, unsigned int nops
,
8198 struct expand_operand
*ops
)
8200 rtx pat
= maybe_gen_insn (icode
, nops
, ops
);
8203 emit_jump_insn (pat
);
8209 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
8213 expand_insn (enum insn_code icode
, unsigned int nops
,
8214 struct expand_operand
*ops
)
8216 if (!maybe_expand_insn (icode
, nops
, ops
))
8220 /* Like expand_insn, but for jumps. */
8223 expand_jump_insn (enum insn_code icode
, unsigned int nops
,
8224 struct expand_operand
*ops
)
8226 if (!maybe_expand_jump_insn (icode
, nops
, ops
))
8230 /* Reduce conditional compilation elsewhere. */
8233 #define CODE_FOR_insv CODE_FOR_nothing
8237 #define CODE_FOR_extv CODE_FOR_nothing
8240 #define HAVE_extzv 0
8241 #define CODE_FOR_extzv CODE_FOR_nothing
8244 /* Enumerates the possible types of structure operand to an
8246 enum extraction_type
{ ET_unaligned_mem
, ET_reg
};
8248 /* Check whether insv, extv or extzv pattern ICODE can be used for an
8249 insertion or extraction of type TYPE on a structure of mode MODE.
8250 Return true if so and fill in *INSN accordingly. STRUCT_OP is the
8251 operand number of the structure (the first sign_extract or zero_extract
8252 operand) and FIELD_OP is the operand number of the field (the other
8253 side of the set from the sign_extract or zero_extract). */
8256 get_traditional_extraction_insn (extraction_insn
*insn
,
8257 enum extraction_type type
,
8258 enum machine_mode mode
,
8259 enum insn_code icode
,
8260 int struct_op
, int field_op
)
8262 const struct insn_data_d
*data
= &insn_data
[icode
];
8264 enum machine_mode struct_mode
= data
->operand
[struct_op
].mode
;
8265 if (struct_mode
== VOIDmode
)
8266 struct_mode
= word_mode
;
8267 if (mode
!= struct_mode
)
8270 enum machine_mode field_mode
= data
->operand
[field_op
].mode
;
8271 if (field_mode
== VOIDmode
)
8272 field_mode
= word_mode
;
8274 enum machine_mode pos_mode
= data
->operand
[struct_op
+ 2].mode
;
8275 if (pos_mode
== VOIDmode
)
8276 pos_mode
= word_mode
;
8278 insn
->icode
= icode
;
8279 insn
->field_mode
= field_mode
;
8280 insn
->struct_mode
= (type
== ET_unaligned_mem
? byte_mode
: struct_mode
);
8281 insn
->pos_mode
= pos_mode
;
8285 /* Return true if an optab exists to perform an insertion or extraction
8286 of type TYPE in mode MODE. Describe the instruction in *INSN if so.
8288 REG_OPTAB is the optab to use for register structures and
8289 MISALIGN_OPTAB is the optab to use for misaligned memory structures.
8290 POS_OP is the operand number of the bit position. */
8293 get_optab_extraction_insn (struct extraction_insn
*insn
,
8294 enum extraction_type type
,
8295 enum machine_mode mode
, direct_optab reg_optab
,
8296 direct_optab misalign_optab
, int pos_op
)
8298 direct_optab optab
= (type
== ET_unaligned_mem
? misalign_optab
: reg_optab
);
8299 enum insn_code icode
= direct_optab_handler (optab
, mode
);
8300 if (icode
== CODE_FOR_nothing
)
8303 const struct insn_data_d
*data
= &insn_data
[icode
];
8305 insn
->icode
= icode
;
8306 insn
->field_mode
= mode
;
8307 insn
->struct_mode
= (type
== ET_unaligned_mem
? BLKmode
: mode
);
8308 insn
->pos_mode
= data
->operand
[pos_op
].mode
;
8309 if (insn
->pos_mode
== VOIDmode
)
8310 insn
->pos_mode
= word_mode
;
8314 /* Return true if an instruction exists to perform an insertion or
8315 extraction (PATTERN says which) of type TYPE in mode MODE.
8316 Describe the instruction in *INSN if so. */
8319 get_extraction_insn (extraction_insn
*insn
,
8320 enum extraction_pattern pattern
,
8321 enum extraction_type type
,
8322 enum machine_mode mode
)
8328 && get_traditional_extraction_insn (insn
, type
, mode
,
8329 CODE_FOR_insv
, 0, 3))
8331 return get_optab_extraction_insn (insn
, type
, mode
, insv_optab
,
8332 insvmisalign_optab
, 2);
8336 && get_traditional_extraction_insn (insn
, type
, mode
,
8337 CODE_FOR_extv
, 1, 0))
8339 return get_optab_extraction_insn (insn
, type
, mode
, extv_optab
,
8340 extvmisalign_optab
, 3);
8344 && get_traditional_extraction_insn (insn
, type
, mode
,
8345 CODE_FOR_extzv
, 1, 0))
8347 return get_optab_extraction_insn (insn
, type
, mode
, extzv_optab
,
8348 extzvmisalign_optab
, 3);
8355 /* Return true if an instruction exists to access a field of mode
8356 FIELDMODE in a structure that has STRUCT_BITS significant bits.
8357 Describe the "best" such instruction in *INSN if so. PATTERN and
8358 TYPE describe the type of insertion or extraction we want to perform.
8360 For an insertion, the number of significant structure bits includes
8361 all bits of the target. For an extraction, it need only include the
8362 most significant bit of the field. Larger widths are acceptable
8366 get_best_extraction_insn (extraction_insn
*insn
,
8367 enum extraction_pattern pattern
,
8368 enum extraction_type type
,
8369 unsigned HOST_WIDE_INT struct_bits
,
8370 enum machine_mode field_mode
)
8372 enum machine_mode mode
= smallest_mode_for_size (struct_bits
, MODE_INT
);
8373 while (mode
!= VOIDmode
)
8375 if (get_extraction_insn (insn
, pattern
, type
, mode
))
8377 while (mode
!= VOIDmode
8378 && GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (field_mode
)
8379 && !TRULY_NOOP_TRUNCATION_MODES_P (insn
->field_mode
,
8382 get_extraction_insn (insn
, pattern
, type
, mode
);
8383 mode
= GET_MODE_WIDER_MODE (mode
);
8387 mode
= GET_MODE_WIDER_MODE (mode
);
8392 /* Return true if an instruction exists to access a field of mode
8393 FIELDMODE in a register structure that has STRUCT_BITS significant bits.
8394 Describe the "best" such instruction in *INSN if so. PATTERN describes
8395 the type of insertion or extraction we want to perform.
8397 For an insertion, the number of significant structure bits includes
8398 all bits of the target. For an extraction, it need only include the
8399 most significant bit of the field. Larger widths are acceptable
8403 get_best_reg_extraction_insn (extraction_insn
*insn
,
8404 enum extraction_pattern pattern
,
8405 unsigned HOST_WIDE_INT struct_bits
,
8406 enum machine_mode field_mode
)
8408 return get_best_extraction_insn (insn
, pattern
, ET_reg
, struct_bits
,
8412 /* Return true if an instruction exists to access a field of BITSIZE
8413 bits starting BITNUM bits into a memory structure. Describe the
8414 "best" such instruction in *INSN if so. PATTERN describes the type
8415 of insertion or extraction we want to perform and FIELDMODE is the
8416 natural mode of the extracted field.
8418 The instructions considered here only access bytes that overlap
8419 the bitfield; they do not touch any surrounding bytes. */
8422 get_best_mem_extraction_insn (extraction_insn
*insn
,
8423 enum extraction_pattern pattern
,
8424 HOST_WIDE_INT bitsize
, HOST_WIDE_INT bitnum
,
8425 enum machine_mode field_mode
)
8427 unsigned HOST_WIDE_INT struct_bits
= (bitnum
% BITS_PER_UNIT
8429 + BITS_PER_UNIT
- 1);
8430 struct_bits
-= struct_bits
% BITS_PER_UNIT
;
8431 return get_best_extraction_insn (insn
, pattern
, ET_unaligned_mem
,
8432 struct_bits
, field_mode
);
8435 #include "gt-optabs.h"