1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2014 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"
32 #include "tree-hasher.h"
33 #include "stor-layout.h"
34 #include "stringpool.h"
42 #include "hard-reg-set.h"
53 #include "dominance.h"
55 #include "basic-block.h"
58 struct target_optabs default_target_optabs
;
59 struct target_libfuncs default_target_libfuncs
;
60 struct target_optabs
*this_fn_optabs
= &default_target_optabs
;
62 struct target_optabs
*this_target_optabs
= &default_target_optabs
;
63 struct target_libfuncs
*this_target_libfuncs
= &default_target_libfuncs
;
66 #define libfunc_hash \
67 (this_target_libfuncs->x_libfunc_hash)
69 static void prepare_float_lib_cmp (rtx
, rtx
, enum rtx_code
, rtx
*,
71 static rtx
expand_unop_direct (enum machine_mode
, optab
, rtx
, rtx
, int);
72 static void emit_libcall_block_1 (rtx_insn
*, rtx
, rtx
, rtx
, bool);
74 /* Debug facility for use in GDB. */
75 void debug_optab_libfuncs (void);
77 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
78 #if ENABLE_DECIMAL_BID_FORMAT
79 #define DECIMAL_PREFIX "bid_"
81 #define DECIMAL_PREFIX "dpd_"
84 /* Used for libfunc_hash. */
87 libfunc_hasher::hash (libfunc_entry
*e
)
89 return ((e
->mode1
+ e
->mode2
* NUM_MACHINE_MODES
) ^ e
->op
);
92 /* Used for libfunc_hash. */
95 libfunc_hasher::equal (libfunc_entry
*e1
, libfunc_entry
*e2
)
97 return e1
->op
== e2
->op
&& e1
->mode1
== e2
->mode1
&& e1
->mode2
== e2
->mode2
;
100 /* Return libfunc corresponding operation defined by OPTAB converting
101 from MODE2 to MODE1. Trigger lazy initialization if needed, return NULL
102 if no libfunc is available. */
104 convert_optab_libfunc (convert_optab optab
, enum machine_mode mode1
,
105 enum machine_mode mode2
)
107 struct libfunc_entry e
;
108 struct libfunc_entry
**slot
;
110 /* ??? This ought to be an assert, but not all of the places
111 that we expand optabs know about the optabs that got moved
113 if (!(optab
>= FIRST_CONV_OPTAB
&& optab
<= LAST_CONVLIB_OPTAB
))
119 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
122 const struct convert_optab_libcall_d
*d
123 = &convlib_def
[optab
- FIRST_CONV_OPTAB
];
125 if (d
->libcall_gen
== NULL
)
128 d
->libcall_gen (optab
, d
->libcall_basename
, mode1
, mode2
);
129 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
133 return (*slot
)->libfunc
;
136 /* Return libfunc corresponding operation defined by OPTAB in MODE.
137 Trigger lazy initialization if needed, return NULL if no libfunc is
140 optab_libfunc (optab optab
, enum machine_mode mode
)
142 struct libfunc_entry e
;
143 struct libfunc_entry
**slot
;
145 /* ??? This ought to be an assert, but not all of the places
146 that we expand optabs know about the optabs that got moved
148 if (!(optab
>= FIRST_NORM_OPTAB
&& optab
<= LAST_NORMLIB_OPTAB
))
154 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
157 const struct optab_libcall_d
*d
158 = &normlib_def
[optab
- FIRST_NORM_OPTAB
];
160 if (d
->libcall_gen
== NULL
)
163 d
->libcall_gen (optab
, d
->libcall_basename
, d
->libcall_suffix
, mode
);
164 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
168 return (*slot
)->libfunc
;
172 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
173 the result of operation CODE applied to OP0 (and OP1 if it is a binary
176 If the last insn does not set TARGET, don't do anything, but return 1.
178 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
179 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
180 try again, ensuring that TARGET is not one of the operands. */
183 add_equal_note (rtx_insn
*insns
, rtx target
, enum rtx_code code
, rtx op0
, rtx op1
)
189 gcc_assert (insns
&& INSN_P (insns
) && NEXT_INSN (insns
));
191 if (GET_RTX_CLASS (code
) != RTX_COMM_ARITH
192 && GET_RTX_CLASS (code
) != RTX_BIN_ARITH
193 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
194 && GET_RTX_CLASS (code
) != RTX_COMPARE
195 && GET_RTX_CLASS (code
) != RTX_UNARY
)
198 if (GET_CODE (target
) == ZERO_EXTRACT
)
201 for (last_insn
= insns
;
202 NEXT_INSN (last_insn
) != NULL_RTX
;
203 last_insn
= NEXT_INSN (last_insn
))
206 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
207 a value changing in the insn, so the note would be invalid for CSE. */
208 if (reg_overlap_mentioned_p (target
, op0
)
209 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
212 && (rtx_equal_p (target
, op0
)
213 || (op1
&& rtx_equal_p (target
, op1
))))
215 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
216 over expanding it as temp = MEM op X, MEM = temp. If the target
217 supports MEM = MEM op X instructions, it is sometimes too hard
218 to reconstruct that form later, especially if X is also a memory,
219 and due to multiple occurrences of addresses the address might
220 be forced into register unnecessarily.
221 Note that not emitting the REG_EQUIV note might inhibit
222 CSE in some cases. */
223 set
= single_set (last_insn
);
225 && GET_CODE (SET_SRC (set
)) == code
226 && MEM_P (SET_DEST (set
))
227 && (rtx_equal_p (SET_DEST (set
), XEXP (SET_SRC (set
), 0))
228 || (op1
&& rtx_equal_p (SET_DEST (set
),
229 XEXP (SET_SRC (set
), 1)))))
235 set
= set_for_reg_notes (last_insn
);
239 if (! rtx_equal_p (SET_DEST (set
), target
)
240 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
241 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
242 || ! rtx_equal_p (XEXP (SET_DEST (set
), 0), target
)))
245 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
255 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (target
) != GET_MODE (op0
))
257 note
= gen_rtx_fmt_e (code
, GET_MODE (op0
), copy_rtx (op0
));
258 if (GET_MODE_SIZE (GET_MODE (op0
))
259 > GET_MODE_SIZE (GET_MODE (target
)))
260 note
= simplify_gen_unary (TRUNCATE
, GET_MODE (target
),
261 note
, GET_MODE (op0
));
263 note
= simplify_gen_unary (ZERO_EXTEND
, GET_MODE (target
),
264 note
, GET_MODE (op0
));
269 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
273 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
275 set_unique_reg_note (last_insn
, REG_EQUAL
, note
);
280 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
281 for a widening operation would be. In most cases this would be OP0, but if
282 that's a constant it'll be VOIDmode, which isn't useful. */
284 static enum machine_mode
285 widened_mode (enum machine_mode to_mode
, rtx op0
, rtx op1
)
287 enum machine_mode m0
= GET_MODE (op0
);
288 enum machine_mode m1
= GET_MODE (op1
);
289 enum machine_mode result
;
291 if (m0
== VOIDmode
&& m1
== VOIDmode
)
293 else if (m0
== VOIDmode
|| GET_MODE_SIZE (m0
) < GET_MODE_SIZE (m1
))
298 if (GET_MODE_SIZE (result
) > GET_MODE_SIZE (to_mode
))
304 /* Like optab_handler, but for widening_operations that have a
305 TO_MODE and a FROM_MODE. */
308 widening_optab_handler (optab op
, enum machine_mode to_mode
,
309 enum machine_mode from_mode
)
311 unsigned scode
= (op
<< 16) | to_mode
;
312 if (to_mode
!= from_mode
&& from_mode
!= VOIDmode
)
314 /* ??? Why does find_widening_optab_handler_and_mode attempt to
315 widen things that can't be widened? E.g. add_optab... */
316 if (op
> LAST_CONV_OPTAB
)
317 return CODE_FOR_nothing
;
318 scode
|= from_mode
<< 8;
320 return raw_optab_handler (scode
);
323 /* Find a widening optab even if it doesn't widen as much as we want.
324 E.g. if from_mode is HImode, and to_mode is DImode, and there is no
325 direct HI->SI insn, then return SI->DI, if that exists.
326 If PERMIT_NON_WIDENING is non-zero then this can be used with
327 non-widening optabs also. */
330 find_widening_optab_handler_and_mode (optab op
, enum machine_mode to_mode
,
331 enum machine_mode from_mode
,
332 int permit_non_widening
,
333 enum machine_mode
*found_mode
)
335 for (; (permit_non_widening
|| from_mode
!= to_mode
)
336 && GET_MODE_SIZE (from_mode
) <= GET_MODE_SIZE (to_mode
)
337 && from_mode
!= VOIDmode
;
338 from_mode
= GET_MODE_WIDER_MODE (from_mode
))
340 enum insn_code handler
= widening_optab_handler (op
, to_mode
,
343 if (handler
!= CODE_FOR_nothing
)
346 *found_mode
= from_mode
;
351 return CODE_FOR_nothing
;
354 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
355 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
356 not actually do a sign-extend or zero-extend, but can leave the
357 higher-order bits of the result rtx undefined, for example, in the case
358 of logical operations, but not right shifts. */
361 widen_operand (rtx op
, enum machine_mode mode
, enum machine_mode oldmode
,
362 int unsignedp
, int no_extend
)
366 /* If we don't have to extend and this is a constant, return it. */
367 if (no_extend
&& GET_MODE (op
) == VOIDmode
)
370 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
371 extend since it will be more efficient to do so unless the signedness of
372 a promoted object differs from our extension. */
374 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)
375 && SUBREG_CHECK_PROMOTED_SIGN (op
, unsignedp
)))
376 return convert_modes (mode
, oldmode
, op
, unsignedp
);
378 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
380 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
381 return gen_lowpart (mode
, force_reg (GET_MODE (op
), op
));
383 /* Otherwise, get an object of MODE, clobber it, and set the low-order
386 result
= gen_reg_rtx (mode
);
387 emit_clobber (result
);
388 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
392 /* Return the optab used for computing the operation given by the tree code,
393 CODE and the tree EXP. This function is not always usable (for example, it
394 cannot give complete results for multiplication or division) but probably
395 ought to be relied on more widely throughout the expander. */
397 optab_for_tree_code (enum tree_code code
, const_tree type
,
398 enum optab_subtype subtype
)
410 return one_cmpl_optab
;
415 case MULT_HIGHPART_EXPR
:
416 return TYPE_UNSIGNED (type
) ? umul_highpart_optab
: smul_highpart_optab
;
422 return TYPE_UNSIGNED (type
) ? umod_optab
: smod_optab
;
430 if (TYPE_SATURATING (type
))
431 return TYPE_UNSIGNED (type
) ? usdiv_optab
: ssdiv_optab
;
432 return TYPE_UNSIGNED (type
) ? udiv_optab
: sdiv_optab
;
435 if (TREE_CODE (type
) == VECTOR_TYPE
)
437 if (subtype
== optab_vector
)
438 return TYPE_SATURATING (type
) ? unknown_optab
: vashl_optab
;
440 gcc_assert (subtype
== optab_scalar
);
442 if (TYPE_SATURATING (type
))
443 return TYPE_UNSIGNED (type
) ? usashl_optab
: ssashl_optab
;
447 if (TREE_CODE (type
) == VECTOR_TYPE
)
449 if (subtype
== optab_vector
)
450 return TYPE_UNSIGNED (type
) ? vlshr_optab
: vashr_optab
;
452 gcc_assert (subtype
== optab_scalar
);
454 return TYPE_UNSIGNED (type
) ? lshr_optab
: ashr_optab
;
457 if (TREE_CODE (type
) == VECTOR_TYPE
)
459 if (subtype
== optab_vector
)
462 gcc_assert (subtype
== optab_scalar
);
467 if (TREE_CODE (type
) == VECTOR_TYPE
)
469 if (subtype
== optab_vector
)
472 gcc_assert (subtype
== optab_scalar
);
477 return TYPE_UNSIGNED (type
) ? umax_optab
: smax_optab
;
480 return TYPE_UNSIGNED (type
) ? umin_optab
: smin_optab
;
482 case REALIGN_LOAD_EXPR
:
483 return vec_realign_load_optab
;
486 return TYPE_UNSIGNED (type
) ? usum_widen_optab
: ssum_widen_optab
;
489 return TYPE_UNSIGNED (type
) ? udot_prod_optab
: sdot_prod_optab
;
492 return TYPE_UNSIGNED (type
) ? usad_optab
: ssad_optab
;
494 case WIDEN_MULT_PLUS_EXPR
:
495 return (TYPE_UNSIGNED (type
)
496 ? (TYPE_SATURATING (type
)
497 ? usmadd_widen_optab
: umadd_widen_optab
)
498 : (TYPE_SATURATING (type
)
499 ? ssmadd_widen_optab
: smadd_widen_optab
));
501 case WIDEN_MULT_MINUS_EXPR
:
502 return (TYPE_UNSIGNED (type
)
503 ? (TYPE_SATURATING (type
)
504 ? usmsub_widen_optab
: umsub_widen_optab
)
505 : (TYPE_SATURATING (type
)
506 ? ssmsub_widen_optab
: smsub_widen_optab
));
512 return TYPE_UNSIGNED (type
) ? reduc_umax_optab
: reduc_smax_optab
;
515 return TYPE_UNSIGNED (type
) ? reduc_umin_optab
: reduc_smin_optab
;
517 case REDUC_PLUS_EXPR
:
518 return TYPE_UNSIGNED (type
) ? reduc_uplus_optab
: reduc_splus_optab
;
520 case VEC_LSHIFT_EXPR
:
521 return vec_shl_optab
;
523 case VEC_RSHIFT_EXPR
:
524 return vec_shr_optab
;
526 case VEC_WIDEN_MULT_HI_EXPR
:
527 return TYPE_UNSIGNED (type
) ?
528 vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
530 case VEC_WIDEN_MULT_LO_EXPR
:
531 return TYPE_UNSIGNED (type
) ?
532 vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
534 case VEC_WIDEN_MULT_EVEN_EXPR
:
535 return TYPE_UNSIGNED (type
) ?
536 vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
538 case VEC_WIDEN_MULT_ODD_EXPR
:
539 return TYPE_UNSIGNED (type
) ?
540 vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
542 case VEC_WIDEN_LSHIFT_HI_EXPR
:
543 return TYPE_UNSIGNED (type
) ?
544 vec_widen_ushiftl_hi_optab
: vec_widen_sshiftl_hi_optab
;
546 case VEC_WIDEN_LSHIFT_LO_EXPR
:
547 return TYPE_UNSIGNED (type
) ?
548 vec_widen_ushiftl_lo_optab
: vec_widen_sshiftl_lo_optab
;
550 case VEC_UNPACK_HI_EXPR
:
551 return TYPE_UNSIGNED (type
) ?
552 vec_unpacku_hi_optab
: vec_unpacks_hi_optab
;
554 case VEC_UNPACK_LO_EXPR
:
555 return TYPE_UNSIGNED (type
) ?
556 vec_unpacku_lo_optab
: vec_unpacks_lo_optab
;
558 case VEC_UNPACK_FLOAT_HI_EXPR
:
559 /* The signedness is determined from input operand. */
560 return TYPE_UNSIGNED (type
) ?
561 vec_unpacku_float_hi_optab
: vec_unpacks_float_hi_optab
;
563 case VEC_UNPACK_FLOAT_LO_EXPR
:
564 /* The signedness is determined from input operand. */
565 return TYPE_UNSIGNED (type
) ?
566 vec_unpacku_float_lo_optab
: vec_unpacks_float_lo_optab
;
568 case VEC_PACK_TRUNC_EXPR
:
569 return vec_pack_trunc_optab
;
571 case VEC_PACK_SAT_EXPR
:
572 return TYPE_UNSIGNED (type
) ? vec_pack_usat_optab
: vec_pack_ssat_optab
;
574 case VEC_PACK_FIX_TRUNC_EXPR
:
575 /* The signedness is determined from output operand. */
576 return TYPE_UNSIGNED (type
) ?
577 vec_pack_ufix_trunc_optab
: vec_pack_sfix_trunc_optab
;
583 trapv
= INTEGRAL_TYPE_P (type
) && TYPE_OVERFLOW_TRAPS (type
);
586 case POINTER_PLUS_EXPR
:
588 if (TYPE_SATURATING (type
))
589 return TYPE_UNSIGNED (type
) ? usadd_optab
: ssadd_optab
;
590 return trapv
? addv_optab
: add_optab
;
593 if (TYPE_SATURATING (type
))
594 return TYPE_UNSIGNED (type
) ? ussub_optab
: sssub_optab
;
595 return trapv
? subv_optab
: sub_optab
;
598 if (TYPE_SATURATING (type
))
599 return TYPE_UNSIGNED (type
) ? usmul_optab
: ssmul_optab
;
600 return trapv
? smulv_optab
: smul_optab
;
603 if (TYPE_SATURATING (type
))
604 return TYPE_UNSIGNED (type
) ? usneg_optab
: ssneg_optab
;
605 return trapv
? negv_optab
: neg_optab
;
608 return trapv
? absv_optab
: abs_optab
;
611 return unknown_optab
;
616 /* Expand vector widening operations.
618 There are two different classes of operations handled here:
619 1) Operations whose result is wider than all the arguments to the operation.
620 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
621 In this case OP0 and optionally OP1 would be initialized,
622 but WIDE_OP wouldn't (not relevant for this case).
623 2) Operations whose result is of the same size as the last argument to the
624 operation, but wider than all the other arguments to the operation.
625 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
626 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
628 E.g, when called to expand the following operations, this is how
629 the arguments will be initialized:
631 widening-sum 2 oprnd0 - oprnd1
632 widening-dot-product 3 oprnd0 oprnd1 oprnd2
633 widening-mult 2 oprnd0 oprnd1 -
634 type-promotion (vec-unpack) 1 oprnd0 - - */
637 expand_widen_pattern_expr (sepops ops
, rtx op0
, rtx op1
, rtx wide_op
,
638 rtx target
, int unsignedp
)
640 struct expand_operand eops
[4];
641 tree oprnd0
, oprnd1
, oprnd2
;
642 enum machine_mode wmode
= VOIDmode
, tmode0
, tmode1
= VOIDmode
;
643 optab widen_pattern_optab
;
644 enum insn_code icode
;
645 int nops
= TREE_CODE_LENGTH (ops
->code
);
649 tmode0
= TYPE_MODE (TREE_TYPE (oprnd0
));
650 widen_pattern_optab
=
651 optab_for_tree_code (ops
->code
, TREE_TYPE (oprnd0
), optab_default
);
652 if (ops
->code
== WIDEN_MULT_PLUS_EXPR
653 || ops
->code
== WIDEN_MULT_MINUS_EXPR
)
654 icode
= find_widening_optab_handler (widen_pattern_optab
,
655 TYPE_MODE (TREE_TYPE (ops
->op2
)),
658 icode
= optab_handler (widen_pattern_optab
, tmode0
);
659 gcc_assert (icode
!= CODE_FOR_nothing
);
664 tmode1
= TYPE_MODE (TREE_TYPE (oprnd1
));
667 /* The last operand is of a wider mode than the rest of the operands. */
672 gcc_assert (tmode1
== tmode0
);
675 wmode
= TYPE_MODE (TREE_TYPE (oprnd2
));
679 create_output_operand (&eops
[op
++], target
, TYPE_MODE (ops
->type
));
680 create_convert_operand_from (&eops
[op
++], op0
, tmode0
, unsignedp
);
682 create_convert_operand_from (&eops
[op
++], op1
, tmode1
, unsignedp
);
684 create_convert_operand_from (&eops
[op
++], wide_op
, wmode
, unsignedp
);
685 expand_insn (icode
, op
, eops
);
686 return eops
[0].value
;
689 /* Generate code to perform an operation specified by TERNARY_OPTAB
690 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
692 UNSIGNEDP is for the case where we have to widen the operands
693 to perform the operation. It says to use zero-extension.
695 If TARGET is nonzero, the value
696 is generated there, if it is convenient to do so.
697 In all cases an rtx is returned for the locus of the value;
698 this may or may not be TARGET. */
701 expand_ternary_op (enum machine_mode mode
, optab ternary_optab
, rtx op0
,
702 rtx op1
, rtx op2
, rtx target
, int unsignedp
)
704 struct expand_operand ops
[4];
705 enum insn_code icode
= optab_handler (ternary_optab
, mode
);
707 gcc_assert (optab_handler (ternary_optab
, mode
) != CODE_FOR_nothing
);
709 create_output_operand (&ops
[0], target
, mode
);
710 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
711 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
712 create_convert_operand_from (&ops
[3], op2
, mode
, unsignedp
);
713 expand_insn (icode
, 4, ops
);
718 /* Like expand_binop, but return a constant rtx if the result can be
719 calculated at compile time. The arguments and return value are
720 otherwise the same as for expand_binop. */
723 simplify_expand_binop (enum machine_mode mode
, optab binoptab
,
724 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
725 enum optab_methods methods
)
727 if (CONSTANT_P (op0
) && CONSTANT_P (op1
))
729 rtx x
= simplify_binary_operation (optab_to_code (binoptab
),
735 return expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
);
738 /* Like simplify_expand_binop, but always put the result in TARGET.
739 Return true if the expansion succeeded. */
742 force_expand_binop (enum machine_mode mode
, optab binoptab
,
743 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
744 enum optab_methods methods
)
746 rtx x
= simplify_expand_binop (mode
, binoptab
, op0
, op1
,
747 target
, unsignedp
, methods
);
751 emit_move_insn (target
, x
);
755 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */
758 expand_vec_shift_expr (sepops ops
, rtx target
)
760 struct expand_operand eops
[3];
761 enum insn_code icode
;
762 rtx rtx_op1
, rtx_op2
;
763 enum machine_mode mode
= TYPE_MODE (ops
->type
);
764 tree vec_oprnd
= ops
->op0
;
765 tree shift_oprnd
= ops
->op1
;
770 case VEC_RSHIFT_EXPR
:
771 shift_optab
= vec_shr_optab
;
773 case VEC_LSHIFT_EXPR
:
774 shift_optab
= vec_shl_optab
;
780 icode
= optab_handler (shift_optab
, mode
);
781 gcc_assert (icode
!= CODE_FOR_nothing
);
783 rtx_op1
= expand_normal (vec_oprnd
);
784 rtx_op2
= expand_normal (shift_oprnd
);
786 create_output_operand (&eops
[0], target
, mode
);
787 create_input_operand (&eops
[1], rtx_op1
, GET_MODE (rtx_op1
));
788 create_convert_operand_from_type (&eops
[2], rtx_op2
, TREE_TYPE (shift_oprnd
));
789 expand_insn (icode
, 3, eops
);
791 return eops
[0].value
;
794 /* Create a new vector value in VMODE with all elements set to OP. The
795 mode of OP must be the element mode of VMODE. If OP is a constant,
796 then the return value will be a constant. */
799 expand_vector_broadcast (enum machine_mode vmode
, rtx op
)
801 enum insn_code icode
;
806 gcc_checking_assert (VECTOR_MODE_P (vmode
));
808 n
= GET_MODE_NUNITS (vmode
);
809 vec
= rtvec_alloc (n
);
810 for (i
= 0; i
< n
; ++i
)
811 RTVEC_ELT (vec
, i
) = op
;
814 return gen_rtx_CONST_VECTOR (vmode
, vec
);
816 /* ??? If the target doesn't have a vec_init, then we have no easy way
817 of performing this operation. Most of this sort of generic support
818 is hidden away in the vector lowering support in gimple. */
819 icode
= optab_handler (vec_init_optab
, vmode
);
820 if (icode
== CODE_FOR_nothing
)
823 ret
= gen_reg_rtx (vmode
);
824 emit_insn (GEN_FCN (icode
) (ret
, gen_rtx_PARALLEL (vmode
, vec
)));
829 /* This subroutine of expand_doubleword_shift handles the cases in which
830 the effective shift value is >= BITS_PER_WORD. The arguments and return
831 value are the same as for the parent routine, except that SUPERWORD_OP1
832 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
833 INTO_TARGET may be null if the caller has decided to calculate it. */
836 expand_superword_shift (optab binoptab
, rtx outof_input
, rtx superword_op1
,
837 rtx outof_target
, rtx into_target
,
838 int unsignedp
, enum optab_methods methods
)
840 if (into_target
!= 0)
841 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, superword_op1
,
842 into_target
, unsignedp
, methods
))
845 if (outof_target
!= 0)
847 /* For a signed right shift, we must fill OUTOF_TARGET with copies
848 of the sign bit, otherwise we must fill it with zeros. */
849 if (binoptab
!= ashr_optab
)
850 emit_move_insn (outof_target
, CONST0_RTX (word_mode
));
852 if (!force_expand_binop (word_mode
, binoptab
,
853 outof_input
, GEN_INT (BITS_PER_WORD
- 1),
854 outof_target
, unsignedp
, methods
))
860 /* This subroutine of expand_doubleword_shift handles the cases in which
861 the effective shift value is < BITS_PER_WORD. The arguments and return
862 value are the same as for the parent routine. */
865 expand_subword_shift (enum machine_mode op1_mode
, optab binoptab
,
866 rtx outof_input
, rtx into_input
, rtx op1
,
867 rtx outof_target
, rtx into_target
,
868 int unsignedp
, enum optab_methods methods
,
869 unsigned HOST_WIDE_INT shift_mask
)
871 optab reverse_unsigned_shift
, unsigned_shift
;
874 reverse_unsigned_shift
= (binoptab
== ashl_optab
? lshr_optab
: ashl_optab
);
875 unsigned_shift
= (binoptab
== ashl_optab
? ashl_optab
: lshr_optab
);
877 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
878 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
879 the opposite direction to BINOPTAB. */
880 if (CONSTANT_P (op1
) || shift_mask
>= BITS_PER_WORD
)
882 carries
= outof_input
;
883 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
,
884 op1_mode
), op1_mode
);
885 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
890 /* We must avoid shifting by BITS_PER_WORD bits since that is either
891 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
892 has unknown behavior. Do a single shift first, then shift by the
893 remainder. It's OK to use ~OP1 as the remainder if shift counts
894 are truncated to the mode size. */
895 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
896 outof_input
, const1_rtx
, 0, unsignedp
, methods
);
897 if (shift_mask
== BITS_PER_WORD
- 1)
899 tmp
= immed_wide_int_const
900 (wi::minus_one (GET_MODE_PRECISION (op1_mode
)), op1_mode
);
901 tmp
= simplify_expand_binop (op1_mode
, xor_optab
, op1
, tmp
,
906 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
- 1,
907 op1_mode
), op1_mode
);
908 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
912 if (tmp
== 0 || carries
== 0)
914 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
915 carries
, tmp
, 0, unsignedp
, methods
);
919 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
920 so the result can go directly into INTO_TARGET if convenient. */
921 tmp
= expand_binop (word_mode
, unsigned_shift
, into_input
, op1
,
922 into_target
, unsignedp
, methods
);
926 /* Now OR in the bits carried over from OUTOF_INPUT. */
927 if (!force_expand_binop (word_mode
, ior_optab
, tmp
, carries
,
928 into_target
, unsignedp
, methods
))
931 /* Use a standard word_mode shift for the out-of half. */
932 if (outof_target
!= 0)
933 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
934 outof_target
, unsignedp
, methods
))
941 #ifdef HAVE_conditional_move
942 /* Try implementing expand_doubleword_shift using conditional moves.
943 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
944 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
945 are the shift counts to use in the former and latter case. All other
946 arguments are the same as the parent routine. */
949 expand_doubleword_shift_condmove (enum machine_mode op1_mode
, optab binoptab
,
950 enum rtx_code cmp_code
, rtx cmp1
, rtx cmp2
,
951 rtx outof_input
, rtx into_input
,
952 rtx subword_op1
, rtx superword_op1
,
953 rtx outof_target
, rtx into_target
,
954 int unsignedp
, enum optab_methods methods
,
955 unsigned HOST_WIDE_INT shift_mask
)
957 rtx outof_superword
, into_superword
;
959 /* Put the superword version of the output into OUTOF_SUPERWORD and
961 outof_superword
= outof_target
!= 0 ? gen_reg_rtx (word_mode
) : 0;
962 if (outof_target
!= 0 && subword_op1
== superword_op1
)
964 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
965 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
966 into_superword
= outof_target
;
967 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
968 outof_superword
, 0, unsignedp
, methods
))
973 into_superword
= gen_reg_rtx (word_mode
);
974 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
975 outof_superword
, into_superword
,
980 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
981 if (!expand_subword_shift (op1_mode
, binoptab
,
982 outof_input
, into_input
, subword_op1
,
983 outof_target
, into_target
,
984 unsignedp
, methods
, shift_mask
))
987 /* Select between them. Do the INTO half first because INTO_SUPERWORD
988 might be the current value of OUTOF_TARGET. */
989 if (!emit_conditional_move (into_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
990 into_target
, into_superword
, word_mode
, false))
993 if (outof_target
!= 0)
994 if (!emit_conditional_move (outof_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
995 outof_target
, outof_superword
,
1003 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
1004 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
1005 input operand; the shift moves bits in the direction OUTOF_INPUT->
1006 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
1007 of the target. OP1 is the shift count and OP1_MODE is its mode.
1008 If OP1 is constant, it will have been truncated as appropriate
1009 and is known to be nonzero.
1011 If SHIFT_MASK is zero, the result of word shifts is undefined when the
1012 shift count is outside the range [0, BITS_PER_WORD). This routine must
1013 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
1015 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
1016 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
1017 fill with zeros or sign bits as appropriate.
1019 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
1020 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
1021 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
1022 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
1025 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
1026 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
1027 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
1028 function wants to calculate it itself.
1030 Return true if the shift could be successfully synthesized. */
1033 expand_doubleword_shift (enum machine_mode op1_mode
, optab binoptab
,
1034 rtx outof_input
, rtx into_input
, rtx op1
,
1035 rtx outof_target
, rtx into_target
,
1036 int unsignedp
, enum optab_methods methods
,
1037 unsigned HOST_WIDE_INT shift_mask
)
1039 rtx superword_op1
, tmp
, cmp1
, cmp2
;
1040 enum rtx_code cmp_code
;
1042 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
1043 fill the result with sign or zero bits as appropriate. If so, the value
1044 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
1045 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
1046 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
1048 This isn't worthwhile for constant shifts since the optimizers will
1049 cope better with in-range shift counts. */
1050 if (shift_mask
>= BITS_PER_WORD
1051 && outof_target
!= 0
1052 && !CONSTANT_P (op1
))
1054 if (!expand_doubleword_shift (op1_mode
, binoptab
,
1055 outof_input
, into_input
, op1
,
1057 unsignedp
, methods
, shift_mask
))
1059 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
1060 outof_target
, unsignedp
, methods
))
1065 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
1066 is true when the effective shift value is less than BITS_PER_WORD.
1067 Set SUPERWORD_OP1 to the shift count that should be used to shift
1068 OUTOF_INPUT into INTO_TARGET when the condition is false. */
1069 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
, op1_mode
), op1_mode
);
1070 if (!CONSTANT_P (op1
) && shift_mask
== BITS_PER_WORD
- 1)
1072 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
1073 is a subword shift count. */
1074 cmp1
= simplify_expand_binop (op1_mode
, and_optab
, op1
, tmp
,
1076 cmp2
= CONST0_RTX (op1_mode
);
1078 superword_op1
= op1
;
1082 /* Set CMP1 to OP1 - BITS_PER_WORD. */
1083 cmp1
= simplify_expand_binop (op1_mode
, sub_optab
, op1
, tmp
,
1085 cmp2
= CONST0_RTX (op1_mode
);
1087 superword_op1
= cmp1
;
1092 /* If we can compute the condition at compile time, pick the
1093 appropriate subroutine. */
1094 tmp
= simplify_relational_operation (cmp_code
, SImode
, op1_mode
, cmp1
, cmp2
);
1095 if (tmp
!= 0 && CONST_INT_P (tmp
))
1097 if (tmp
== const0_rtx
)
1098 return expand_superword_shift (binoptab
, outof_input
, superword_op1
,
1099 outof_target
, into_target
,
1100 unsignedp
, methods
);
1102 return expand_subword_shift (op1_mode
, binoptab
,
1103 outof_input
, into_input
, op1
,
1104 outof_target
, into_target
,
1105 unsignedp
, methods
, shift_mask
);
1108 #ifdef HAVE_conditional_move
1109 /* Try using conditional moves to generate straight-line code. */
1111 rtx_insn
*start
= get_last_insn ();
1112 if (expand_doubleword_shift_condmove (op1_mode
, binoptab
,
1113 cmp_code
, cmp1
, cmp2
,
1114 outof_input
, into_input
,
1116 outof_target
, into_target
,
1117 unsignedp
, methods
, shift_mask
))
1119 delete_insns_since (start
);
1123 /* As a last resort, use branches to select the correct alternative. */
1124 rtx_code_label
*subword_label
= gen_label_rtx ();
1125 rtx_code_label
*done_label
= gen_label_rtx ();
1128 do_compare_rtx_and_jump (cmp1
, cmp2
, cmp_code
, false, op1_mode
,
1129 0, 0, subword_label
, -1);
1132 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
1133 outof_target
, into_target
,
1134 unsignedp
, methods
))
1137 emit_jump_insn (gen_jump (done_label
));
1139 emit_label (subword_label
);
1141 if (!expand_subword_shift (op1_mode
, binoptab
,
1142 outof_input
, into_input
, op1
,
1143 outof_target
, into_target
,
1144 unsignedp
, methods
, shift_mask
))
1147 emit_label (done_label
);
1151 /* Subroutine of expand_binop. Perform a double word multiplication of
1152 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1153 as the target's word_mode. This function return NULL_RTX if anything
1154 goes wrong, in which case it may have already emitted instructions
1155 which need to be deleted.
1157 If we want to multiply two two-word values and have normal and widening
1158 multiplies of single-word values, we can do this with three smaller
1161 The multiplication proceeds as follows:
1162 _______________________
1163 [__op0_high_|__op0_low__]
1164 _______________________
1165 * [__op1_high_|__op1_low__]
1166 _______________________________________________
1167 _______________________
1168 (1) [__op0_low__*__op1_low__]
1169 _______________________
1170 (2a) [__op0_low__*__op1_high_]
1171 _______________________
1172 (2b) [__op0_high_*__op1_low__]
1173 _______________________
1174 (3) [__op0_high_*__op1_high_]
1177 This gives a 4-word result. Since we are only interested in the
1178 lower 2 words, partial result (3) and the upper words of (2a) and
1179 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1180 calculated using non-widening multiplication.
1182 (1), however, needs to be calculated with an unsigned widening
1183 multiplication. If this operation is not directly supported we
1184 try using a signed widening multiplication and adjust the result.
1185 This adjustment works as follows:
1187 If both operands are positive then no adjustment is needed.
1189 If the operands have different signs, for example op0_low < 0 and
1190 op1_low >= 0, the instruction treats the most significant bit of
1191 op0_low as a sign bit instead of a bit with significance
1192 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1193 with 2**BITS_PER_WORD - op0_low, and two's complements the
1194 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1197 Similarly, if both operands are negative, we need to add
1198 (op0_low + op1_low) * 2**BITS_PER_WORD.
1200 We use a trick to adjust quickly. We logically shift op0_low right
1201 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1202 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1203 logical shift exists, we do an arithmetic right shift and subtract
1207 expand_doubleword_mult (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
1208 bool umulp
, enum optab_methods methods
)
1210 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1211 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1212 rtx wordm1
= umulp
? NULL_RTX
: GEN_INT (BITS_PER_WORD
- 1);
1213 rtx product
, adjust
, product_high
, temp
;
1215 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1216 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1217 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1218 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1220 /* If we're using an unsigned multiply to directly compute the product
1221 of the low-order words of the operands and perform any required
1222 adjustments of the operands, we begin by trying two more multiplications
1223 and then computing the appropriate sum.
1225 We have checked above that the required addition is provided.
1226 Full-word addition will normally always succeed, especially if
1227 it is provided at all, so we don't worry about its failure. The
1228 multiplication may well fail, however, so we do handle that. */
1232 /* ??? This could be done with emit_store_flag where available. */
1233 temp
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1234 NULL_RTX
, 1, methods
);
1236 op0_high
= expand_binop (word_mode
, add_optab
, op0_high
, temp
,
1237 NULL_RTX
, 0, OPTAB_DIRECT
);
1240 temp
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1241 NULL_RTX
, 0, methods
);
1244 op0_high
= expand_binop (word_mode
, sub_optab
, op0_high
, temp
,
1245 NULL_RTX
, 0, OPTAB_DIRECT
);
1252 adjust
= expand_binop (word_mode
, smul_optab
, op0_high
, op1_low
,
1253 NULL_RTX
, 0, OPTAB_DIRECT
);
1257 /* OP0_HIGH should now be dead. */
1261 /* ??? This could be done with emit_store_flag where available. */
1262 temp
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1263 NULL_RTX
, 1, methods
);
1265 op1_high
= expand_binop (word_mode
, add_optab
, op1_high
, temp
,
1266 NULL_RTX
, 0, OPTAB_DIRECT
);
1269 temp
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1270 NULL_RTX
, 0, methods
);
1273 op1_high
= expand_binop (word_mode
, sub_optab
, op1_high
, temp
,
1274 NULL_RTX
, 0, OPTAB_DIRECT
);
1281 temp
= expand_binop (word_mode
, smul_optab
, op1_high
, op0_low
,
1282 NULL_RTX
, 0, OPTAB_DIRECT
);
1286 /* OP1_HIGH should now be dead. */
1288 adjust
= expand_binop (word_mode
, add_optab
, adjust
, temp
,
1289 NULL_RTX
, 0, OPTAB_DIRECT
);
1291 if (target
&& !REG_P (target
))
1295 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1296 target
, 1, OPTAB_DIRECT
);
1298 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1299 target
, 1, OPTAB_DIRECT
);
1304 product_high
= operand_subword (product
, high
, 1, mode
);
1305 adjust
= expand_binop (word_mode
, add_optab
, product_high
, adjust
,
1306 NULL_RTX
, 0, OPTAB_DIRECT
);
1307 emit_move_insn (product_high
, adjust
);
1311 /* Wrapper around expand_binop which takes an rtx code to specify
1312 the operation to perform, not an optab pointer. All other
1313 arguments are the same. */
1315 expand_simple_binop (enum machine_mode mode
, enum rtx_code code
, rtx op0
,
1316 rtx op1
, rtx target
, int unsignedp
,
1317 enum optab_methods methods
)
1319 optab binop
= code_to_optab (code
);
1322 return expand_binop (mode
, binop
, op0
, op1
, target
, unsignedp
, methods
);
1325 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1326 binop. Order them according to commutative_operand_precedence and, if
1327 possible, try to put TARGET or a pseudo first. */
1329 swap_commutative_operands_with_target (rtx target
, rtx op0
, rtx op1
)
1331 int op0_prec
= commutative_operand_precedence (op0
);
1332 int op1_prec
= commutative_operand_precedence (op1
);
1334 if (op0_prec
< op1_prec
)
1337 if (op0_prec
> op1_prec
)
1340 /* With equal precedence, both orders are ok, but it is better if the
1341 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1342 if (target
== 0 || REG_P (target
))
1343 return (REG_P (op1
) && !REG_P (op0
)) || target
== op1
;
1345 return rtx_equal_p (op1
, target
);
1348 /* Return true if BINOPTAB implements a shift operation. */
1351 shift_optab_p (optab binoptab
)
1353 switch (optab_to_code (binoptab
))
1369 /* Return true if BINOPTAB implements a commutative binary operation. */
1372 commutative_optab_p (optab binoptab
)
1374 return (GET_RTX_CLASS (optab_to_code (binoptab
)) == RTX_COMM_ARITH
1375 || binoptab
== smul_widen_optab
1376 || binoptab
== umul_widen_optab
1377 || binoptab
== smul_highpart_optab
1378 || binoptab
== umul_highpart_optab
);
1381 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
1382 optimizing, and if the operand is a constant that costs more than
1383 1 instruction, force the constant into a register and return that
1384 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1387 avoid_expensive_constant (enum machine_mode mode
, optab binoptab
,
1388 int opn
, rtx x
, bool unsignedp
)
1390 bool speed
= optimize_insn_for_speed_p ();
1392 if (mode
!= VOIDmode
1395 && (rtx_cost (x
, optab_to_code (binoptab
), opn
, speed
)
1396 > set_src_cost (x
, speed
)))
1398 if (CONST_INT_P (x
))
1400 HOST_WIDE_INT intval
= trunc_int_for_mode (INTVAL (x
), mode
);
1401 if (intval
!= INTVAL (x
))
1402 x
= GEN_INT (intval
);
1405 x
= convert_modes (mode
, VOIDmode
, x
, unsignedp
);
1406 x
= force_reg (mode
, x
);
1411 /* Helper function for expand_binop: handle the case where there
1412 is an insn that directly implements the indicated operation.
1413 Returns null if this is not possible. */
1415 expand_binop_directly (enum machine_mode mode
, optab binoptab
,
1417 rtx target
, int unsignedp
, enum optab_methods methods
,
1420 enum machine_mode from_mode
= widened_mode (mode
, op0
, op1
);
1421 enum insn_code icode
= find_widening_optab_handler (binoptab
, mode
,
1423 enum machine_mode xmode0
= insn_data
[(int) icode
].operand
[1].mode
;
1424 enum machine_mode xmode1
= insn_data
[(int) icode
].operand
[2].mode
;
1425 enum machine_mode mode0
, mode1
, tmp_mode
;
1426 struct expand_operand ops
[3];
1429 rtx xop0
= op0
, xop1
= op1
;
1432 /* If it is a commutative operator and the modes would match
1433 if we would swap the operands, we can save the conversions. */
1434 commutative_p
= commutative_optab_p (binoptab
);
1436 && GET_MODE (xop0
) != xmode0
&& GET_MODE (xop1
) != xmode1
1437 && GET_MODE (xop0
) == xmode1
&& GET_MODE (xop1
) == xmode1
)
1444 /* If we are optimizing, force expensive constants into a register. */
1445 xop0
= avoid_expensive_constant (xmode0
, binoptab
, 0, xop0
, unsignedp
);
1446 if (!shift_optab_p (binoptab
))
1447 xop1
= avoid_expensive_constant (xmode1
, binoptab
, 1, xop1
, unsignedp
);
1449 /* In case the insn wants input operands in modes different from
1450 those of the actual operands, convert the operands. It would
1451 seem that we don't need to convert CONST_INTs, but we do, so
1452 that they're properly zero-extended, sign-extended or truncated
1455 mode0
= GET_MODE (xop0
) != VOIDmode
? GET_MODE (xop0
) : mode
;
1456 if (xmode0
!= VOIDmode
&& xmode0
!= mode0
)
1458 xop0
= convert_modes (xmode0
, mode0
, xop0
, unsignedp
);
1462 mode1
= GET_MODE (xop1
) != VOIDmode
? GET_MODE (xop1
) : mode
;
1463 if (xmode1
!= VOIDmode
&& xmode1
!= mode1
)
1465 xop1
= convert_modes (xmode1
, mode1
, xop1
, unsignedp
);
1469 /* If operation is commutative,
1470 try to make the first operand a register.
1471 Even better, try to make it the same as the target.
1472 Also try to make the last operand a constant. */
1474 && swap_commutative_operands_with_target (target
, xop0
, xop1
))
1481 /* Now, if insn's predicates don't allow our operands, put them into
1484 if (binoptab
== vec_pack_trunc_optab
1485 || binoptab
== vec_pack_usat_optab
1486 || binoptab
== vec_pack_ssat_optab
1487 || binoptab
== vec_pack_ufix_trunc_optab
1488 || binoptab
== vec_pack_sfix_trunc_optab
)
1490 /* The mode of the result is different then the mode of the
1492 tmp_mode
= insn_data
[(int) icode
].operand
[0].mode
;
1493 if (GET_MODE_NUNITS (tmp_mode
) != 2 * GET_MODE_NUNITS (mode
))
1495 delete_insns_since (last
);
1502 create_output_operand (&ops
[0], target
, tmp_mode
);
1503 create_input_operand (&ops
[1], xop0
, mode0
);
1504 create_input_operand (&ops
[2], xop1
, mode1
);
1505 pat
= maybe_gen_insn (icode
, 3, ops
);
1508 /* If PAT is composed of more than one insn, try to add an appropriate
1509 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1510 operand, call expand_binop again, this time without a target. */
1511 if (INSN_P (pat
) && NEXT_INSN (as_a
<rtx_insn
*> (pat
)) != NULL_RTX
1512 && ! add_equal_note (as_a
<rtx_insn
*> (pat
), ops
[0].value
,
1513 optab_to_code (binoptab
),
1514 ops
[1].value
, ops
[2].value
))
1516 delete_insns_since (last
);
1517 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
1518 unsignedp
, methods
);
1522 return ops
[0].value
;
1524 delete_insns_since (last
);
1528 /* Generate code to perform an operation specified by BINOPTAB
1529 on operands OP0 and OP1, with result having machine-mode MODE.
1531 UNSIGNEDP is for the case where we have to widen the operands
1532 to perform the operation. It says to use zero-extension.
1534 If TARGET is nonzero, the value
1535 is generated there, if it is convenient to do so.
1536 In all cases an rtx is returned for the locus of the value;
1537 this may or may not be TARGET. */
1540 expand_binop (enum machine_mode mode
, optab binoptab
, rtx op0
, rtx op1
,
1541 rtx target
, int unsignedp
, enum optab_methods methods
)
1543 enum optab_methods next_methods
1544 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
1545 ? OPTAB_WIDEN
: methods
);
1546 enum mode_class mclass
;
1547 enum machine_mode wider_mode
;
1550 rtx_insn
*entry_last
= get_last_insn ();
1553 mclass
= GET_MODE_CLASS (mode
);
1555 /* If subtracting an integer constant, convert this into an addition of
1556 the negated constant. */
1558 if (binoptab
== sub_optab
&& CONST_INT_P (op1
))
1560 op1
= negate_rtx (mode
, op1
);
1561 binoptab
= add_optab
;
1564 /* Record where to delete back to if we backtrack. */
1565 last
= get_last_insn ();
1567 /* If we can do it with a three-operand insn, do so. */
1569 if (methods
!= OPTAB_MUST_WIDEN
1570 && find_widening_optab_handler (binoptab
, mode
,
1571 widened_mode (mode
, op0
, op1
), 1)
1572 != CODE_FOR_nothing
)
1574 temp
= expand_binop_directly (mode
, binoptab
, op0
, op1
, target
,
1575 unsignedp
, methods
, last
);
1580 /* If we were trying to rotate, and that didn't work, try rotating
1581 the other direction before falling back to shifts and bitwise-or. */
1582 if (((binoptab
== rotl_optab
1583 && optab_handler (rotr_optab
, mode
) != CODE_FOR_nothing
)
1584 || (binoptab
== rotr_optab
1585 && optab_handler (rotl_optab
, mode
) != CODE_FOR_nothing
))
1586 && mclass
== MODE_INT
)
1588 optab otheroptab
= (binoptab
== rotl_optab
? rotr_optab
: rotl_optab
);
1590 unsigned int bits
= GET_MODE_PRECISION (mode
);
1592 if (CONST_INT_P (op1
))
1593 newop1
= GEN_INT (bits
- INTVAL (op1
));
1594 else if (targetm
.shift_truncation_mask (mode
) == bits
- 1)
1595 newop1
= negate_rtx (GET_MODE (op1
), op1
);
1597 newop1
= expand_binop (GET_MODE (op1
), sub_optab
,
1598 gen_int_mode (bits
, GET_MODE (op1
)), op1
,
1599 NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1601 temp
= expand_binop_directly (mode
, otheroptab
, op0
, newop1
,
1602 target
, unsignedp
, methods
, last
);
1607 /* If this is a multiply, see if we can do a widening operation that
1608 takes operands of this mode and makes a wider mode. */
1610 if (binoptab
== smul_optab
1611 && GET_MODE_2XWIDER_MODE (mode
) != VOIDmode
1612 && (widening_optab_handler ((unsignedp
? umul_widen_optab
1613 : smul_widen_optab
),
1614 GET_MODE_2XWIDER_MODE (mode
), mode
)
1615 != CODE_FOR_nothing
))
1617 temp
= expand_binop (GET_MODE_2XWIDER_MODE (mode
),
1618 unsignedp
? umul_widen_optab
: smul_widen_optab
,
1619 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1623 if (GET_MODE_CLASS (mode
) == MODE_INT
1624 && TRULY_NOOP_TRUNCATION_MODES_P (mode
, GET_MODE (temp
)))
1625 return gen_lowpart (mode
, temp
);
1627 return convert_to_mode (mode
, temp
, unsignedp
);
1631 /* If this is a vector shift by a scalar, see if we can do a vector
1632 shift by a vector. If so, broadcast the scalar into a vector. */
1633 if (mclass
== MODE_VECTOR_INT
)
1635 optab otheroptab
= unknown_optab
;
1637 if (binoptab
== ashl_optab
)
1638 otheroptab
= vashl_optab
;
1639 else if (binoptab
== ashr_optab
)
1640 otheroptab
= vashr_optab
;
1641 else if (binoptab
== lshr_optab
)
1642 otheroptab
= vlshr_optab
;
1643 else if (binoptab
== rotl_optab
)
1644 otheroptab
= vrotl_optab
;
1645 else if (binoptab
== rotr_optab
)
1646 otheroptab
= vrotr_optab
;
1648 if (otheroptab
&& optab_handler (otheroptab
, mode
) != CODE_FOR_nothing
)
1650 rtx vop1
= expand_vector_broadcast (mode
, op1
);
1653 temp
= expand_binop_directly (mode
, otheroptab
, op0
, vop1
,
1654 target
, unsignedp
, methods
, last
);
1661 /* Look for a wider mode of the same class for which we think we
1662 can open-code the operation. Check for a widening multiply at the
1663 wider mode as well. */
1665 if (CLASS_HAS_WIDER_MODES_P (mclass
)
1666 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
1667 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
1668 wider_mode
!= VOIDmode
;
1669 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1671 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
1672 || (binoptab
== smul_optab
1673 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
1674 && (find_widening_optab_handler ((unsignedp
1676 : smul_widen_optab
),
1677 GET_MODE_WIDER_MODE (wider_mode
),
1679 != CODE_FOR_nothing
)))
1681 rtx xop0
= op0
, xop1
= op1
;
1684 /* For certain integer operations, we need not actually extend
1685 the narrow operands, as long as we will truncate
1686 the results to the same narrowness. */
1688 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1689 || binoptab
== xor_optab
1690 || binoptab
== add_optab
|| binoptab
== sub_optab
1691 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1692 && mclass
== MODE_INT
)
1695 xop0
= avoid_expensive_constant (mode
, binoptab
, 0,
1697 if (binoptab
!= ashl_optab
)
1698 xop1
= avoid_expensive_constant (mode
, binoptab
, 1,
1702 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
1704 /* The second operand of a shift must always be extended. */
1705 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1706 no_extend
&& binoptab
!= ashl_optab
);
1708 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1709 unsignedp
, OPTAB_DIRECT
);
1712 if (mclass
!= MODE_INT
1713 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
1716 target
= gen_reg_rtx (mode
);
1717 convert_move (target
, temp
, 0);
1721 return gen_lowpart (mode
, temp
);
1724 delete_insns_since (last
);
1728 /* If operation is commutative,
1729 try to make the first operand a register.
1730 Even better, try to make it the same as the target.
1731 Also try to make the last operand a constant. */
1732 if (commutative_optab_p (binoptab
)
1733 && swap_commutative_operands_with_target (target
, op0
, op1
))
1740 /* These can be done a word at a time. */
1741 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
1742 && mclass
== MODE_INT
1743 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1744 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1749 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1750 won't be accurate, so use a new target. */
1754 || !valid_multiword_target_p (target
))
1755 target
= gen_reg_rtx (mode
);
1759 /* Do the actual arithmetic. */
1760 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1762 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1763 rtx x
= expand_binop (word_mode
, binoptab
,
1764 operand_subword_force (op0
, i
, mode
),
1765 operand_subword_force (op1
, i
, mode
),
1766 target_piece
, unsignedp
, next_methods
);
1771 if (target_piece
!= x
)
1772 emit_move_insn (target_piece
, x
);
1775 insns
= get_insns ();
1778 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
1785 /* Synthesize double word shifts from single word shifts. */
1786 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
1787 || binoptab
== ashr_optab
)
1788 && mclass
== MODE_INT
1789 && (CONST_INT_P (op1
) || optimize_insn_for_speed_p ())
1790 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1791 && GET_MODE_PRECISION (mode
) == GET_MODE_BITSIZE (mode
)
1792 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
1793 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1794 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1796 unsigned HOST_WIDE_INT shift_mask
, double_shift_mask
;
1797 enum machine_mode op1_mode
;
1799 double_shift_mask
= targetm
.shift_truncation_mask (mode
);
1800 shift_mask
= targetm
.shift_truncation_mask (word_mode
);
1801 op1_mode
= GET_MODE (op1
) != VOIDmode
? GET_MODE (op1
) : word_mode
;
1803 /* Apply the truncation to constant shifts. */
1804 if (double_shift_mask
> 0 && CONST_INT_P (op1
))
1805 op1
= GEN_INT (INTVAL (op1
) & double_shift_mask
);
1807 if (op1
== CONST0_RTX (op1_mode
))
1810 /* Make sure that this is a combination that expand_doubleword_shift
1811 can handle. See the comments there for details. */
1812 if (double_shift_mask
== 0
1813 || (shift_mask
== BITS_PER_WORD
- 1
1814 && double_shift_mask
== BITS_PER_WORD
* 2 - 1))
1817 rtx into_target
, outof_target
;
1818 rtx into_input
, outof_input
;
1819 int left_shift
, outof_word
;
1821 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1822 won't be accurate, so use a new target. */
1826 || !valid_multiword_target_p (target
))
1827 target
= gen_reg_rtx (mode
);
1831 /* OUTOF_* is the word we are shifting bits away from, and
1832 INTO_* is the word that we are shifting bits towards, thus
1833 they differ depending on the direction of the shift and
1834 WORDS_BIG_ENDIAN. */
1836 left_shift
= binoptab
== ashl_optab
;
1837 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1839 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1840 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1842 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1843 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1845 if (expand_doubleword_shift (op1_mode
, binoptab
,
1846 outof_input
, into_input
, op1
,
1847 outof_target
, into_target
,
1848 unsignedp
, next_methods
, shift_mask
))
1850 insns
= get_insns ();
1860 /* Synthesize double word rotates from single word shifts. */
1861 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
1862 && mclass
== MODE_INT
1863 && CONST_INT_P (op1
)
1864 && GET_MODE_PRECISION (mode
) == 2 * BITS_PER_WORD
1865 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1866 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1869 rtx into_target
, outof_target
;
1870 rtx into_input
, outof_input
;
1872 int shift_count
, left_shift
, outof_word
;
1874 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1875 won't be accurate, so use a new target. Do this also if target is not
1876 a REG, first because having a register instead may open optimization
1877 opportunities, and second because if target and op0 happen to be MEMs
1878 designating the same location, we would risk clobbering it too early
1879 in the code sequence we generate below. */
1884 || !valid_multiword_target_p (target
))
1885 target
= gen_reg_rtx (mode
);
1889 shift_count
= INTVAL (op1
);
1891 /* OUTOF_* is the word we are shifting bits away from, and
1892 INTO_* is the word that we are shifting bits towards, thus
1893 they differ depending on the direction of the shift and
1894 WORDS_BIG_ENDIAN. */
1896 left_shift
= (binoptab
== rotl_optab
);
1897 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1899 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1900 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1902 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1903 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1905 if (shift_count
== BITS_PER_WORD
)
1907 /* This is just a word swap. */
1908 emit_move_insn (outof_target
, into_input
);
1909 emit_move_insn (into_target
, outof_input
);
1914 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1915 rtx first_shift_count
, second_shift_count
;
1916 optab reverse_unsigned_shift
, unsigned_shift
;
1918 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1919 ? lshr_optab
: ashl_optab
);
1921 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1922 ? ashl_optab
: lshr_optab
);
1924 if (shift_count
> BITS_PER_WORD
)
1926 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
1927 second_shift_count
= GEN_INT (2 * BITS_PER_WORD
- shift_count
);
1931 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
1932 second_shift_count
= GEN_INT (shift_count
);
1935 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1936 outof_input
, first_shift_count
,
1937 NULL_RTX
, unsignedp
, next_methods
);
1938 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1939 into_input
, second_shift_count
,
1940 NULL_RTX
, unsignedp
, next_methods
);
1942 if (into_temp1
!= 0 && into_temp2
!= 0)
1943 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1944 into_target
, unsignedp
, next_methods
);
1948 if (inter
!= 0 && inter
!= into_target
)
1949 emit_move_insn (into_target
, inter
);
1951 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1952 into_input
, first_shift_count
,
1953 NULL_RTX
, unsignedp
, next_methods
);
1954 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1955 outof_input
, second_shift_count
,
1956 NULL_RTX
, unsignedp
, next_methods
);
1958 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1959 inter
= expand_binop (word_mode
, ior_optab
,
1960 outof_temp1
, outof_temp2
,
1961 outof_target
, unsignedp
, next_methods
);
1963 if (inter
!= 0 && inter
!= outof_target
)
1964 emit_move_insn (outof_target
, inter
);
1967 insns
= get_insns ();
1977 /* These can be done a word at a time by propagating carries. */
1978 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1979 && mclass
== MODE_INT
1980 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
1981 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1984 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1985 const unsigned int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
1986 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1987 rtx xop0
, xop1
, xtarget
;
1989 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1990 value is one of those, use it. Otherwise, use 1 since it is the
1991 one easiest to get. */
1992 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1993 int normalizep
= STORE_FLAG_VALUE
;
1998 /* Prepare the operands. */
1999 xop0
= force_reg (mode
, op0
);
2000 xop1
= force_reg (mode
, op1
);
2002 xtarget
= gen_reg_rtx (mode
);
2004 if (target
== 0 || !REG_P (target
) || !valid_multiword_target_p (target
))
2007 /* Indicate for flow that the entire target reg is being set. */
2009 emit_clobber (xtarget
);
2011 /* Do the actual arithmetic. */
2012 for (i
= 0; i
< nwords
; i
++)
2014 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
2015 rtx target_piece
= operand_subword (xtarget
, index
, 1, mode
);
2016 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
2017 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
2020 /* Main add/subtract of the input operands. */
2021 x
= expand_binop (word_mode
, binoptab
,
2022 op0_piece
, op1_piece
,
2023 target_piece
, unsignedp
, next_methods
);
2029 /* Store carry from main add/subtract. */
2030 carry_out
= gen_reg_rtx (word_mode
);
2031 carry_out
= emit_store_flag_force (carry_out
,
2032 (binoptab
== add_optab
2035 word_mode
, 1, normalizep
);
2042 /* Add/subtract previous carry to main result. */
2043 newx
= expand_binop (word_mode
,
2044 normalizep
== 1 ? binoptab
: otheroptab
,
2046 NULL_RTX
, 1, next_methods
);
2050 /* Get out carry from adding/subtracting carry in. */
2051 rtx carry_tmp
= gen_reg_rtx (word_mode
);
2052 carry_tmp
= emit_store_flag_force (carry_tmp
,
2053 (binoptab
== add_optab
2056 word_mode
, 1, normalizep
);
2058 /* Logical-ior the two poss. carry together. */
2059 carry_out
= expand_binop (word_mode
, ior_optab
,
2060 carry_out
, carry_tmp
,
2061 carry_out
, 0, next_methods
);
2065 emit_move_insn (target_piece
, newx
);
2069 if (x
!= target_piece
)
2070 emit_move_insn (target_piece
, x
);
2073 carry_in
= carry_out
;
2076 if (i
== GET_MODE_BITSIZE (mode
) / (unsigned) BITS_PER_WORD
)
2078 if (optab_handler (mov_optab
, mode
) != CODE_FOR_nothing
2079 || ! rtx_equal_p (target
, xtarget
))
2081 rtx temp
= emit_move_insn (target
, xtarget
);
2083 set_dst_reg_note (temp
, REG_EQUAL
,
2084 gen_rtx_fmt_ee (optab_to_code (binoptab
),
2085 mode
, copy_rtx (xop0
),
2096 delete_insns_since (last
);
2099 /* Attempt to synthesize double word multiplies using a sequence of word
2100 mode multiplications. We first attempt to generate a sequence using a
2101 more efficient unsigned widening multiply, and if that fails we then
2102 try using a signed widening multiply. */
2104 if (binoptab
== smul_optab
2105 && mclass
== MODE_INT
2106 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
2107 && optab_handler (smul_optab
, word_mode
) != CODE_FOR_nothing
2108 && optab_handler (add_optab
, word_mode
) != CODE_FOR_nothing
)
2110 rtx product
= NULL_RTX
;
2111 if (widening_optab_handler (umul_widen_optab
, mode
, word_mode
)
2112 != CODE_FOR_nothing
)
2114 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
2117 delete_insns_since (last
);
2120 if (product
== NULL_RTX
2121 && widening_optab_handler (smul_widen_optab
, mode
, word_mode
)
2122 != CODE_FOR_nothing
)
2124 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
2127 delete_insns_since (last
);
2130 if (product
!= NULL_RTX
)
2132 if (optab_handler (mov_optab
, mode
) != CODE_FOR_nothing
)
2134 temp
= emit_move_insn (target
? target
: product
, product
);
2135 set_dst_reg_note (temp
,
2137 gen_rtx_fmt_ee (MULT
, mode
,
2140 target
? target
: product
);
2146 /* It can't be open-coded in this mode.
2147 Use a library call if one is available and caller says that's ok. */
2149 libfunc
= optab_libfunc (binoptab
, mode
);
2151 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
2155 enum machine_mode op1_mode
= mode
;
2160 if (shift_optab_p (binoptab
))
2162 op1_mode
= targetm
.libgcc_shift_count_mode ();
2163 /* Specify unsigned here,
2164 since negative shift counts are meaningless. */
2165 op1x
= convert_to_mode (op1_mode
, op1
, 1);
2168 if (GET_MODE (op0
) != VOIDmode
2169 && GET_MODE (op0
) != mode
)
2170 op0
= convert_to_mode (mode
, op0
, unsignedp
);
2172 /* Pass 1 for NO_QUEUE so we don't lose any increments
2173 if the libcall is cse'd or moved. */
2174 value
= emit_library_call_value (libfunc
,
2175 NULL_RTX
, LCT_CONST
, mode
, 2,
2176 op0
, mode
, op1x
, op1_mode
);
2178 insns
= get_insns ();
2181 target
= gen_reg_rtx (mode
);
2182 emit_libcall_block_1 (insns
, target
, value
,
2183 gen_rtx_fmt_ee (optab_to_code (binoptab
),
2185 trapv_binoptab_p (binoptab
));
2190 delete_insns_since (last
);
2192 /* It can't be done in this mode. Can we do it in a wider mode? */
2194 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
2195 || methods
== OPTAB_MUST_WIDEN
))
2197 /* Caller says, don't even try. */
2198 delete_insns_since (entry_last
);
2202 /* Compute the value of METHODS to pass to recursive calls.
2203 Don't allow widening to be tried recursively. */
2205 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
2207 /* Look for a wider mode of the same class for which it appears we can do
2210 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2212 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2213 wider_mode
!= VOIDmode
;
2214 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2216 if (find_widening_optab_handler (binoptab
, wider_mode
, mode
, 1)
2218 || (methods
== OPTAB_LIB
2219 && optab_libfunc (binoptab
, wider_mode
)))
2221 rtx xop0
= op0
, xop1
= op1
;
2224 /* For certain integer operations, we need not actually extend
2225 the narrow operands, as long as we will truncate
2226 the results to the same narrowness. */
2228 if ((binoptab
== ior_optab
|| binoptab
== and_optab
2229 || binoptab
== xor_optab
2230 || binoptab
== add_optab
|| binoptab
== sub_optab
2231 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
2232 && mclass
== MODE_INT
)
2235 xop0
= widen_operand (xop0
, wider_mode
, mode
,
2236 unsignedp
, no_extend
);
2238 /* The second operand of a shift must always be extended. */
2239 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
2240 no_extend
&& binoptab
!= ashl_optab
);
2242 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
2243 unsignedp
, methods
);
2246 if (mclass
!= MODE_INT
2247 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
2250 target
= gen_reg_rtx (mode
);
2251 convert_move (target
, temp
, 0);
2255 return gen_lowpart (mode
, temp
);
2258 delete_insns_since (last
);
2263 delete_insns_since (entry_last
);
2267 /* Expand a binary operator which has both signed and unsigned forms.
2268 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2271 If we widen unsigned operands, we may use a signed wider operation instead
2272 of an unsigned wider operation, since the result would be the same. */
2275 sign_expand_binop (enum machine_mode mode
, optab uoptab
, optab soptab
,
2276 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
2277 enum optab_methods methods
)
2280 optab direct_optab
= unsignedp
? uoptab
: soptab
;
2283 /* Do it without widening, if possible. */
2284 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
2285 unsignedp
, OPTAB_DIRECT
);
2286 if (temp
|| methods
== OPTAB_DIRECT
)
2289 /* Try widening to a signed int. Disable any direct use of any
2290 signed insn in the current mode. */
2291 save_enable
= swap_optab_enable (soptab
, mode
, false);
2293 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
2294 unsignedp
, OPTAB_WIDEN
);
2296 /* For unsigned operands, try widening to an unsigned int. */
2297 if (!temp
&& unsignedp
)
2298 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
2299 unsignedp
, OPTAB_WIDEN
);
2300 if (temp
|| methods
== OPTAB_WIDEN
)
2303 /* Use the right width libcall if that exists. */
2304 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
2305 unsignedp
, OPTAB_LIB
);
2306 if (temp
|| methods
== OPTAB_LIB
)
2309 /* Must widen and use a libcall, use either signed or unsigned. */
2310 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
2311 unsignedp
, methods
);
2312 if (!temp
&& unsignedp
)
2313 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
2314 unsignedp
, methods
);
2317 /* Undo the fiddling above. */
2319 swap_optab_enable (soptab
, mode
, true);
2323 /* Generate code to perform an operation specified by UNOPPTAB
2324 on operand OP0, with two results to TARG0 and TARG1.
2325 We assume that the order of the operands for the instruction
2326 is TARG0, TARG1, OP0.
2328 Either TARG0 or TARG1 may be zero, but what that means is that
2329 the result is not actually wanted. We will generate it into
2330 a dummy pseudo-reg and discard it. They may not both be zero.
2332 Returns 1 if this operation can be performed; 0 if not. */
2335 expand_twoval_unop (optab unoptab
, rtx op0
, rtx targ0
, rtx targ1
,
2338 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2339 enum mode_class mclass
;
2340 enum machine_mode wider_mode
;
2341 rtx_insn
*entry_last
= get_last_insn ();
2344 mclass
= GET_MODE_CLASS (mode
);
2347 targ0
= gen_reg_rtx (mode
);
2349 targ1
= gen_reg_rtx (mode
);
2351 /* Record where to go back to if we fail. */
2352 last
= get_last_insn ();
2354 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
2356 struct expand_operand ops
[3];
2357 enum insn_code icode
= optab_handler (unoptab
, mode
);
2359 create_fixed_operand (&ops
[0], targ0
);
2360 create_fixed_operand (&ops
[1], targ1
);
2361 create_convert_operand_from (&ops
[2], op0
, mode
, unsignedp
);
2362 if (maybe_expand_insn (icode
, 3, ops
))
2366 /* It can't be done in this mode. Can we do it in a wider mode? */
2368 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2370 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2371 wider_mode
!= VOIDmode
;
2372 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2374 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2376 rtx t0
= gen_reg_rtx (wider_mode
);
2377 rtx t1
= gen_reg_rtx (wider_mode
);
2378 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2380 if (expand_twoval_unop (unoptab
, cop0
, t0
, t1
, unsignedp
))
2382 convert_move (targ0
, t0
, unsignedp
);
2383 convert_move (targ1
, t1
, unsignedp
);
2387 delete_insns_since (last
);
2392 delete_insns_since (entry_last
);
2396 /* Generate code to perform an operation specified by BINOPTAB
2397 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2398 We assume that the order of the operands for the instruction
2399 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2400 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2402 Either TARG0 or TARG1 may be zero, but what that means is that
2403 the result is not actually wanted. We will generate it into
2404 a dummy pseudo-reg and discard it. They may not both be zero.
2406 Returns 1 if this operation can be performed; 0 if not. */
2409 expand_twoval_binop (optab binoptab
, rtx op0
, rtx op1
, rtx targ0
, rtx targ1
,
2412 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2413 enum mode_class mclass
;
2414 enum machine_mode wider_mode
;
2415 rtx_insn
*entry_last
= get_last_insn ();
2418 mclass
= GET_MODE_CLASS (mode
);
2421 targ0
= gen_reg_rtx (mode
);
2423 targ1
= gen_reg_rtx (mode
);
2425 /* Record where to go back to if we fail. */
2426 last
= get_last_insn ();
2428 if (optab_handler (binoptab
, mode
) != CODE_FOR_nothing
)
2430 struct expand_operand ops
[4];
2431 enum insn_code icode
= optab_handler (binoptab
, mode
);
2432 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2433 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2434 rtx xop0
= op0
, xop1
= op1
;
2436 /* If we are optimizing, force expensive constants into a register. */
2437 xop0
= avoid_expensive_constant (mode0
, binoptab
, 0, xop0
, unsignedp
);
2438 xop1
= avoid_expensive_constant (mode1
, binoptab
, 1, xop1
, unsignedp
);
2440 create_fixed_operand (&ops
[0], targ0
);
2441 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
2442 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
2443 create_fixed_operand (&ops
[3], targ1
);
2444 if (maybe_expand_insn (icode
, 4, ops
))
2446 delete_insns_since (last
);
2449 /* It can't be done in this mode. Can we do it in a wider mode? */
2451 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2453 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2454 wider_mode
!= VOIDmode
;
2455 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2457 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
)
2459 rtx t0
= gen_reg_rtx (wider_mode
);
2460 rtx t1
= gen_reg_rtx (wider_mode
);
2461 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2462 rtx cop1
= convert_modes (wider_mode
, mode
, op1
, unsignedp
);
2464 if (expand_twoval_binop (binoptab
, cop0
, cop1
,
2467 convert_move (targ0
, t0
, unsignedp
);
2468 convert_move (targ1
, t1
, unsignedp
);
2472 delete_insns_since (last
);
2477 delete_insns_since (entry_last
);
2481 /* Expand the two-valued library call indicated by BINOPTAB, but
2482 preserve only one of the values. If TARG0 is non-NULL, the first
2483 value is placed into TARG0; otherwise the second value is placed
2484 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2485 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2486 This routine assumes that the value returned by the library call is
2487 as if the return value was of an integral mode twice as wide as the
2488 mode of OP0. Returns 1 if the call was successful. */
2491 expand_twoval_binop_libfunc (optab binoptab
, rtx op0
, rtx op1
,
2492 rtx targ0
, rtx targ1
, enum rtx_code code
)
2494 enum machine_mode mode
;
2495 enum machine_mode libval_mode
;
2500 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2501 gcc_assert (!targ0
!= !targ1
);
2503 mode
= GET_MODE (op0
);
2504 libfunc
= optab_libfunc (binoptab
, mode
);
2508 /* The value returned by the library function will have twice as
2509 many bits as the nominal MODE. */
2510 libval_mode
= smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode
),
2513 libval
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
2517 /* Get the part of VAL containing the value that we want. */
2518 libval
= simplify_gen_subreg (mode
, libval
, libval_mode
,
2519 targ0
? 0 : GET_MODE_SIZE (mode
));
2520 insns
= get_insns ();
2522 /* Move the into the desired location. */
2523 emit_libcall_block (insns
, targ0
? targ0
: targ1
, libval
,
2524 gen_rtx_fmt_ee (code
, mode
, op0
, op1
));
2530 /* Wrapper around expand_unop which takes an rtx code to specify
2531 the operation to perform, not an optab pointer. All other
2532 arguments are the same. */
2534 expand_simple_unop (enum machine_mode mode
, enum rtx_code code
, rtx op0
,
2535 rtx target
, int unsignedp
)
2537 optab unop
= code_to_optab (code
);
2540 return expand_unop (mode
, unop
, op0
, target
, unsignedp
);
2546 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2548 A similar operation can be used for clrsb. UNOPTAB says which operation
2549 we are trying to expand. */
2551 widen_leading (enum machine_mode mode
, rtx op0
, rtx target
, optab unoptab
)
2553 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2554 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2556 enum machine_mode wider_mode
;
2557 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2558 wider_mode
!= VOIDmode
;
2559 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2561 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2566 last
= get_last_insn ();
2569 target
= gen_reg_rtx (mode
);
2570 xop0
= widen_operand (op0
, wider_mode
, mode
,
2571 unoptab
!= clrsb_optab
, false);
2572 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2573 unoptab
!= clrsb_optab
);
2576 (wider_mode
, sub_optab
, temp
,
2577 gen_int_mode (GET_MODE_PRECISION (wider_mode
)
2578 - GET_MODE_PRECISION (mode
),
2580 target
, true, OPTAB_DIRECT
);
2582 delete_insns_since (last
);
2591 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2592 quantities, choosing which based on whether the high word is nonzero. */
2594 expand_doubleword_clz (enum machine_mode mode
, rtx op0
, rtx target
)
2596 rtx xop0
= force_reg (mode
, op0
);
2597 rtx subhi
= gen_highpart (word_mode
, xop0
);
2598 rtx sublo
= gen_lowpart (word_mode
, xop0
);
2599 rtx_code_label
*hi0_label
= gen_label_rtx ();
2600 rtx_code_label
*after_label
= gen_label_rtx ();
2604 /* If we were not given a target, use a word_mode register, not a
2605 'mode' register. The result will fit, and nobody is expecting
2606 anything bigger (the return type of __builtin_clz* is int). */
2608 target
= gen_reg_rtx (word_mode
);
2610 /* In any case, write to a word_mode scratch in both branches of the
2611 conditional, so we can ensure there is a single move insn setting
2612 'target' to tag a REG_EQUAL note on. */
2613 result
= gen_reg_rtx (word_mode
);
2617 /* If the high word is not equal to zero,
2618 then clz of the full value is clz of the high word. */
2619 emit_cmp_and_jump_insns (subhi
, CONST0_RTX (word_mode
), EQ
, 0,
2620 word_mode
, true, hi0_label
);
2622 temp
= expand_unop_direct (word_mode
, clz_optab
, subhi
, result
, true);
2627 convert_move (result
, temp
, true);
2629 emit_jump_insn (gen_jump (after_label
));
2632 /* Else clz of the full value is clz of the low word plus the number
2633 of bits in the high word. */
2634 emit_label (hi0_label
);
2636 temp
= expand_unop_direct (word_mode
, clz_optab
, sublo
, 0, true);
2639 temp
= expand_binop (word_mode
, add_optab
, temp
,
2640 gen_int_mode (GET_MODE_BITSIZE (word_mode
), word_mode
),
2641 result
, true, OPTAB_DIRECT
);
2645 convert_move (result
, temp
, true);
2647 emit_label (after_label
);
2648 convert_move (target
, result
, true);
2653 add_equal_note (seq
, target
, CLZ
, xop0
, 0);
2665 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2667 widen_bswap (enum machine_mode mode
, rtx op0
, rtx target
)
2669 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2670 enum machine_mode wider_mode
;
2674 if (!CLASS_HAS_WIDER_MODES_P (mclass
))
2677 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2678 wider_mode
!= VOIDmode
;
2679 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2680 if (optab_handler (bswap_optab
, wider_mode
) != CODE_FOR_nothing
)
2685 last
= get_last_insn ();
2687 x
= widen_operand (op0
, wider_mode
, mode
, true, true);
2688 x
= expand_unop (wider_mode
, bswap_optab
, x
, NULL_RTX
, true);
2690 gcc_assert (GET_MODE_PRECISION (wider_mode
) == GET_MODE_BITSIZE (wider_mode
)
2691 && GET_MODE_PRECISION (mode
) == GET_MODE_BITSIZE (mode
));
2693 x
= expand_shift (RSHIFT_EXPR
, wider_mode
, x
,
2694 GET_MODE_BITSIZE (wider_mode
)
2695 - GET_MODE_BITSIZE (mode
),
2701 target
= gen_reg_rtx (mode
);
2702 emit_move_insn (target
, gen_lowpart (mode
, x
));
2705 delete_insns_since (last
);
2710 /* Try calculating bswap as two bswaps of two word-sized operands. */
2713 expand_doubleword_bswap (enum machine_mode mode
, rtx op
, rtx target
)
2717 t1
= expand_unop (word_mode
, bswap_optab
,
2718 operand_subword_force (op
, 0, mode
), NULL_RTX
, true);
2719 t0
= expand_unop (word_mode
, bswap_optab
,
2720 operand_subword_force (op
, 1, mode
), NULL_RTX
, true);
2722 if (target
== 0 || !valid_multiword_target_p (target
))
2723 target
= gen_reg_rtx (mode
);
2725 emit_clobber (target
);
2726 emit_move_insn (operand_subword (target
, 0, 1, mode
), t0
);
2727 emit_move_insn (operand_subword (target
, 1, 1, mode
), t1
);
2732 /* Try calculating (parity x) as (and (popcount x) 1), where
2733 popcount can also be done in a wider mode. */
2735 expand_parity (enum machine_mode mode
, rtx op0
, rtx target
)
2737 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2738 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2740 enum machine_mode wider_mode
;
2741 for (wider_mode
= mode
; wider_mode
!= VOIDmode
;
2742 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2744 if (optab_handler (popcount_optab
, wider_mode
) != CODE_FOR_nothing
)
2749 last
= get_last_insn ();
2752 target
= gen_reg_rtx (mode
);
2753 xop0
= widen_operand (op0
, wider_mode
, mode
, true, false);
2754 temp
= expand_unop (wider_mode
, popcount_optab
, xop0
, NULL_RTX
,
2757 temp
= expand_binop (wider_mode
, and_optab
, temp
, const1_rtx
,
2758 target
, true, OPTAB_DIRECT
);
2760 delete_insns_since (last
);
2769 /* Try calculating ctz(x) as K - clz(x & -x) ,
2770 where K is GET_MODE_PRECISION(mode) - 1.
2772 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2773 don't have to worry about what the hardware does in that case. (If
2774 the clz instruction produces the usual value at 0, which is K, the
2775 result of this code sequence will be -1; expand_ffs, below, relies
2776 on this. It might be nice to have it be K instead, for consistency
2777 with the (very few) processors that provide a ctz with a defined
2778 value, but that would take one more instruction, and it would be
2779 less convenient for expand_ffs anyway. */
2782 expand_ctz (enum machine_mode mode
, rtx op0
, rtx target
)
2787 if (optab_handler (clz_optab
, mode
) == CODE_FOR_nothing
)
2792 temp
= expand_unop_direct (mode
, neg_optab
, op0
, NULL_RTX
, true);
2794 temp
= expand_binop (mode
, and_optab
, op0
, temp
, NULL_RTX
,
2795 true, OPTAB_DIRECT
);
2797 temp
= expand_unop_direct (mode
, clz_optab
, temp
, NULL_RTX
, true);
2799 temp
= expand_binop (mode
, sub_optab
,
2800 gen_int_mode (GET_MODE_PRECISION (mode
) - 1, mode
),
2802 true, OPTAB_DIRECT
);
2812 add_equal_note (seq
, temp
, CTZ
, op0
, 0);
2818 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2819 else with the sequence used by expand_clz.
2821 The ffs builtin promises to return zero for a zero value and ctz/clz
2822 may have an undefined value in that case. If they do not give us a
2823 convenient value, we have to generate a test and branch. */
2825 expand_ffs (enum machine_mode mode
, rtx op0
, rtx target
)
2827 HOST_WIDE_INT val
= 0;
2828 bool defined_at_zero
= false;
2832 if (optab_handler (ctz_optab
, mode
) != CODE_FOR_nothing
)
2836 temp
= expand_unop_direct (mode
, ctz_optab
, op0
, 0, true);
2840 defined_at_zero
= (CTZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2);
2842 else if (optab_handler (clz_optab
, mode
) != CODE_FOR_nothing
)
2845 temp
= expand_ctz (mode
, op0
, 0);
2849 if (CLZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2)
2851 defined_at_zero
= true;
2852 val
= (GET_MODE_PRECISION (mode
) - 1) - val
;
2858 if (defined_at_zero
&& val
== -1)
2859 /* No correction needed at zero. */;
2862 /* We don't try to do anything clever with the situation found
2863 on some processors (eg Alpha) where ctz(0:mode) ==
2864 bitsize(mode). If someone can think of a way to send N to -1
2865 and leave alone all values in the range 0..N-1 (where N is a
2866 power of two), cheaper than this test-and-branch, please add it.
2868 The test-and-branch is done after the operation itself, in case
2869 the operation sets condition codes that can be recycled for this.
2870 (This is true on i386, for instance.) */
2872 rtx_code_label
*nonzero_label
= gen_label_rtx ();
2873 emit_cmp_and_jump_insns (op0
, CONST0_RTX (mode
), NE
, 0,
2874 mode
, true, nonzero_label
);
2876 convert_move (temp
, GEN_INT (-1), false);
2877 emit_label (nonzero_label
);
2880 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2881 to produce a value in the range 0..bitsize. */
2882 temp
= expand_binop (mode
, add_optab
, temp
, gen_int_mode (1, mode
),
2883 target
, false, OPTAB_DIRECT
);
2890 add_equal_note (seq
, temp
, FFS
, op0
, 0);
2899 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2900 conditions, VAL may already be a SUBREG against which we cannot generate
2901 a further SUBREG. In this case, we expect forcing the value into a
2902 register will work around the situation. */
2905 lowpart_subreg_maybe_copy (enum machine_mode omode
, rtx val
,
2906 enum machine_mode imode
)
2909 ret
= lowpart_subreg (omode
, val
, imode
);
2912 val
= force_reg (imode
, val
);
2913 ret
= lowpart_subreg (omode
, val
, imode
);
2914 gcc_assert (ret
!= NULL
);
2919 /* Expand a floating point absolute value or negation operation via a
2920 logical operation on the sign bit. */
2923 expand_absneg_bit (enum rtx_code code
, enum machine_mode mode
,
2924 rtx op0
, rtx target
)
2926 const struct real_format
*fmt
;
2927 int bitpos
, word
, nwords
, i
;
2928 enum machine_mode imode
;
2932 /* The format has to have a simple sign bit. */
2933 fmt
= REAL_MODE_FORMAT (mode
);
2937 bitpos
= fmt
->signbit_rw
;
2941 /* Don't create negative zeros if the format doesn't support them. */
2942 if (code
== NEG
&& !fmt
->has_signed_zero
)
2945 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
2947 imode
= int_mode_for_mode (mode
);
2948 if (imode
== BLKmode
)
2957 if (FLOAT_WORDS_BIG_ENDIAN
)
2958 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
2960 word
= bitpos
/ BITS_PER_WORD
;
2961 bitpos
= bitpos
% BITS_PER_WORD
;
2962 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
2965 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
2971 || (nwords
> 1 && !valid_multiword_target_p (target
)))
2972 target
= gen_reg_rtx (mode
);
2978 for (i
= 0; i
< nwords
; ++i
)
2980 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
2981 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
2985 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2987 immed_wide_int_const (mask
, imode
),
2988 targ_piece
, 1, OPTAB_LIB_WIDEN
);
2989 if (temp
!= targ_piece
)
2990 emit_move_insn (targ_piece
, temp
);
2993 emit_move_insn (targ_piece
, op0_piece
);
2996 insns
= get_insns ();
3003 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
3004 gen_lowpart (imode
, op0
),
3005 immed_wide_int_const (mask
, imode
),
3006 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3007 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3009 set_dst_reg_note (get_last_insn (), REG_EQUAL
,
3010 gen_rtx_fmt_e (code
, mode
, copy_rtx (op0
)),
3017 /* As expand_unop, but will fail rather than attempt the operation in a
3018 different mode or with a libcall. */
3020 expand_unop_direct (enum machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
3023 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
3025 struct expand_operand ops
[2];
3026 enum insn_code icode
= optab_handler (unoptab
, mode
);
3027 rtx_insn
*last
= get_last_insn ();
3030 create_output_operand (&ops
[0], target
, mode
);
3031 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
3032 pat
= maybe_gen_insn (icode
, 2, ops
);
3035 if (INSN_P (pat
) && NEXT_INSN (as_a
<rtx_insn
*> (pat
)) != NULL_RTX
3036 && ! add_equal_note (as_a
<rtx_insn
*> (pat
), ops
[0].value
,
3037 optab_to_code (unoptab
),
3038 ops
[1].value
, NULL_RTX
))
3040 delete_insns_since (last
);
3041 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
3046 return ops
[0].value
;
3052 /* Generate code to perform an operation specified by UNOPTAB
3053 on operand OP0, with result having machine-mode MODE.
3055 UNSIGNEDP is for the case where we have to widen the operands
3056 to perform the operation. It says to use zero-extension.
3058 If TARGET is nonzero, the value
3059 is generated there, if it is convenient to do so.
3060 In all cases an rtx is returned for the locus of the value;
3061 this may or may not be TARGET. */
3064 expand_unop (enum machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
3067 enum mode_class mclass
= GET_MODE_CLASS (mode
);
3068 enum machine_mode wider_mode
;
3072 temp
= expand_unop_direct (mode
, unoptab
, op0
, target
, unsignedp
);
3076 /* It can't be done in this mode. Can we open-code it in a wider mode? */
3078 /* Widening (or narrowing) clz needs special treatment. */
3079 if (unoptab
== clz_optab
)
3081 temp
= widen_leading (mode
, op0
, target
, unoptab
);
3085 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
3086 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
3088 temp
= expand_doubleword_clz (mode
, op0
, target
);
3096 if (unoptab
== clrsb_optab
)
3098 temp
= widen_leading (mode
, op0
, target
, unoptab
);
3104 /* Widening (or narrowing) bswap needs special treatment. */
3105 if (unoptab
== bswap_optab
)
3107 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
3108 or ROTATERT. First try these directly; if this fails, then try the
3109 obvious pair of shifts with allowed widening, as this will probably
3110 be always more efficient than the other fallback methods. */
3116 if (optab_handler (rotl_optab
, mode
) != CODE_FOR_nothing
)
3118 temp
= expand_binop (mode
, rotl_optab
, op0
, GEN_INT (8), target
,
3119 unsignedp
, OPTAB_DIRECT
);
3124 if (optab_handler (rotr_optab
, mode
) != CODE_FOR_nothing
)
3126 temp
= expand_binop (mode
, rotr_optab
, op0
, GEN_INT (8), target
,
3127 unsignedp
, OPTAB_DIRECT
);
3132 last
= get_last_insn ();
3134 temp1
= expand_binop (mode
, ashl_optab
, op0
, GEN_INT (8), NULL_RTX
,
3135 unsignedp
, OPTAB_WIDEN
);
3136 temp2
= expand_binop (mode
, lshr_optab
, op0
, GEN_INT (8), NULL_RTX
,
3137 unsignedp
, OPTAB_WIDEN
);
3140 temp
= expand_binop (mode
, ior_optab
, temp1
, temp2
, target
,
3141 unsignedp
, OPTAB_WIDEN
);
3146 delete_insns_since (last
);
3149 temp
= widen_bswap (mode
, op0
, target
);
3153 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
3154 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
3156 temp
= expand_doubleword_bswap (mode
, op0
, target
);
3164 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3165 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
3166 wider_mode
!= VOIDmode
;
3167 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3169 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
3172 rtx_insn
*last
= get_last_insn ();
3174 /* For certain operations, we need not actually extend
3175 the narrow operand, as long as we will truncate the
3176 results to the same narrowness. */
3178 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3179 (unoptab
== neg_optab
3180 || unoptab
== one_cmpl_optab
)
3181 && mclass
== MODE_INT
);
3183 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3188 if (mclass
!= MODE_INT
3189 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
3192 target
= gen_reg_rtx (mode
);
3193 convert_move (target
, temp
, 0);
3197 return gen_lowpart (mode
, temp
);
3200 delete_insns_since (last
);
3204 /* These can be done a word at a time. */
3205 if (unoptab
== one_cmpl_optab
3206 && mclass
== MODE_INT
3207 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
3208 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
3213 if (target
== 0 || target
== op0
|| !valid_multiword_target_p (target
))
3214 target
= gen_reg_rtx (mode
);
3218 /* Do the actual arithmetic. */
3219 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
3221 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
3222 rtx x
= expand_unop (word_mode
, unoptab
,
3223 operand_subword_force (op0
, i
, mode
),
3224 target_piece
, unsignedp
);
3226 if (target_piece
!= x
)
3227 emit_move_insn (target_piece
, x
);
3230 insns
= get_insns ();
3237 if (optab_to_code (unoptab
) == NEG
)
3239 /* Try negating floating point values by flipping the sign bit. */
3240 if (SCALAR_FLOAT_MODE_P (mode
))
3242 temp
= expand_absneg_bit (NEG
, mode
, op0
, target
);
3247 /* If there is no negation pattern, and we have no negative zero,
3248 try subtracting from zero. */
3249 if (!HONOR_SIGNED_ZEROS (mode
))
3251 temp
= expand_binop (mode
, (unoptab
== negv_optab
3252 ? subv_optab
: sub_optab
),
3253 CONST0_RTX (mode
), op0
, target
,
3254 unsignedp
, OPTAB_DIRECT
);
3260 /* Try calculating parity (x) as popcount (x) % 2. */
3261 if (unoptab
== parity_optab
)
3263 temp
= expand_parity (mode
, op0
, target
);
3268 /* Try implementing ffs (x) in terms of clz (x). */
3269 if (unoptab
== ffs_optab
)
3271 temp
= expand_ffs (mode
, op0
, target
);
3276 /* Try implementing ctz (x) in terms of clz (x). */
3277 if (unoptab
== ctz_optab
)
3279 temp
= expand_ctz (mode
, op0
, target
);
3285 /* Now try a library call in this mode. */
3286 libfunc
= optab_libfunc (unoptab
, mode
);
3292 enum machine_mode outmode
= mode
;
3294 /* All of these functions return small values. Thus we choose to
3295 have them return something that isn't a double-word. */
3296 if (unoptab
== ffs_optab
|| unoptab
== clz_optab
|| unoptab
== ctz_optab
3297 || unoptab
== clrsb_optab
|| unoptab
== popcount_optab
3298 || unoptab
== parity_optab
)
3300 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node
),
3301 optab_libfunc (unoptab
, mode
)));
3305 /* Pass 1 for NO_QUEUE so we don't lose any increments
3306 if the libcall is cse'd or moved. */
3307 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, outmode
,
3309 insns
= get_insns ();
3312 target
= gen_reg_rtx (outmode
);
3313 eq_value
= gen_rtx_fmt_e (optab_to_code (unoptab
), mode
, op0
);
3314 if (GET_MODE_SIZE (outmode
) < GET_MODE_SIZE (mode
))
3315 eq_value
= simplify_gen_unary (TRUNCATE
, outmode
, eq_value
, mode
);
3316 else if (GET_MODE_SIZE (outmode
) > GET_MODE_SIZE (mode
))
3317 eq_value
= simplify_gen_unary (ZERO_EXTEND
, outmode
, eq_value
, mode
);
3318 emit_libcall_block_1 (insns
, target
, value
, eq_value
,
3319 trapv_unoptab_p (unoptab
));
3324 /* It can't be done in this mode. Can we do it in a wider mode? */
3326 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3328 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
3329 wider_mode
!= VOIDmode
;
3330 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3332 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
3333 || optab_libfunc (unoptab
, wider_mode
))
3336 rtx_insn
*last
= get_last_insn ();
3338 /* For certain operations, we need not actually extend
3339 the narrow operand, as long as we will truncate the
3340 results to the same narrowness. */
3341 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3342 (unoptab
== neg_optab
3343 || unoptab
== one_cmpl_optab
3344 || unoptab
== bswap_optab
)
3345 && mclass
== MODE_INT
);
3347 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3350 /* If we are generating clz using wider mode, adjust the
3351 result. Similarly for clrsb. */
3352 if ((unoptab
== clz_optab
|| unoptab
== clrsb_optab
)
3355 (wider_mode
, sub_optab
, temp
,
3356 gen_int_mode (GET_MODE_PRECISION (wider_mode
)
3357 - GET_MODE_PRECISION (mode
),
3359 target
, true, OPTAB_DIRECT
);
3361 /* Likewise for bswap. */
3362 if (unoptab
== bswap_optab
&& temp
!= 0)
3364 gcc_assert (GET_MODE_PRECISION (wider_mode
)
3365 == GET_MODE_BITSIZE (wider_mode
)
3366 && GET_MODE_PRECISION (mode
)
3367 == GET_MODE_BITSIZE (mode
));
3369 temp
= expand_shift (RSHIFT_EXPR
, wider_mode
, temp
,
3370 GET_MODE_BITSIZE (wider_mode
)
3371 - GET_MODE_BITSIZE (mode
),
3377 if (mclass
!= MODE_INT
)
3380 target
= gen_reg_rtx (mode
);
3381 convert_move (target
, temp
, 0);
3385 return gen_lowpart (mode
, temp
);
3388 delete_insns_since (last
);
3393 /* One final attempt at implementing negation via subtraction,
3394 this time allowing widening of the operand. */
3395 if (optab_to_code (unoptab
) == NEG
&& !HONOR_SIGNED_ZEROS (mode
))
3398 temp
= expand_binop (mode
,
3399 unoptab
== negv_optab
? subv_optab
: sub_optab
,
3400 CONST0_RTX (mode
), op0
,
3401 target
, unsignedp
, OPTAB_LIB_WIDEN
);
3409 /* Emit code to compute the absolute value of OP0, with result to
3410 TARGET if convenient. (TARGET may be 0.) The return value says
3411 where the result actually is to be found.
3413 MODE is the mode of the operand; the mode of the result is
3414 different but can be deduced from MODE.
3419 expand_abs_nojump (enum machine_mode mode
, rtx op0
, rtx target
,
3420 int result_unsignedp
)
3424 if (GET_MODE_CLASS (mode
) != MODE_INT
3426 result_unsignedp
= 1;
3428 /* First try to do it with a special abs instruction. */
3429 temp
= expand_unop (mode
, result_unsignedp
? abs_optab
: absv_optab
,
3434 /* For floating point modes, try clearing the sign bit. */
3435 if (SCALAR_FLOAT_MODE_P (mode
))
3437 temp
= expand_absneg_bit (ABS
, mode
, op0
, target
);
3442 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3443 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
3444 && !HONOR_SIGNED_ZEROS (mode
))
3446 rtx_insn
*last
= get_last_insn ();
3448 temp
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3451 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3457 delete_insns_since (last
);
3460 /* If this machine has expensive jumps, we can do integer absolute
3461 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3462 where W is the width of MODE. */
3464 if (GET_MODE_CLASS (mode
) == MODE_INT
3465 && BRANCH_COST (optimize_insn_for_speed_p (),
3468 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
3469 GET_MODE_PRECISION (mode
) - 1,
3472 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
3475 temp
= expand_binop (mode
, result_unsignedp
? sub_optab
: subv_optab
,
3476 temp
, extended
, target
, 0, OPTAB_LIB_WIDEN
);
3486 expand_abs (enum machine_mode mode
, rtx op0
, rtx target
,
3487 int result_unsignedp
, int safe
)
3490 rtx_code_label
*op1
;
3492 if (GET_MODE_CLASS (mode
) != MODE_INT
3494 result_unsignedp
= 1;
3496 temp
= expand_abs_nojump (mode
, op0
, target
, result_unsignedp
);
3500 /* If that does not win, use conditional jump and negate. */
3502 /* It is safe to use the target if it is the same
3503 as the source if this is also a pseudo register */
3504 if (op0
== target
&& REG_P (op0
)
3505 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
3508 op1
= gen_label_rtx ();
3509 if (target
== 0 || ! safe
3510 || GET_MODE (target
) != mode
3511 || (MEM_P (target
) && MEM_VOLATILE_P (target
))
3513 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
3514 target
= gen_reg_rtx (mode
);
3516 emit_move_insn (target
, op0
);
3519 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
3520 NULL_RTX
, NULL_RTX
, op1
, -1);
3522 op0
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3525 emit_move_insn (target
, op0
);
3531 /* Emit code to compute the one's complement absolute value of OP0
3532 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3533 (TARGET may be NULL_RTX.) The return value says where the result
3534 actually is to be found.
3536 MODE is the mode of the operand; the mode of the result is
3537 different but can be deduced from MODE. */
3540 expand_one_cmpl_abs_nojump (enum machine_mode mode
, rtx op0
, rtx target
)
3544 /* Not applicable for floating point modes. */
3545 if (FLOAT_MODE_P (mode
))
3548 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3549 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
)
3551 rtx_insn
*last
= get_last_insn ();
3553 temp
= expand_unop (mode
, one_cmpl_optab
, op0
, NULL_RTX
, 0);
3555 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3561 delete_insns_since (last
);
3564 /* If this machine has expensive jumps, we can do one's complement
3565 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3567 if (GET_MODE_CLASS (mode
) == MODE_INT
3568 && BRANCH_COST (optimize_insn_for_speed_p (),
3571 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
3572 GET_MODE_PRECISION (mode
) - 1,
3575 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
3585 /* A subroutine of expand_copysign, perform the copysign operation using the
3586 abs and neg primitives advertised to exist on the target. The assumption
3587 is that we have a split register file, and leaving op0 in fp registers,
3588 and not playing with subregs so much, will help the register allocator. */
3591 expand_copysign_absneg (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3592 int bitpos
, bool op0_is_abs
)
3594 enum machine_mode imode
;
3595 enum insn_code icode
;
3597 rtx_code_label
*label
;
3602 /* Check if the back end provides an insn that handles signbit for the
3604 icode
= optab_handler (signbit_optab
, mode
);
3605 if (icode
!= CODE_FOR_nothing
)
3607 imode
= insn_data
[(int) icode
].operand
[0].mode
;
3608 sign
= gen_reg_rtx (imode
);
3609 emit_unop_insn (icode
, sign
, op1
, UNKNOWN
);
3613 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3615 imode
= int_mode_for_mode (mode
);
3616 if (imode
== BLKmode
)
3618 op1
= gen_lowpart (imode
, op1
);
3625 if (FLOAT_WORDS_BIG_ENDIAN
)
3626 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3628 word
= bitpos
/ BITS_PER_WORD
;
3629 bitpos
= bitpos
% BITS_PER_WORD
;
3630 op1
= operand_subword_force (op1
, word
, mode
);
3633 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3634 sign
= expand_binop (imode
, and_optab
, op1
,
3635 immed_wide_int_const (mask
, imode
),
3636 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3641 op0
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
3648 if (target
== NULL_RTX
)
3649 target
= copy_to_reg (op0
);
3651 emit_move_insn (target
, op0
);
3654 label
= gen_label_rtx ();
3655 emit_cmp_and_jump_insns (sign
, const0_rtx
, EQ
, NULL_RTX
, imode
, 1, label
);
3657 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3658 op0
= simplify_unary_operation (NEG
, mode
, op0
, mode
);
3660 op0
= expand_unop (mode
, neg_optab
, op0
, target
, 0);
3662 emit_move_insn (target
, op0
);
3670 /* A subroutine of expand_copysign, perform the entire copysign operation
3671 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3672 is true if op0 is known to have its sign bit clear. */
3675 expand_copysign_bit (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3676 int bitpos
, bool op0_is_abs
)
3678 enum machine_mode imode
;
3679 int word
, nwords
, i
;
3683 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3685 imode
= int_mode_for_mode (mode
);
3686 if (imode
== BLKmode
)
3695 if (FLOAT_WORDS_BIG_ENDIAN
)
3696 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3698 word
= bitpos
/ BITS_PER_WORD
;
3699 bitpos
= bitpos
% BITS_PER_WORD
;
3700 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
3703 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3708 || (nwords
> 1 && !valid_multiword_target_p (target
)))
3709 target
= gen_reg_rtx (mode
);
3715 for (i
= 0; i
< nwords
; ++i
)
3717 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
3718 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
3724 = expand_binop (imode
, and_optab
, op0_piece
,
3725 immed_wide_int_const (~mask
, imode
),
3726 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3727 op1
= expand_binop (imode
, and_optab
,
3728 operand_subword_force (op1
, i
, mode
),
3729 immed_wide_int_const (mask
, imode
),
3730 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3732 temp
= expand_binop (imode
, ior_optab
, op0_piece
, op1
,
3733 targ_piece
, 1, OPTAB_LIB_WIDEN
);
3734 if (temp
!= targ_piece
)
3735 emit_move_insn (targ_piece
, temp
);
3738 emit_move_insn (targ_piece
, op0_piece
);
3741 insns
= get_insns ();
3748 op1
= expand_binop (imode
, and_optab
, gen_lowpart (imode
, op1
),
3749 immed_wide_int_const (mask
, imode
),
3750 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3752 op0
= gen_lowpart (imode
, op0
);
3754 op0
= expand_binop (imode
, and_optab
, op0
,
3755 immed_wide_int_const (~mask
, imode
),
3756 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3758 temp
= expand_binop (imode
, ior_optab
, op0
, op1
,
3759 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3760 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3766 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3767 scalar floating point mode. Return NULL if we do not know how to
3768 expand the operation inline. */
3771 expand_copysign (rtx op0
, rtx op1
, rtx target
)
3773 enum machine_mode mode
= GET_MODE (op0
);
3774 const struct real_format
*fmt
;
3778 gcc_assert (SCALAR_FLOAT_MODE_P (mode
));
3779 gcc_assert (GET_MODE (op1
) == mode
);
3781 /* First try to do it with a special instruction. */
3782 temp
= expand_binop (mode
, copysign_optab
, op0
, op1
,
3783 target
, 0, OPTAB_DIRECT
);
3787 fmt
= REAL_MODE_FORMAT (mode
);
3788 if (fmt
== NULL
|| !fmt
->has_signed_zero
)
3792 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3794 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0
)))
3795 op0
= simplify_unary_operation (ABS
, mode
, op0
, mode
);
3799 if (fmt
->signbit_ro
>= 0
3800 && (CONST_DOUBLE_AS_FLOAT_P (op0
)
3801 || (optab_handler (neg_optab
, mode
) != CODE_FOR_nothing
3802 && optab_handler (abs_optab
, mode
) != CODE_FOR_nothing
)))
3804 temp
= expand_copysign_absneg (mode
, op0
, op1
, target
,
3805 fmt
->signbit_ro
, op0_is_abs
);
3810 if (fmt
->signbit_rw
< 0)
3812 return expand_copysign_bit (mode
, op0
, op1
, target
,
3813 fmt
->signbit_rw
, op0_is_abs
);
3816 /* Generate an instruction whose insn-code is INSN_CODE,
3817 with two operands: an output TARGET and an input OP0.
3818 TARGET *must* be nonzero, and the output is always stored there.
3819 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3820 the value that is stored into TARGET.
3822 Return false if expansion failed. */
3825 maybe_emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
,
3828 struct expand_operand ops
[2];
3831 create_output_operand (&ops
[0], target
, GET_MODE (target
));
3832 create_input_operand (&ops
[1], op0
, GET_MODE (op0
));
3833 pat
= maybe_gen_insn (icode
, 2, ops
);
3837 if (INSN_P (pat
) && NEXT_INSN (as_a
<rtx_insn
*> (pat
)) != NULL_RTX
3839 add_equal_note (as_a
<rtx_insn
*> (pat
), ops
[0].value
, code
, ops
[1].value
,
3844 if (ops
[0].value
!= target
)
3845 emit_move_insn (target
, ops
[0].value
);
3848 /* Generate an instruction whose insn-code is INSN_CODE,
3849 with two operands: an output TARGET and an input OP0.
3850 TARGET *must* be nonzero, and the output is always stored there.
3851 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3852 the value that is stored into TARGET. */
3855 emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
, enum rtx_code code
)
3857 bool ok
= maybe_emit_unop_insn (icode
, target
, op0
, code
);
3861 struct no_conflict_data
3864 rtx_insn
*first
, *insn
;
3868 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3869 the currently examined clobber / store has to stay in the list of
3870 insns that constitute the actual libcall block. */
3872 no_conflict_move_test (rtx dest
, const_rtx set
, void *p0
)
3874 struct no_conflict_data
*p
= (struct no_conflict_data
*) p0
;
3876 /* If this inns directly contributes to setting the target, it must stay. */
3877 if (reg_overlap_mentioned_p (p
->target
, dest
))
3878 p
->must_stay
= true;
3879 /* If we haven't committed to keeping any other insns in the list yet,
3880 there is nothing more to check. */
3881 else if (p
->insn
== p
->first
)
3883 /* If this insn sets / clobbers a register that feeds one of the insns
3884 already in the list, this insn has to stay too. */
3885 else if (reg_overlap_mentioned_p (dest
, PATTERN (p
->first
))
3886 || (CALL_P (p
->first
) && (find_reg_fusage (p
->first
, USE
, dest
)))
3887 || reg_used_between_p (dest
, p
->first
, p
->insn
)
3888 /* Likewise if this insn depends on a register set by a previous
3889 insn in the list, or if it sets a result (presumably a hard
3890 register) that is set or clobbered by a previous insn.
3891 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3892 SET_DEST perform the former check on the address, and the latter
3893 check on the MEM. */
3894 || (GET_CODE (set
) == SET
3895 && (modified_in_p (SET_SRC (set
), p
->first
)
3896 || modified_in_p (SET_DEST (set
), p
->first
)
3897 || modified_between_p (SET_SRC (set
), p
->first
, p
->insn
)
3898 || modified_between_p (SET_DEST (set
), p
->first
, p
->insn
))))
3899 p
->must_stay
= true;
3903 /* Emit code to make a call to a constant function or a library call.
3905 INSNS is a list containing all insns emitted in the call.
3906 These insns leave the result in RESULT. Our block is to copy RESULT
3907 to TARGET, which is logically equivalent to EQUIV.
3909 We first emit any insns that set a pseudo on the assumption that these are
3910 loading constants into registers; doing so allows them to be safely cse'ed
3911 between blocks. Then we emit all the other insns in the block, followed by
3912 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3913 note with an operand of EQUIV. */
3916 emit_libcall_block_1 (rtx_insn
*insns
, rtx target
, rtx result
, rtx equiv
,
3917 bool equiv_may_trap
)
3919 rtx final_dest
= target
;
3920 rtx_insn
*next
, *last
, *insn
;
3922 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3923 into a MEM later. Protect the libcall block from this change. */
3924 if (! REG_P (target
) || REG_USERVAR_P (target
))
3925 target
= gen_reg_rtx (GET_MODE (target
));
3927 /* If we're using non-call exceptions, a libcall corresponding to an
3928 operation that may trap may also trap. */
3929 /* ??? See the comment in front of make_reg_eh_region_note. */
3930 if (cfun
->can_throw_non_call_exceptions
3931 && (equiv_may_trap
|| may_trap_p (equiv
)))
3933 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3936 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
3939 int lp_nr
= INTVAL (XEXP (note
, 0));
3940 if (lp_nr
== 0 || lp_nr
== INT_MIN
)
3941 remove_note (insn
, note
);
3947 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3948 reg note to indicate that this call cannot throw or execute a nonlocal
3949 goto (unless there is already a REG_EH_REGION note, in which case
3951 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3953 make_reg_eh_region_note_nothrow_nononlocal (insn
);
3956 /* First emit all insns that set pseudos. Remove them from the list as
3957 we go. Avoid insns that set pseudos which were referenced in previous
3958 insns. These can be generated by move_by_pieces, for example,
3959 to update an address. Similarly, avoid insns that reference things
3960 set in previous insns. */
3962 for (insn
= insns
; insn
; insn
= next
)
3964 rtx set
= single_set (insn
);
3966 next
= NEXT_INSN (insn
);
3968 if (set
!= 0 && REG_P (SET_DEST (set
))
3969 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
)
3971 struct no_conflict_data data
;
3973 data
.target
= const0_rtx
;
3977 note_stores (PATTERN (insn
), no_conflict_move_test
, &data
);
3978 if (! data
.must_stay
)
3980 if (PREV_INSN (insn
))
3981 SET_NEXT_INSN (PREV_INSN (insn
)) = next
;
3986 SET_PREV_INSN (next
) = PREV_INSN (insn
);
3992 /* Some ports use a loop to copy large arguments onto the stack.
3993 Don't move anything outside such a loop. */
3998 /* Write the remaining insns followed by the final copy. */
3999 for (insn
= insns
; insn
; insn
= next
)
4001 next
= NEXT_INSN (insn
);
4006 last
= emit_move_insn (target
, result
);
4007 set_dst_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
), target
);
4009 if (final_dest
!= target
)
4010 emit_move_insn (final_dest
, target
);
4014 emit_libcall_block (rtx insns
, rtx target
, rtx result
, rtx equiv
)
4016 emit_libcall_block_1 (safe_as_a
<rtx_insn
*> (insns
),
4017 target
, result
, equiv
, false);
4020 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
4021 PURPOSE describes how this comparison will be used. CODE is the rtx
4022 comparison code we will be using.
4024 ??? Actually, CODE is slightly weaker than that. A target is still
4025 required to implement all of the normal bcc operations, but not
4026 required to implement all (or any) of the unordered bcc operations. */
4029 can_compare_p (enum rtx_code code
, enum machine_mode mode
,
4030 enum can_compare_purpose purpose
)
4033 test
= gen_rtx_fmt_ee (code
, mode
, const0_rtx
, const0_rtx
);
4036 enum insn_code icode
;
4038 if (purpose
== ccp_jump
4039 && (icode
= optab_handler (cbranch_optab
, mode
)) != CODE_FOR_nothing
4040 && insn_operand_matches (icode
, 0, test
))
4042 if (purpose
== ccp_store_flag
4043 && (icode
= optab_handler (cstore_optab
, mode
)) != CODE_FOR_nothing
4044 && insn_operand_matches (icode
, 1, test
))
4046 if (purpose
== ccp_cmov
4047 && optab_handler (cmov_optab
, mode
) != CODE_FOR_nothing
)
4050 mode
= GET_MODE_WIDER_MODE (mode
);
4051 PUT_MODE (test
, mode
);
4053 while (mode
!= VOIDmode
);
4058 /* This function is called when we are going to emit a compare instruction that
4059 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
4061 *PMODE is the mode of the inputs (in case they are const_int).
4062 *PUNSIGNEDP nonzero says that the operands are unsigned;
4063 this matters if they need to be widened (as given by METHODS).
4065 If they have mode BLKmode, then SIZE specifies the size of both operands.
4067 This function performs all the setup necessary so that the caller only has
4068 to emit a single comparison insn. This setup can involve doing a BLKmode
4069 comparison or emitting a library call to perform the comparison if no insn
4070 is available to handle it.
4071 The values which are passed in through pointers can be modified; the caller
4072 should perform the comparison on the modified values. Constant
4073 comparisons must have already been folded. */
4076 prepare_cmp_insn (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4077 int unsignedp
, enum optab_methods methods
,
4078 rtx
*ptest
, enum machine_mode
*pmode
)
4080 enum machine_mode mode
= *pmode
;
4082 enum machine_mode cmp_mode
;
4083 enum mode_class mclass
;
4085 /* The other methods are not needed. */
4086 gcc_assert (methods
== OPTAB_DIRECT
|| methods
== OPTAB_WIDEN
4087 || methods
== OPTAB_LIB_WIDEN
);
4089 /* If we are optimizing, force expensive constants into a register. */
4090 if (CONSTANT_P (x
) && optimize
4091 && (rtx_cost (x
, COMPARE
, 0, optimize_insn_for_speed_p ())
4092 > COSTS_N_INSNS (1)))
4093 x
= force_reg (mode
, x
);
4095 if (CONSTANT_P (y
) && optimize
4096 && (rtx_cost (y
, COMPARE
, 1, optimize_insn_for_speed_p ())
4097 > COSTS_N_INSNS (1)))
4098 y
= force_reg (mode
, y
);
4101 /* Make sure if we have a canonical comparison. The RTL
4102 documentation states that canonical comparisons are required only
4103 for targets which have cc0. */
4104 gcc_assert (!CONSTANT_P (x
) || CONSTANT_P (y
));
4107 /* Don't let both operands fail to indicate the mode. */
4108 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
4109 x
= force_reg (mode
, x
);
4110 if (mode
== VOIDmode
)
4111 mode
= GET_MODE (x
) != VOIDmode
? GET_MODE (x
) : GET_MODE (y
);
4113 /* Handle all BLKmode compares. */
4115 if (mode
== BLKmode
)
4117 enum machine_mode result_mode
;
4118 enum insn_code cmp_code
;
4123 = GEN_INT (MIN (MEM_ALIGN (x
), MEM_ALIGN (y
)) / BITS_PER_UNIT
);
4127 /* Try to use a memory block compare insn - either cmpstr
4128 or cmpmem will do. */
4129 for (cmp_mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
4130 cmp_mode
!= VOIDmode
;
4131 cmp_mode
= GET_MODE_WIDER_MODE (cmp_mode
))
4133 cmp_code
= direct_optab_handler (cmpmem_optab
, cmp_mode
);
4134 if (cmp_code
== CODE_FOR_nothing
)
4135 cmp_code
= direct_optab_handler (cmpstr_optab
, cmp_mode
);
4136 if (cmp_code
== CODE_FOR_nothing
)
4137 cmp_code
= direct_optab_handler (cmpstrn_optab
, cmp_mode
);
4138 if (cmp_code
== CODE_FOR_nothing
)
4141 /* Must make sure the size fits the insn's mode. */
4142 if ((CONST_INT_P (size
)
4143 && INTVAL (size
) >= (1 << GET_MODE_BITSIZE (cmp_mode
)))
4144 || (GET_MODE_BITSIZE (GET_MODE (size
))
4145 > GET_MODE_BITSIZE (cmp_mode
)))
4148 result_mode
= insn_data
[cmp_code
].operand
[0].mode
;
4149 result
= gen_reg_rtx (result_mode
);
4150 size
= convert_to_mode (cmp_mode
, size
, 1);
4151 emit_insn (GEN_FCN (cmp_code
) (result
, x
, y
, size
, opalign
));
4153 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, result
, const0_rtx
);
4154 *pmode
= result_mode
;
4158 if (methods
!= OPTAB_LIB
&& methods
!= OPTAB_LIB_WIDEN
)
4161 /* Otherwise call a library function, memcmp. */
4162 libfunc
= memcmp_libfunc
;
4163 length_type
= sizetype
;
4164 result_mode
= TYPE_MODE (integer_type_node
);
4165 cmp_mode
= TYPE_MODE (length_type
);
4166 size
= convert_to_mode (TYPE_MODE (length_type
), size
,
4167 TYPE_UNSIGNED (length_type
));
4169 result
= emit_library_call_value (libfunc
, 0, LCT_PURE
,
4177 methods
= OPTAB_LIB_WIDEN
;
4181 /* Don't allow operands to the compare to trap, as that can put the
4182 compare and branch in different basic blocks. */
4183 if (cfun
->can_throw_non_call_exceptions
)
4186 x
= force_reg (mode
, x
);
4188 y
= force_reg (mode
, y
);
4191 if (GET_MODE_CLASS (mode
) == MODE_CC
)
4193 gcc_assert (can_compare_p (comparison
, CCmode
, ccp_jump
));
4194 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
4198 mclass
= GET_MODE_CLASS (mode
);
4199 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
4203 enum insn_code icode
;
4204 icode
= optab_handler (cbranch_optab
, cmp_mode
);
4205 if (icode
!= CODE_FOR_nothing
4206 && insn_operand_matches (icode
, 0, test
))
4208 rtx_insn
*last
= get_last_insn ();
4209 rtx op0
= prepare_operand (icode
, x
, 1, mode
, cmp_mode
, unsignedp
);
4210 rtx op1
= prepare_operand (icode
, y
, 2, mode
, cmp_mode
, unsignedp
);
4212 && insn_operand_matches (icode
, 1, op0
)
4213 && insn_operand_matches (icode
, 2, op1
))
4215 XEXP (test
, 0) = op0
;
4216 XEXP (test
, 1) = op1
;
4221 delete_insns_since (last
);
4224 if (methods
== OPTAB_DIRECT
|| !CLASS_HAS_WIDER_MODES_P (mclass
))
4226 cmp_mode
= GET_MODE_WIDER_MODE (cmp_mode
);
4228 while (cmp_mode
!= VOIDmode
);
4230 if (methods
!= OPTAB_LIB_WIDEN
)
4233 if (!SCALAR_FLOAT_MODE_P (mode
))
4236 enum machine_mode ret_mode
;
4238 /* Handle a libcall just for the mode we are using. */
4239 libfunc
= optab_libfunc (cmp_optab
, mode
);
4240 gcc_assert (libfunc
);
4242 /* If we want unsigned, and this mode has a distinct unsigned
4243 comparison routine, use that. */
4246 rtx ulibfunc
= optab_libfunc (ucmp_optab
, mode
);
4251 ret_mode
= targetm
.libgcc_cmp_return_mode ();
4252 result
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4253 ret_mode
, 2, x
, mode
, y
, mode
);
4255 /* There are two kinds of comparison routines. Biased routines
4256 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4257 of gcc expect that the comparison operation is equivalent
4258 to the modified comparison. For signed comparisons compare the
4259 result against 1 in the biased case, and zero in the unbiased
4260 case. For unsigned comparisons always compare against 1 after
4261 biasing the unbiased result by adding 1. This gives us a way to
4263 The comparisons in the fixed-point helper library are always
4268 if (!TARGET_LIB_INT_CMP_BIASED
&& !ALL_FIXED_POINT_MODE_P (mode
))
4271 x
= plus_constant (ret_mode
, result
, 1);
4277 prepare_cmp_insn (x
, y
, comparison
, NULL_RTX
, unsignedp
, methods
,
4281 prepare_float_lib_cmp (x
, y
, comparison
, ptest
, pmode
);
4289 /* Before emitting an insn with code ICODE, make sure that X, which is going
4290 to be used for operand OPNUM of the insn, is converted from mode MODE to
4291 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4292 that it is accepted by the operand predicate. Return the new value. */
4295 prepare_operand (enum insn_code icode
, rtx x
, int opnum
, enum machine_mode mode
,
4296 enum machine_mode wider_mode
, int unsignedp
)
4298 if (mode
!= wider_mode
)
4299 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
4301 if (!insn_operand_matches (icode
, opnum
, x
))
4303 if (reload_completed
)
4305 x
= copy_to_mode_reg (insn_data
[(int) icode
].operand
[opnum
].mode
, x
);
4311 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4312 we can do the branch. */
4315 emit_cmp_and_jump_insn_1 (rtx test
, enum machine_mode mode
, rtx label
, int prob
)
4317 enum machine_mode optab_mode
;
4318 enum mode_class mclass
;
4319 enum insn_code icode
;
4322 mclass
= GET_MODE_CLASS (mode
);
4323 optab_mode
= (mclass
== MODE_CC
) ? CCmode
: mode
;
4324 icode
= optab_handler (cbranch_optab
, optab_mode
);
4326 gcc_assert (icode
!= CODE_FOR_nothing
);
4327 gcc_assert (insn_operand_matches (icode
, 0, test
));
4328 insn
= emit_jump_insn (GEN_FCN (icode
) (test
, XEXP (test
, 0),
4329 XEXP (test
, 1), label
));
4331 && profile_status_for_fn (cfun
) != PROFILE_ABSENT
4334 && any_condjump_p (insn
)
4335 && !find_reg_note (insn
, REG_BR_PROB
, 0))
4336 add_int_reg_note (insn
, REG_BR_PROB
, prob
);
4339 /* Generate code to compare X with Y so that the condition codes are
4340 set and to jump to LABEL if the condition is true. If X is a
4341 constant and Y is not a constant, then the comparison is swapped to
4342 ensure that the comparison RTL has the canonical form.
4344 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4345 need to be widened. UNSIGNEDP is also used to select the proper
4346 branch condition code.
4348 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4350 MODE is the mode of the inputs (in case they are const_int).
4352 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4353 It will be potentially converted into an unsigned variant based on
4354 UNSIGNEDP to select a proper jump instruction.
4356 PROB is the probability of jumping to LABEL. */
4359 emit_cmp_and_jump_insns (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4360 enum machine_mode mode
, int unsignedp
, rtx label
,
4363 rtx op0
= x
, op1
= y
;
4366 /* Swap operands and condition to ensure canonical RTL. */
4367 if (swap_commutative_operands_p (x
, y
)
4368 && can_compare_p (swap_condition (comparison
), mode
, ccp_jump
))
4371 comparison
= swap_condition (comparison
);
4374 /* If OP0 is still a constant, then both X and Y must be constants
4375 or the opposite comparison is not supported. Force X into a register
4376 to create canonical RTL. */
4377 if (CONSTANT_P (op0
))
4378 op0
= force_reg (mode
, op0
);
4381 comparison
= unsigned_condition (comparison
);
4383 prepare_cmp_insn (op0
, op1
, comparison
, size
, unsignedp
, OPTAB_LIB_WIDEN
,
4385 emit_cmp_and_jump_insn_1 (test
, mode
, label
, prob
);
4389 /* Emit a library call comparison between floating point X and Y.
4390 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4393 prepare_float_lib_cmp (rtx x
, rtx y
, enum rtx_code comparison
,
4394 rtx
*ptest
, enum machine_mode
*pmode
)
4396 enum rtx_code swapped
= swap_condition (comparison
);
4397 enum rtx_code reversed
= reverse_condition_maybe_unordered (comparison
);
4398 enum machine_mode orig_mode
= GET_MODE (x
);
4399 enum machine_mode mode
, cmp_mode
;
4400 rtx true_rtx
, false_rtx
;
4401 rtx value
, target
, equiv
;
4404 bool reversed_p
= false;
4405 cmp_mode
= targetm
.libgcc_cmp_return_mode ();
4407 for (mode
= orig_mode
;
4409 mode
= GET_MODE_WIDER_MODE (mode
))
4411 if (code_to_optab (comparison
)
4412 && (libfunc
= optab_libfunc (code_to_optab (comparison
), mode
)))
4415 if (code_to_optab (swapped
)
4416 && (libfunc
= optab_libfunc (code_to_optab (swapped
), mode
)))
4419 tmp
= x
; x
= y
; y
= tmp
;
4420 comparison
= swapped
;
4424 if (code_to_optab (reversed
)
4425 && (libfunc
= optab_libfunc (code_to_optab (reversed
), mode
)))
4427 comparison
= reversed
;
4433 gcc_assert (mode
!= VOIDmode
);
4435 if (mode
!= orig_mode
)
4437 x
= convert_to_mode (mode
, x
, 0);
4438 y
= convert_to_mode (mode
, y
, 0);
4441 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4442 the RTL. The allows the RTL optimizers to delete the libcall if the
4443 condition can be determined at compile-time. */
4444 if (comparison
== UNORDERED
4445 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4447 true_rtx
= const_true_rtx
;
4448 false_rtx
= const0_rtx
;
4455 true_rtx
= const0_rtx
;
4456 false_rtx
= const_true_rtx
;
4460 true_rtx
= const_true_rtx
;
4461 false_rtx
= const0_rtx
;
4465 true_rtx
= const1_rtx
;
4466 false_rtx
= const0_rtx
;
4470 true_rtx
= const0_rtx
;
4471 false_rtx
= constm1_rtx
;
4475 true_rtx
= constm1_rtx
;
4476 false_rtx
= const0_rtx
;
4480 true_rtx
= const0_rtx
;
4481 false_rtx
= const1_rtx
;
4489 if (comparison
== UNORDERED
)
4491 rtx temp
= simplify_gen_relational (NE
, cmp_mode
, mode
, x
, x
);
4492 equiv
= simplify_gen_relational (NE
, cmp_mode
, mode
, y
, y
);
4493 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4494 temp
, const_true_rtx
, equiv
);
4498 equiv
= simplify_gen_relational (comparison
, cmp_mode
, mode
, x
, y
);
4499 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4500 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4501 equiv
, true_rtx
, false_rtx
);
4505 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4506 cmp_mode
, 2, x
, mode
, y
, mode
);
4507 insns
= get_insns ();
4510 target
= gen_reg_rtx (cmp_mode
);
4511 emit_libcall_block (insns
, target
, value
, equiv
);
4513 if (comparison
== UNORDERED
4514 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
)
4516 *ptest
= gen_rtx_fmt_ee (reversed_p
? EQ
: NE
, VOIDmode
, target
, false_rtx
);
4518 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, target
, const0_rtx
);
4523 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4526 emit_indirect_jump (rtx loc
)
4528 struct expand_operand ops
[1];
4530 create_address_operand (&ops
[0], loc
);
4531 expand_jump_insn (CODE_FOR_indirect_jump
, 1, ops
);
4535 #ifdef HAVE_conditional_move
4537 /* Emit a conditional move instruction if the machine supports one for that
4538 condition and machine mode.
4540 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4541 the mode to use should they be constants. If it is VOIDmode, they cannot
4544 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4545 should be stored there. MODE is the mode to use should they be constants.
4546 If it is VOIDmode, they cannot both be constants.
4548 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4549 is not supported. */
4552 emit_conditional_move (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4553 enum machine_mode cmode
, rtx op2
, rtx op3
,
4554 enum machine_mode mode
, int unsignedp
)
4556 rtx tem
, comparison
;
4558 enum insn_code icode
;
4559 enum rtx_code reversed
;
4561 /* If one operand is constant, make it the second one. Only do this
4562 if the other operand is not constant as well. */
4564 if (swap_commutative_operands_p (op0
, op1
))
4569 code
= swap_condition (code
);
4572 /* get_condition will prefer to generate LT and GT even if the old
4573 comparison was against zero, so undo that canonicalization here since
4574 comparisons against zero are cheaper. */
4575 if (code
== LT
&& op1
== const1_rtx
)
4576 code
= LE
, op1
= const0_rtx
;
4577 else if (code
== GT
&& op1
== constm1_rtx
)
4578 code
= GE
, op1
= const0_rtx
;
4580 if (cmode
== VOIDmode
)
4581 cmode
= GET_MODE (op0
);
4583 if (swap_commutative_operands_p (op2
, op3
)
4584 && ((reversed
= reversed_comparison_code_parts (code
, op0
, op1
, NULL
))
4593 if (mode
== VOIDmode
)
4594 mode
= GET_MODE (op2
);
4596 icode
= direct_optab_handler (movcc_optab
, mode
);
4598 if (icode
== CODE_FOR_nothing
)
4602 target
= gen_reg_rtx (mode
);
4604 code
= unsignedp
? unsigned_condition (code
) : code
;
4605 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4607 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4608 return NULL and let the caller figure out how best to deal with this
4610 if (!COMPARISON_P (comparison
))
4613 saved_pending_stack_adjust save
;
4614 save_pending_stack_adjust (&save
);
4615 last
= get_last_insn ();
4616 do_pending_stack_adjust ();
4617 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4618 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4619 &comparison
, &cmode
);
4622 struct expand_operand ops
[4];
4624 create_output_operand (&ops
[0], target
, mode
);
4625 create_fixed_operand (&ops
[1], comparison
);
4626 create_input_operand (&ops
[2], op2
, mode
);
4627 create_input_operand (&ops
[3], op3
, mode
);
4628 if (maybe_expand_insn (icode
, 4, ops
))
4630 if (ops
[0].value
!= target
)
4631 convert_move (target
, ops
[0].value
, false);
4635 delete_insns_since (last
);
4636 restore_pending_stack_adjust (&save
);
4640 /* Return nonzero if a conditional move of mode MODE is supported.
4642 This function is for combine so it can tell whether an insn that looks
4643 like a conditional move is actually supported by the hardware. If we
4644 guess wrong we lose a bit on optimization, but that's it. */
4645 /* ??? sparc64 supports conditionally moving integers values based on fp
4646 comparisons, and vice versa. How do we handle them? */
4649 can_conditionally_move_p (enum machine_mode mode
)
4651 if (direct_optab_handler (movcc_optab
, mode
) != CODE_FOR_nothing
)
4657 #endif /* HAVE_conditional_move */
4659 /* Emit a conditional addition instruction if the machine supports one for that
4660 condition and machine mode.
4662 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4663 the mode to use should they be constants. If it is VOIDmode, they cannot
4666 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4667 should be stored there. MODE is the mode to use should they be constants.
4668 If it is VOIDmode, they cannot both be constants.
4670 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4671 is not supported. */
4674 emit_conditional_add (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4675 enum machine_mode cmode
, rtx op2
, rtx op3
,
4676 enum machine_mode mode
, int unsignedp
)
4678 rtx tem
, comparison
;
4680 enum insn_code icode
;
4682 /* If one operand is constant, make it the second one. Only do this
4683 if the other operand is not constant as well. */
4685 if (swap_commutative_operands_p (op0
, op1
))
4690 code
= swap_condition (code
);
4693 /* get_condition will prefer to generate LT and GT even if the old
4694 comparison was against zero, so undo that canonicalization here since
4695 comparisons against zero are cheaper. */
4696 if (code
== LT
&& op1
== const1_rtx
)
4697 code
= LE
, op1
= const0_rtx
;
4698 else if (code
== GT
&& op1
== constm1_rtx
)
4699 code
= GE
, op1
= const0_rtx
;
4701 if (cmode
== VOIDmode
)
4702 cmode
= GET_MODE (op0
);
4704 if (mode
== VOIDmode
)
4705 mode
= GET_MODE (op2
);
4707 icode
= optab_handler (addcc_optab
, mode
);
4709 if (icode
== CODE_FOR_nothing
)
4713 target
= gen_reg_rtx (mode
);
4715 code
= unsignedp
? unsigned_condition (code
) : code
;
4716 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4718 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4719 return NULL and let the caller figure out how best to deal with this
4721 if (!COMPARISON_P (comparison
))
4724 do_pending_stack_adjust ();
4725 last
= get_last_insn ();
4726 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4727 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4728 &comparison
, &cmode
);
4731 struct expand_operand ops
[4];
4733 create_output_operand (&ops
[0], target
, mode
);
4734 create_fixed_operand (&ops
[1], comparison
);
4735 create_input_operand (&ops
[2], op2
, mode
);
4736 create_input_operand (&ops
[3], op3
, mode
);
4737 if (maybe_expand_insn (icode
, 4, ops
))
4739 if (ops
[0].value
!= target
)
4740 convert_move (target
, ops
[0].value
, false);
4744 delete_insns_since (last
);
4748 /* These functions attempt to generate an insn body, rather than
4749 emitting the insn, but if the gen function already emits them, we
4750 make no attempt to turn them back into naked patterns. */
4752 /* Generate and return an insn body to add Y to X. */
4755 gen_add2_insn (rtx x
, rtx y
)
4757 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (x
));
4759 gcc_assert (insn_operand_matches (icode
, 0, x
));
4760 gcc_assert (insn_operand_matches (icode
, 1, x
));
4761 gcc_assert (insn_operand_matches (icode
, 2, y
));
4763 return GEN_FCN (icode
) (x
, x
, y
);
4766 /* Generate and return an insn body to add r1 and c,
4767 storing the result in r0. */
4770 gen_add3_insn (rtx r0
, rtx r1
, rtx c
)
4772 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (r0
));
4774 if (icode
== CODE_FOR_nothing
4775 || !insn_operand_matches (icode
, 0, r0
)
4776 || !insn_operand_matches (icode
, 1, r1
)
4777 || !insn_operand_matches (icode
, 2, c
))
4780 return GEN_FCN (icode
) (r0
, r1
, c
);
4784 have_add2_insn (rtx x
, rtx y
)
4786 enum insn_code icode
;
4788 gcc_assert (GET_MODE (x
) != VOIDmode
);
4790 icode
= optab_handler (add_optab
, GET_MODE (x
));
4792 if (icode
== CODE_FOR_nothing
)
4795 if (!insn_operand_matches (icode
, 0, x
)
4796 || !insn_operand_matches (icode
, 1, x
)
4797 || !insn_operand_matches (icode
, 2, y
))
4803 /* Generate and return an insn body to add Y to X. */
4806 gen_addptr3_insn (rtx x
, rtx y
, rtx z
)
4808 enum insn_code icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
4810 gcc_assert (insn_operand_matches (icode
, 0, x
));
4811 gcc_assert (insn_operand_matches (icode
, 1, y
));
4812 gcc_assert (insn_operand_matches (icode
, 2, z
));
4814 return GEN_FCN (icode
) (x
, y
, z
);
4817 /* Return true if the target implements an addptr pattern and X, Y,
4818 and Z are valid for the pattern predicates. */
4821 have_addptr3_insn (rtx x
, rtx y
, rtx z
)
4823 enum insn_code icode
;
4825 gcc_assert (GET_MODE (x
) != VOIDmode
);
4827 icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
4829 if (icode
== CODE_FOR_nothing
)
4832 if (!insn_operand_matches (icode
, 0, x
)
4833 || !insn_operand_matches (icode
, 1, y
)
4834 || !insn_operand_matches (icode
, 2, z
))
4840 /* Generate and return an insn body to subtract Y from X. */
4843 gen_sub2_insn (rtx x
, rtx y
)
4845 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (x
));
4847 gcc_assert (insn_operand_matches (icode
, 0, x
));
4848 gcc_assert (insn_operand_matches (icode
, 1, x
));
4849 gcc_assert (insn_operand_matches (icode
, 2, y
));
4851 return GEN_FCN (icode
) (x
, x
, y
);
4854 /* Generate and return an insn body to subtract r1 and c,
4855 storing the result in r0. */
4858 gen_sub3_insn (rtx r0
, rtx r1
, rtx c
)
4860 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (r0
));
4862 if (icode
== CODE_FOR_nothing
4863 || !insn_operand_matches (icode
, 0, r0
)
4864 || !insn_operand_matches (icode
, 1, r1
)
4865 || !insn_operand_matches (icode
, 2, c
))
4868 return GEN_FCN (icode
) (r0
, r1
, c
);
4872 have_sub2_insn (rtx x
, rtx y
)
4874 enum insn_code icode
;
4876 gcc_assert (GET_MODE (x
) != VOIDmode
);
4878 icode
= optab_handler (sub_optab
, GET_MODE (x
));
4880 if (icode
== CODE_FOR_nothing
)
4883 if (!insn_operand_matches (icode
, 0, x
)
4884 || !insn_operand_matches (icode
, 1, x
)
4885 || !insn_operand_matches (icode
, 2, y
))
4891 /* Generate the body of an instruction to copy Y into X.
4892 It may be a list of insns, if one insn isn't enough. */
4895 gen_move_insn (rtx x
, rtx y
)
4900 emit_move_insn_1 (x
, y
);
4906 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4907 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4908 no such operation exists, CODE_FOR_nothing will be returned. */
4911 can_extend_p (enum machine_mode to_mode
, enum machine_mode from_mode
,
4915 #ifdef HAVE_ptr_extend
4917 return CODE_FOR_ptr_extend
;
4920 tab
= unsignedp
? zext_optab
: sext_optab
;
4921 return convert_optab_handler (tab
, to_mode
, from_mode
);
4924 /* Generate the body of an insn to extend Y (with mode MFROM)
4925 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4928 gen_extend_insn (rtx x
, rtx y
, enum machine_mode mto
,
4929 enum machine_mode mfrom
, int unsignedp
)
4931 enum insn_code icode
= can_extend_p (mto
, mfrom
, unsignedp
);
4932 return GEN_FCN (icode
) (x
, y
);
4935 /* can_fix_p and can_float_p say whether the target machine
4936 can directly convert a given fixed point type to
4937 a given floating point type, or vice versa.
4938 The returned value is the CODE_FOR_... value to use,
4939 or CODE_FOR_nothing if these modes cannot be directly converted.
4941 *TRUNCP_PTR is set to 1 if it is necessary to output
4942 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4944 static enum insn_code
4945 can_fix_p (enum machine_mode fixmode
, enum machine_mode fltmode
,
4946 int unsignedp
, int *truncp_ptr
)
4949 enum insn_code icode
;
4951 tab
= unsignedp
? ufixtrunc_optab
: sfixtrunc_optab
;
4952 icode
= convert_optab_handler (tab
, fixmode
, fltmode
);
4953 if (icode
!= CODE_FOR_nothing
)
4959 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4960 for this to work. We need to rework the fix* and ftrunc* patterns
4961 and documentation. */
4962 tab
= unsignedp
? ufix_optab
: sfix_optab
;
4963 icode
= convert_optab_handler (tab
, fixmode
, fltmode
);
4964 if (icode
!= CODE_FOR_nothing
4965 && optab_handler (ftrunc_optab
, fltmode
) != CODE_FOR_nothing
)
4972 return CODE_FOR_nothing
;
4976 can_float_p (enum machine_mode fltmode
, enum machine_mode fixmode
,
4981 tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
4982 return convert_optab_handler (tab
, fltmode
, fixmode
);
4985 /* Function supportable_convert_operation
4987 Check whether an operation represented by the code CODE is a
4988 convert operation that is supported by the target platform in
4989 vector form (i.e., when operating on arguments of type VECTYPE_IN
4990 producing a result of type VECTYPE_OUT).
4992 Convert operations we currently support directly are FIX_TRUNC and FLOAT.
4993 This function checks if these operations are supported
4994 by the target platform either directly (via vector tree-codes), or via
4998 - CODE1 is code of vector operation to be used when
4999 vectorizing the operation, if available.
5000 - DECL is decl of target builtin functions to be used
5001 when vectorizing the operation, if available. In this case,
5002 CODE1 is CALL_EXPR. */
5005 supportable_convert_operation (enum tree_code code
,
5006 tree vectype_out
, tree vectype_in
,
5007 tree
*decl
, enum tree_code
*code1
)
5009 enum machine_mode m1
,m2
;
5012 m1
= TYPE_MODE (vectype_out
);
5013 m2
= TYPE_MODE (vectype_in
);
5015 /* First check if we can done conversion directly. */
5016 if ((code
== FIX_TRUNC_EXPR
5017 && can_fix_p (m1
,m2
,TYPE_UNSIGNED (vectype_out
), &truncp
)
5018 != CODE_FOR_nothing
)
5019 || (code
== FLOAT_EXPR
5020 && can_float_p (m1
,m2
,TYPE_UNSIGNED (vectype_in
))
5021 != CODE_FOR_nothing
))
5027 /* Now check for builtin. */
5028 if (targetm
.vectorize
.builtin_conversion
5029 && targetm
.vectorize
.builtin_conversion (code
, vectype_out
, vectype_in
))
5032 *decl
= targetm
.vectorize
.builtin_conversion (code
, vectype_out
, vectype_in
);
5039 /* Generate code to convert FROM to floating point
5040 and store in TO. FROM must be fixed point and not VOIDmode.
5041 UNSIGNEDP nonzero means regard FROM as unsigned.
5042 Normally this is done by correcting the final value
5043 if it is negative. */
5046 expand_float (rtx to
, rtx from
, int unsignedp
)
5048 enum insn_code icode
;
5050 enum machine_mode fmode
, imode
;
5051 bool can_do_signed
= false;
5053 /* Crash now, because we won't be able to decide which mode to use. */
5054 gcc_assert (GET_MODE (from
) != VOIDmode
);
5056 /* Look for an insn to do the conversion. Do it in the specified
5057 modes if possible; otherwise convert either input, output or both to
5058 wider mode. If the integer mode is wider than the mode of FROM,
5059 we can do the conversion signed even if the input is unsigned. */
5061 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
5062 fmode
= GET_MODE_WIDER_MODE (fmode
))
5063 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
5064 imode
= GET_MODE_WIDER_MODE (imode
))
5066 int doing_unsigned
= unsignedp
;
5068 if (fmode
!= GET_MODE (to
)
5069 && significand_size (fmode
) < GET_MODE_PRECISION (GET_MODE (from
)))
5072 icode
= can_float_p (fmode
, imode
, unsignedp
);
5073 if (icode
== CODE_FOR_nothing
&& unsignedp
)
5075 enum insn_code scode
= can_float_p (fmode
, imode
, 0);
5076 if (scode
!= CODE_FOR_nothing
)
5077 can_do_signed
= true;
5078 if (imode
!= GET_MODE (from
))
5079 icode
= scode
, doing_unsigned
= 0;
5082 if (icode
!= CODE_FOR_nothing
)
5084 if (imode
!= GET_MODE (from
))
5085 from
= convert_to_mode (imode
, from
, unsignedp
);
5087 if (fmode
!= GET_MODE (to
))
5088 target
= gen_reg_rtx (fmode
);
5090 emit_unop_insn (icode
, target
, from
,
5091 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
5094 convert_move (to
, target
, 0);
5099 /* Unsigned integer, and no way to convert directly. Convert as signed,
5100 then unconditionally adjust the result. */
5101 if (unsignedp
&& can_do_signed
)
5103 rtx_code_label
*label
= gen_label_rtx ();
5105 REAL_VALUE_TYPE offset
;
5107 /* Look for a usable floating mode FMODE wider than the source and at
5108 least as wide as the target. Using FMODE will avoid rounding woes
5109 with unsigned values greater than the signed maximum value. */
5111 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
5112 fmode
= GET_MODE_WIDER_MODE (fmode
))
5113 if (GET_MODE_PRECISION (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
5114 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
5117 if (fmode
== VOIDmode
)
5119 /* There is no such mode. Pretend the target is wide enough. */
5120 fmode
= GET_MODE (to
);
5122 /* Avoid double-rounding when TO is narrower than FROM. */
5123 if ((significand_size (fmode
) + 1)
5124 < GET_MODE_PRECISION (GET_MODE (from
)))
5127 rtx_code_label
*neglabel
= gen_label_rtx ();
5129 /* Don't use TARGET if it isn't a register, is a hard register,
5130 or is the wrong mode. */
5132 || REGNO (target
) < FIRST_PSEUDO_REGISTER
5133 || GET_MODE (target
) != fmode
)
5134 target
= gen_reg_rtx (fmode
);
5136 imode
= GET_MODE (from
);
5137 do_pending_stack_adjust ();
5139 /* Test whether the sign bit is set. */
5140 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
5143 /* The sign bit is not set. Convert as signed. */
5144 expand_float (target
, from
, 0);
5145 emit_jump_insn (gen_jump (label
));
5148 /* The sign bit is set.
5149 Convert to a usable (positive signed) value by shifting right
5150 one bit, while remembering if a nonzero bit was shifted
5151 out; i.e., compute (from & 1) | (from >> 1). */
5153 emit_label (neglabel
);
5154 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
5155 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5156 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, 1, NULL_RTX
, 1);
5157 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
5159 expand_float (target
, temp
, 0);
5161 /* Multiply by 2 to undo the shift above. */
5162 temp
= expand_binop (fmode
, add_optab
, target
, target
,
5163 target
, 0, OPTAB_LIB_WIDEN
);
5165 emit_move_insn (target
, temp
);
5167 do_pending_stack_adjust ();
5173 /* If we are about to do some arithmetic to correct for an
5174 unsigned operand, do it in a pseudo-register. */
5176 if (GET_MODE (to
) != fmode
5177 || !REG_P (to
) || REGNO (to
) < FIRST_PSEUDO_REGISTER
)
5178 target
= gen_reg_rtx (fmode
);
5180 /* Convert as signed integer to floating. */
5181 expand_float (target
, from
, 0);
5183 /* If FROM is negative (and therefore TO is negative),
5184 correct its value by 2**bitwidth. */
5186 do_pending_stack_adjust ();
5187 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
),
5191 real_2expN (&offset
, GET_MODE_PRECISION (GET_MODE (from
)), fmode
);
5192 temp
= expand_binop (fmode
, add_optab
, target
,
5193 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
5194 target
, 0, OPTAB_LIB_WIDEN
);
5196 emit_move_insn (target
, temp
);
5198 do_pending_stack_adjust ();
5203 /* No hardware instruction available; call a library routine. */
5208 convert_optab tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
5210 if (GET_MODE_PRECISION (GET_MODE (from
)) < GET_MODE_PRECISION (SImode
))
5211 from
= convert_to_mode (SImode
, from
, unsignedp
);
5213 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5214 gcc_assert (libfunc
);
5218 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5219 GET_MODE (to
), 1, from
,
5221 insns
= get_insns ();
5224 emit_libcall_block (insns
, target
, value
,
5225 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FLOAT
: FLOAT
,
5226 GET_MODE (to
), from
));
5231 /* Copy result to requested destination
5232 if we have been computing in a temp location. */
5236 if (GET_MODE (target
) == GET_MODE (to
))
5237 emit_move_insn (to
, target
);
5239 convert_move (to
, target
, 0);
5243 /* Generate code to convert FROM to fixed point and store in TO. FROM
5244 must be floating point. */
5247 expand_fix (rtx to
, rtx from
, int unsignedp
)
5249 enum insn_code icode
;
5251 enum machine_mode fmode
, imode
;
5254 /* We first try to find a pair of modes, one real and one integer, at
5255 least as wide as FROM and TO, respectively, in which we can open-code
5256 this conversion. If the integer mode is wider than the mode of TO,
5257 we can do the conversion either signed or unsigned. */
5259 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5260 fmode
= GET_MODE_WIDER_MODE (fmode
))
5261 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
5262 imode
= GET_MODE_WIDER_MODE (imode
))
5264 int doing_unsigned
= unsignedp
;
5266 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
5267 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
5268 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
5270 if (icode
!= CODE_FOR_nothing
)
5272 rtx_insn
*last
= get_last_insn ();
5273 if (fmode
!= GET_MODE (from
))
5274 from
= convert_to_mode (fmode
, from
, 0);
5278 rtx temp
= gen_reg_rtx (GET_MODE (from
));
5279 from
= expand_unop (GET_MODE (from
), ftrunc_optab
, from
,
5283 if (imode
!= GET_MODE (to
))
5284 target
= gen_reg_rtx (imode
);
5286 if (maybe_emit_unop_insn (icode
, target
, from
,
5287 doing_unsigned
? UNSIGNED_FIX
: FIX
))
5290 convert_move (to
, target
, unsignedp
);
5293 delete_insns_since (last
);
5297 /* For an unsigned conversion, there is one more way to do it.
5298 If we have a signed conversion, we generate code that compares
5299 the real value to the largest representable positive number. If if
5300 is smaller, the conversion is done normally. Otherwise, subtract
5301 one plus the highest signed number, convert, and add it back.
5303 We only need to check all real modes, since we know we didn't find
5304 anything with a wider integer mode.
5306 This code used to extend FP value into mode wider than the destination.
5307 This is needed for decimal float modes which cannot accurately
5308 represent one plus the highest signed number of the same size, but
5309 not for binary modes. Consider, for instance conversion from SFmode
5312 The hot path through the code is dealing with inputs smaller than 2^63
5313 and doing just the conversion, so there is no bits to lose.
5315 In the other path we know the value is positive in the range 2^63..2^64-1
5316 inclusive. (as for other input overflow happens and result is undefined)
5317 So we know that the most important bit set in mantissa corresponds to
5318 2^63. The subtraction of 2^63 should not generate any rounding as it
5319 simply clears out that bit. The rest is trivial. */
5321 if (unsignedp
&& GET_MODE_PRECISION (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
5322 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5323 fmode
= GET_MODE_WIDER_MODE (fmode
))
5324 if (CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0, &must_trunc
)
5325 && (!DECIMAL_FLOAT_MODE_P (fmode
)
5326 || GET_MODE_BITSIZE (fmode
) > GET_MODE_PRECISION (GET_MODE (to
))))
5329 REAL_VALUE_TYPE offset
;
5331 rtx_code_label
*lab1
, *lab2
;
5334 bitsize
= GET_MODE_PRECISION (GET_MODE (to
));
5335 real_2expN (&offset
, bitsize
- 1, fmode
);
5336 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
5337 lab1
= gen_label_rtx ();
5338 lab2
= gen_label_rtx ();
5340 if (fmode
!= GET_MODE (from
))
5341 from
= convert_to_mode (fmode
, from
, 0);
5343 /* See if we need to do the subtraction. */
5344 do_pending_stack_adjust ();
5345 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
),
5348 /* If not, do the signed "fix" and branch around fixup code. */
5349 expand_fix (to
, from
, 0);
5350 emit_jump_insn (gen_jump (lab2
));
5353 /* Otherwise, subtract 2**(N-1), convert to signed number,
5354 then add 2**(N-1). Do the addition using XOR since this
5355 will often generate better code. */
5357 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
5358 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
5359 expand_fix (to
, target
, 0);
5360 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
5362 ((HOST_WIDE_INT
) 1 << (bitsize
- 1),
5364 to
, 1, OPTAB_LIB_WIDEN
);
5367 emit_move_insn (to
, target
);
5371 if (optab_handler (mov_optab
, GET_MODE (to
)) != CODE_FOR_nothing
)
5373 /* Make a place for a REG_NOTE and add it. */
5374 insn
= emit_move_insn (to
, to
);
5375 set_dst_reg_note (insn
, REG_EQUAL
,
5376 gen_rtx_fmt_e (UNSIGNED_FIX
, GET_MODE (to
),
5384 /* We can't do it with an insn, so use a library call. But first ensure
5385 that the mode of TO is at least as wide as SImode, since those are the
5386 only library calls we know about. */
5388 if (GET_MODE_PRECISION (GET_MODE (to
)) < GET_MODE_PRECISION (SImode
))
5390 target
= gen_reg_rtx (SImode
);
5392 expand_fix (target
, from
, unsignedp
);
5400 convert_optab tab
= unsignedp
? ufix_optab
: sfix_optab
;
5401 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5402 gcc_assert (libfunc
);
5406 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5407 GET_MODE (to
), 1, from
,
5409 insns
= get_insns ();
5412 emit_libcall_block (insns
, target
, value
,
5413 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
5414 GET_MODE (to
), from
));
5419 if (GET_MODE (to
) == GET_MODE (target
))
5420 emit_move_insn (to
, target
);
5422 convert_move (to
, target
, 0);
5426 /* Generate code to convert FROM or TO a fixed-point.
5427 If UINTP is true, either TO or FROM is an unsigned integer.
5428 If SATP is true, we need to saturate the result. */
5431 expand_fixed_convert (rtx to
, rtx from
, int uintp
, int satp
)
5433 enum machine_mode to_mode
= GET_MODE (to
);
5434 enum machine_mode from_mode
= GET_MODE (from
);
5436 enum rtx_code this_code
;
5437 enum insn_code code
;
5442 if (to_mode
== from_mode
)
5444 emit_move_insn (to
, from
);
5450 tab
= satp
? satfractuns_optab
: fractuns_optab
;
5451 this_code
= satp
? UNSIGNED_SAT_FRACT
: UNSIGNED_FRACT_CONVERT
;
5455 tab
= satp
? satfract_optab
: fract_optab
;
5456 this_code
= satp
? SAT_FRACT
: FRACT_CONVERT
;
5458 code
= convert_optab_handler (tab
, to_mode
, from_mode
);
5459 if (code
!= CODE_FOR_nothing
)
5461 emit_unop_insn (code
, to
, from
, this_code
);
5465 libfunc
= convert_optab_libfunc (tab
, to_mode
, from_mode
);
5466 gcc_assert (libfunc
);
5469 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, to_mode
,
5470 1, from
, from_mode
);
5471 insns
= get_insns ();
5474 emit_libcall_block (insns
, to
, value
,
5475 gen_rtx_fmt_e (optab_to_code (tab
), to_mode
, from
));
5478 /* Generate code to convert FROM to fixed point and store in TO. FROM
5479 must be floating point, TO must be signed. Use the conversion optab
5480 TAB to do the conversion. */
5483 expand_sfix_optab (rtx to
, rtx from
, convert_optab tab
)
5485 enum insn_code icode
;
5487 enum machine_mode fmode
, imode
;
5489 /* We first try to find a pair of modes, one real and one integer, at
5490 least as wide as FROM and TO, respectively, in which we can open-code
5491 this conversion. If the integer mode is wider than the mode of TO,
5492 we can do the conversion either signed or unsigned. */
5494 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5495 fmode
= GET_MODE_WIDER_MODE (fmode
))
5496 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
5497 imode
= GET_MODE_WIDER_MODE (imode
))
5499 icode
= convert_optab_handler (tab
, imode
, fmode
);
5500 if (icode
!= CODE_FOR_nothing
)
5502 rtx_insn
*last
= get_last_insn ();
5503 if (fmode
!= GET_MODE (from
))
5504 from
= convert_to_mode (fmode
, from
, 0);
5506 if (imode
!= GET_MODE (to
))
5507 target
= gen_reg_rtx (imode
);
5509 if (!maybe_emit_unop_insn (icode
, target
, from
, UNKNOWN
))
5511 delete_insns_since (last
);
5515 convert_move (to
, target
, 0);
5523 /* Report whether we have an instruction to perform the operation
5524 specified by CODE on operands of mode MODE. */
5526 have_insn_for (enum rtx_code code
, enum machine_mode mode
)
5528 return (code_to_optab (code
)
5529 && (optab_handler (code_to_optab (code
), mode
)
5530 != CODE_FOR_nothing
));
5533 /* Initialize the libfunc fields of an entire group of entries in some
5534 optab. Each entry is set equal to a string consisting of a leading
5535 pair of underscores followed by a generic operation name followed by
5536 a mode name (downshifted to lowercase) followed by a single character
5537 representing the number of operands for the given operation (which is
5538 usually one of the characters '2', '3', or '4').
5540 OPTABLE is the table in which libfunc fields are to be initialized.
5541 OPNAME is the generic (string) name of the operation.
5542 SUFFIX is the character which specifies the number of operands for
5543 the given generic operation.
5544 MODE is the mode to generate for.
5548 gen_libfunc (optab optable
, const char *opname
, int suffix
,
5549 enum machine_mode mode
)
5551 unsigned opname_len
= strlen (opname
);
5552 const char *mname
= GET_MODE_NAME (mode
);
5553 unsigned mname_len
= strlen (mname
);
5554 int prefix_len
= targetm
.libfunc_gnu_prefix
? 6 : 2;
5555 int len
= prefix_len
+ opname_len
+ mname_len
+ 1 + 1;
5556 char *libfunc_name
= XALLOCAVEC (char, len
);
5563 if (targetm
.libfunc_gnu_prefix
)
5570 for (q
= opname
; *q
; )
5572 for (q
= mname
; *q
; q
++)
5573 *p
++ = TOLOWER (*q
);
5577 set_optab_libfunc (optable
, mode
,
5578 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5581 /* Like gen_libfunc, but verify that integer operation is involved. */
5584 gen_int_libfunc (optab optable
, const char *opname
, char suffix
,
5585 enum machine_mode mode
)
5587 int maxsize
= 2 * BITS_PER_WORD
;
5588 int minsize
= BITS_PER_WORD
;
5590 if (GET_MODE_CLASS (mode
) != MODE_INT
)
5592 if (maxsize
< LONG_LONG_TYPE_SIZE
)
5593 maxsize
= LONG_LONG_TYPE_SIZE
;
5594 if (minsize
> INT_TYPE_SIZE
5595 && (trapv_binoptab_p (optable
)
5596 || trapv_unoptab_p (optable
)))
5597 minsize
= INT_TYPE_SIZE
;
5598 if (GET_MODE_BITSIZE (mode
) < minsize
5599 || GET_MODE_BITSIZE (mode
) > maxsize
)
5601 gen_libfunc (optable
, opname
, suffix
, mode
);
5604 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */
5607 gen_fp_libfunc (optab optable
, const char *opname
, char suffix
,
5608 enum machine_mode mode
)
5612 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5613 gen_libfunc (optable
, opname
, suffix
, mode
);
5614 if (DECIMAL_FLOAT_MODE_P (mode
))
5616 dec_opname
= XALLOCAVEC (char, sizeof (DECIMAL_PREFIX
) + strlen (opname
));
5617 /* For BID support, change the name to have either a bid_ or dpd_ prefix
5618 depending on the low level floating format used. */
5619 memcpy (dec_opname
, DECIMAL_PREFIX
, sizeof (DECIMAL_PREFIX
) - 1);
5620 strcpy (dec_opname
+ sizeof (DECIMAL_PREFIX
) - 1, opname
);
5621 gen_libfunc (optable
, dec_opname
, suffix
, mode
);
5625 /* Like gen_libfunc, but verify that fixed-point operation is involved. */
5628 gen_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5629 enum machine_mode mode
)
5631 if (!ALL_FIXED_POINT_MODE_P (mode
))
5633 gen_libfunc (optable
, opname
, suffix
, mode
);
5636 /* Like gen_libfunc, but verify that signed fixed-point operation is
5640 gen_signed_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5641 enum machine_mode mode
)
5643 if (!SIGNED_FIXED_POINT_MODE_P (mode
))
5645 gen_libfunc (optable
, opname
, suffix
, mode
);
5648 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
5652 gen_unsigned_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5653 enum machine_mode mode
)
5655 if (!UNSIGNED_FIXED_POINT_MODE_P (mode
))
5657 gen_libfunc (optable
, opname
, suffix
, mode
);
5660 /* Like gen_libfunc, but verify that FP or INT operation is involved. */
5663 gen_int_fp_libfunc (optab optable
, const char *name
, char suffix
,
5664 enum machine_mode mode
)
5666 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5667 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5668 if (INTEGRAL_MODE_P (mode
))
5669 gen_int_libfunc (optable
, name
, suffix
, mode
);
5672 /* Like gen_libfunc, but verify that FP or INT operation is involved
5673 and add 'v' suffix for integer operation. */
5676 gen_intv_fp_libfunc (optab optable
, const char *name
, char suffix
,
5677 enum machine_mode mode
)
5679 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5680 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5681 if (GET_MODE_CLASS (mode
) == MODE_INT
)
5683 int len
= strlen (name
);
5684 char *v_name
= XALLOCAVEC (char, len
+ 2);
5685 strcpy (v_name
, name
);
5687 v_name
[len
+ 1] = 0;
5688 gen_int_libfunc (optable
, v_name
, suffix
, mode
);
5692 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
5696 gen_int_fp_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5697 enum machine_mode mode
)
5699 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5700 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5701 if (INTEGRAL_MODE_P (mode
))
5702 gen_int_libfunc (optable
, name
, suffix
, mode
);
5703 if (ALL_FIXED_POINT_MODE_P (mode
))
5704 gen_fixed_libfunc (optable
, name
, suffix
, mode
);
5707 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
5711 gen_int_fp_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5712 enum machine_mode mode
)
5714 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5715 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5716 if (INTEGRAL_MODE_P (mode
))
5717 gen_int_libfunc (optable
, name
, suffix
, mode
);
5718 if (SIGNED_FIXED_POINT_MODE_P (mode
))
5719 gen_signed_fixed_libfunc (optable
, name
, suffix
, mode
);
5722 /* Like gen_libfunc, but verify that INT or FIXED operation is
5726 gen_int_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5727 enum machine_mode mode
)
5729 if (INTEGRAL_MODE_P (mode
))
5730 gen_int_libfunc (optable
, name
, suffix
, mode
);
5731 if (ALL_FIXED_POINT_MODE_P (mode
))
5732 gen_fixed_libfunc (optable
, name
, suffix
, mode
);
5735 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
5739 gen_int_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5740 enum machine_mode mode
)
5742 if (INTEGRAL_MODE_P (mode
))
5743 gen_int_libfunc (optable
, name
, suffix
, mode
);
5744 if (SIGNED_FIXED_POINT_MODE_P (mode
))
5745 gen_signed_fixed_libfunc (optable
, name
, suffix
, mode
);
5748 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
5752 gen_int_unsigned_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5753 enum machine_mode mode
)
5755 if (INTEGRAL_MODE_P (mode
))
5756 gen_int_libfunc (optable
, name
, suffix
, mode
);
5757 if (UNSIGNED_FIXED_POINT_MODE_P (mode
))
5758 gen_unsigned_fixed_libfunc (optable
, name
, suffix
, mode
);
5761 /* Initialize the libfunc fields of an entire group of entries of an
5762 inter-mode-class conversion optab. The string formation rules are
5763 similar to the ones for init_libfuncs, above, but instead of having
5764 a mode name and an operand count these functions have two mode names
5765 and no operand count. */
5768 gen_interclass_conv_libfunc (convert_optab tab
,
5770 enum machine_mode tmode
,
5771 enum machine_mode fmode
)
5773 size_t opname_len
= strlen (opname
);
5774 size_t mname_len
= 0;
5776 const char *fname
, *tname
;
5778 int prefix_len
= targetm
.libfunc_gnu_prefix
? 6 : 2;
5779 char *libfunc_name
, *suffix
;
5780 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
5783 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5784 depends on which underlying decimal floating point format is used. */
5785 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
5787 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
5789 nondec_name
= XALLOCAVEC (char, prefix_len
+ opname_len
+ mname_len
+ 1 + 1);
5790 nondec_name
[0] = '_';
5791 nondec_name
[1] = '_';
5792 if (targetm
.libfunc_gnu_prefix
)
5794 nondec_name
[2] = 'g';
5795 nondec_name
[3] = 'n';
5796 nondec_name
[4] = 'u';
5797 nondec_name
[5] = '_';
5800 memcpy (&nondec_name
[prefix_len
], opname
, opname_len
);
5801 nondec_suffix
= nondec_name
+ opname_len
+ prefix_len
;
5803 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 1);
5806 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
5807 memcpy (&dec_name
[2+dec_len
], opname
, opname_len
);
5808 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
5810 fname
= GET_MODE_NAME (fmode
);
5811 tname
= GET_MODE_NAME (tmode
);
5813 if (DECIMAL_FLOAT_MODE_P (fmode
) || DECIMAL_FLOAT_MODE_P (tmode
))
5815 libfunc_name
= dec_name
;
5816 suffix
= dec_suffix
;
5820 libfunc_name
= nondec_name
;
5821 suffix
= nondec_suffix
;
5825 for (q
= fname
; *q
; p
++, q
++)
5827 for (q
= tname
; *q
; p
++, q
++)
5832 set_conv_libfunc (tab
, tmode
, fmode
,
5833 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5836 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5837 int->fp conversion. */
5840 gen_int_to_fp_conv_libfunc (convert_optab tab
,
5842 enum machine_mode tmode
,
5843 enum machine_mode fmode
)
5845 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
5847 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
5849 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5852 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
5856 gen_ufloat_conv_libfunc (convert_optab tab
,
5857 const char *opname ATTRIBUTE_UNUSED
,
5858 enum machine_mode tmode
,
5859 enum machine_mode fmode
)
5861 if (DECIMAL_FLOAT_MODE_P (tmode
))
5862 gen_int_to_fp_conv_libfunc (tab
, "floatuns", tmode
, fmode
);
5864 gen_int_to_fp_conv_libfunc (tab
, "floatun", tmode
, fmode
);
5867 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5868 fp->int conversion. */
5871 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab
,
5873 enum machine_mode tmode
,
5874 enum machine_mode fmode
)
5876 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
5878 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
)
5880 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5883 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5884 fp->int conversion with no decimal floating point involved. */
5887 gen_fp_to_int_conv_libfunc (convert_optab tab
,
5889 enum machine_mode tmode
,
5890 enum machine_mode fmode
)
5892 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
5894 if (GET_MODE_CLASS (tmode
) != MODE_INT
)
5896 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5899 /* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
5900 The string formation rules are
5901 similar to the ones for init_libfunc, above. */
5904 gen_intraclass_conv_libfunc (convert_optab tab
, const char *opname
,
5905 enum machine_mode tmode
, enum machine_mode fmode
)
5907 size_t opname_len
= strlen (opname
);
5908 size_t mname_len
= 0;
5910 const char *fname
, *tname
;
5912 int prefix_len
= targetm
.libfunc_gnu_prefix
? 6 : 2;
5913 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
5914 char *libfunc_name
, *suffix
;
5917 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5918 depends on which underlying decimal floating point format is used. */
5919 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
5921 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
5923 nondec_name
= XALLOCAVEC (char, 2 + opname_len
+ mname_len
+ 1 + 1);
5924 nondec_name
[0] = '_';
5925 nondec_name
[1] = '_';
5926 if (targetm
.libfunc_gnu_prefix
)
5928 nondec_name
[2] = 'g';
5929 nondec_name
[3] = 'n';
5930 nondec_name
[4] = 'u';
5931 nondec_name
[5] = '_';
5933 memcpy (&nondec_name
[prefix_len
], opname
, opname_len
);
5934 nondec_suffix
= nondec_name
+ opname_len
+ prefix_len
;
5936 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 1);
5939 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
5940 memcpy (&dec_name
[2 + dec_len
], opname
, opname_len
);
5941 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
5943 fname
= GET_MODE_NAME (fmode
);
5944 tname
= GET_MODE_NAME (tmode
);
5946 if (DECIMAL_FLOAT_MODE_P (fmode
) || DECIMAL_FLOAT_MODE_P (tmode
))
5948 libfunc_name
= dec_name
;
5949 suffix
= dec_suffix
;
5953 libfunc_name
= nondec_name
;
5954 suffix
= nondec_suffix
;
5958 for (q
= fname
; *q
; p
++, q
++)
5960 for (q
= tname
; *q
; p
++, q
++)
5966 set_conv_libfunc (tab
, tmode
, fmode
,
5967 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5970 /* Pick proper libcall for trunc_optab. We need to chose if we do
5971 truncation or extension and interclass or intraclass. */
5974 gen_trunc_conv_libfunc (convert_optab tab
,
5976 enum machine_mode tmode
,
5977 enum machine_mode fmode
)
5979 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
5981 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
5986 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (fmode
))
5987 || (GET_MODE_CLASS (fmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (tmode
)))
5988 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5990 if (GET_MODE_PRECISION (fmode
) <= GET_MODE_PRECISION (tmode
))
5993 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
5994 && GET_MODE_CLASS (fmode
) == MODE_FLOAT
)
5995 || (DECIMAL_FLOAT_MODE_P (fmode
) && DECIMAL_FLOAT_MODE_P (tmode
)))
5996 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5999 /* Pick proper libcall for extend_optab. We need to chose if we do
6000 truncation or extension and interclass or intraclass. */
6003 gen_extend_conv_libfunc (convert_optab tab
,
6004 const char *opname ATTRIBUTE_UNUSED
,
6005 enum machine_mode tmode
,
6006 enum machine_mode fmode
)
6008 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
6010 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
6015 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (fmode
))
6016 || (GET_MODE_CLASS (fmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (tmode
)))
6017 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6019 if (GET_MODE_PRECISION (fmode
) > GET_MODE_PRECISION (tmode
))
6022 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
6023 && GET_MODE_CLASS (fmode
) == MODE_FLOAT
)
6024 || (DECIMAL_FLOAT_MODE_P (fmode
) && DECIMAL_FLOAT_MODE_P (tmode
)))
6025 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6028 /* Pick proper libcall for fract_optab. We need to chose if we do
6029 interclass or intraclass. */
6032 gen_fract_conv_libfunc (convert_optab tab
,
6034 enum machine_mode tmode
,
6035 enum machine_mode fmode
)
6039 if (!(ALL_FIXED_POINT_MODE_P (tmode
) || ALL_FIXED_POINT_MODE_P (fmode
)))
6042 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
6043 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6045 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6048 /* Pick proper libcall for fractuns_optab. */
6051 gen_fractuns_conv_libfunc (convert_optab tab
,
6053 enum machine_mode tmode
,
6054 enum machine_mode fmode
)
6058 /* One mode must be a fixed-point mode, and the other must be an integer
6060 if (!((ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
)
6061 || (ALL_FIXED_POINT_MODE_P (fmode
)
6062 && GET_MODE_CLASS (tmode
) == MODE_INT
)))
6065 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6068 /* Pick proper libcall for satfract_optab. We need to chose if we do
6069 interclass or intraclass. */
6072 gen_satfract_conv_libfunc (convert_optab tab
,
6074 enum machine_mode tmode
,
6075 enum machine_mode fmode
)
6079 /* TMODE must be a fixed-point mode. */
6080 if (!ALL_FIXED_POINT_MODE_P (tmode
))
6083 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
6084 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6086 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6089 /* Pick proper libcall for satfractuns_optab. */
6092 gen_satfractuns_conv_libfunc (convert_optab tab
,
6094 enum machine_mode tmode
,
6095 enum machine_mode fmode
)
6099 /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
6100 if (!(ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
))
6103 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6106 /* Hashtable callbacks for libfunc_decls. */
6108 struct libfunc_decl_hasher
: ggc_hasher
<tree
>
6113 return IDENTIFIER_HASH_VALUE (DECL_NAME (entry
));
6117 equal (tree decl
, tree name
)
6119 return DECL_NAME (decl
) == name
;
6123 /* A table of previously-created libfuncs, hashed by name. */
6124 static GTY (()) hash_table
<libfunc_decl_hasher
> *libfunc_decls
;
6126 /* Build a decl for a libfunc named NAME. */
6129 build_libfunc_function (const char *name
)
6131 tree decl
= build_decl (UNKNOWN_LOCATION
, FUNCTION_DECL
,
6132 get_identifier (name
),
6133 build_function_type (integer_type_node
, NULL_TREE
));
6134 /* ??? We don't have any type information except for this is
6135 a function. Pretend this is "int foo()". */
6136 DECL_ARTIFICIAL (decl
) = 1;
6137 DECL_EXTERNAL (decl
) = 1;
6138 TREE_PUBLIC (decl
) = 1;
6139 gcc_assert (DECL_ASSEMBLER_NAME (decl
));
6141 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
6142 are the flags assigned by targetm.encode_section_info. */
6143 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl
), 0), NULL
);
6149 init_one_libfunc (const char *name
)
6154 if (libfunc_decls
== NULL
)
6155 libfunc_decls
= hash_table
<libfunc_decl_hasher
>::create_ggc (37);
6157 /* See if we have already created a libfunc decl for this function. */
6158 id
= get_identifier (name
);
6159 hash
= IDENTIFIER_HASH_VALUE (id
);
6160 tree
*slot
= libfunc_decls
->find_slot_with_hash (id
, hash
, INSERT
);
6164 /* Create a new decl, so that it can be passed to
6165 targetm.encode_section_info. */
6166 decl
= build_libfunc_function (name
);
6169 return XEXP (DECL_RTL (decl
), 0);
6172 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */
6175 set_user_assembler_libfunc (const char *name
, const char *asmspec
)
6180 id
= get_identifier (name
);
6181 hash
= IDENTIFIER_HASH_VALUE (id
);
6182 tree
*slot
= libfunc_decls
->find_slot_with_hash (id
, hash
, NO_INSERT
);
6184 decl
= (tree
) *slot
;
6185 set_user_assembler_name (decl
, asmspec
);
6186 return XEXP (DECL_RTL (decl
), 0);
6189 /* Call this to reset the function entry for one optab (OPTABLE) in mode
6190 MODE to NAME, which should be either 0 or a string constant. */
6192 set_optab_libfunc (optab op
, enum machine_mode mode
, const char *name
)
6195 struct libfunc_entry e
;
6196 struct libfunc_entry
**slot
;
6203 val
= init_one_libfunc (name
);
6206 slot
= libfunc_hash
->find_slot (&e
, INSERT
);
6208 *slot
= ggc_alloc
<libfunc_entry
> ();
6210 (*slot
)->mode1
= mode
;
6211 (*slot
)->mode2
= VOIDmode
;
6212 (*slot
)->libfunc
= val
;
6215 /* Call this to reset the function entry for one conversion optab
6216 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
6217 either 0 or a string constant. */
6219 set_conv_libfunc (convert_optab optab
, enum machine_mode tmode
,
6220 enum machine_mode fmode
, const char *name
)
6223 struct libfunc_entry e
;
6224 struct libfunc_entry
**slot
;
6231 val
= init_one_libfunc (name
);
6234 slot
= libfunc_hash
->find_slot (&e
, INSERT
);
6236 *slot
= ggc_alloc
<libfunc_entry
> ();
6237 (*slot
)->op
= optab
;
6238 (*slot
)->mode1
= tmode
;
6239 (*slot
)->mode2
= fmode
;
6240 (*slot
)->libfunc
= val
;
6243 /* Call this to initialize the contents of the optabs
6244 appropriately for the current target machine. */
6250 libfunc_hash
->empty ();
6252 libfunc_hash
= hash_table
<libfunc_hasher
>::create_ggc (10);
6254 /* Fill in the optabs with the insns we support. */
6255 init_all_optabs (this_fn_optabs
);
6257 /* The ffs function operates on `int'. Fall back on it if we do not
6258 have a libgcc2 function for that width. */
6259 if (INT_TYPE_SIZE
< BITS_PER_WORD
)
6260 set_optab_libfunc (ffs_optab
, mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0),
6263 /* Explicitly initialize the bswap libfuncs since we need them to be
6264 valid for things other than word_mode. */
6265 if (targetm
.libfunc_gnu_prefix
)
6267 set_optab_libfunc (bswap_optab
, SImode
, "__gnu_bswapsi2");
6268 set_optab_libfunc (bswap_optab
, DImode
, "__gnu_bswapdi2");
6272 set_optab_libfunc (bswap_optab
, SImode
, "__bswapsi2");
6273 set_optab_libfunc (bswap_optab
, DImode
, "__bswapdi2");
6276 /* Use cabs for double complex abs, since systems generally have cabs.
6277 Don't define any libcall for float complex, so that cabs will be used. */
6278 if (complex_double_type_node
)
6279 set_optab_libfunc (abs_optab
, TYPE_MODE (complex_double_type_node
),
6282 abort_libfunc
= init_one_libfunc ("abort");
6283 memcpy_libfunc
= init_one_libfunc ("memcpy");
6284 memmove_libfunc
= init_one_libfunc ("memmove");
6285 memcmp_libfunc
= init_one_libfunc ("memcmp");
6286 memset_libfunc
= init_one_libfunc ("memset");
6287 setbits_libfunc
= init_one_libfunc ("__setbits");
6289 #ifndef DONT_USE_BUILTIN_SETJMP
6290 setjmp_libfunc
= init_one_libfunc ("__builtin_setjmp");
6291 longjmp_libfunc
= init_one_libfunc ("__builtin_longjmp");
6293 setjmp_libfunc
= init_one_libfunc ("setjmp");
6294 longjmp_libfunc
= init_one_libfunc ("longjmp");
6296 unwind_sjlj_register_libfunc
= init_one_libfunc ("_Unwind_SjLj_Register");
6297 unwind_sjlj_unregister_libfunc
6298 = init_one_libfunc ("_Unwind_SjLj_Unregister");
6300 /* For function entry/exit instrumentation. */
6301 profile_function_entry_libfunc
6302 = init_one_libfunc ("__cyg_profile_func_enter");
6303 profile_function_exit_libfunc
6304 = init_one_libfunc ("__cyg_profile_func_exit");
6306 gcov_flush_libfunc
= init_one_libfunc ("__gcov_flush");
6308 /* Allow the target to add more libcalls or rename some, etc. */
6309 targetm
.init_libfuncs ();
6312 /* Use the current target and options to initialize
6313 TREE_OPTIMIZATION_OPTABS (OPTNODE). */
6316 init_tree_optimization_optabs (tree optnode
)
6318 /* Quick exit if we have already computed optabs for this target. */
6319 if (TREE_OPTIMIZATION_BASE_OPTABS (optnode
) == this_target_optabs
)
6322 /* Forget any previous information and set up for the current target. */
6323 TREE_OPTIMIZATION_BASE_OPTABS (optnode
) = this_target_optabs
;
6324 struct target_optabs
*tmp_optabs
= (struct target_optabs
*)
6325 TREE_OPTIMIZATION_OPTABS (optnode
);
6327 memset (tmp_optabs
, 0, sizeof (struct target_optabs
));
6329 tmp_optabs
= ggc_alloc
<target_optabs
> ();
6331 /* Generate a new set of optabs into tmp_optabs. */
6332 init_all_optabs (tmp_optabs
);
6334 /* If the optabs changed, record it. */
6335 if (memcmp (tmp_optabs
, this_target_optabs
, sizeof (struct target_optabs
)))
6336 TREE_OPTIMIZATION_OPTABS (optnode
) = tmp_optabs
;
6339 TREE_OPTIMIZATION_OPTABS (optnode
) = NULL
;
6340 ggc_free (tmp_optabs
);
6344 /* A helper function for init_sync_libfuncs. Using the basename BASE,
6345 install libfuncs into TAB for BASE_N for 1 <= N <= MAX. */
6348 init_sync_libfuncs_1 (optab tab
, const char *base
, int max
)
6350 enum machine_mode mode
;
6352 size_t len
= strlen (base
);
6355 gcc_assert (max
<= 8);
6356 gcc_assert (len
+ 3 < sizeof (buf
));
6358 memcpy (buf
, base
, len
);
6361 buf
[len
+ 2] = '\0';
6364 for (i
= 1; i
<= max
; i
*= 2)
6366 buf
[len
+ 1] = '0' + i
;
6367 set_optab_libfunc (tab
, mode
, buf
);
6368 mode
= GET_MODE_2XWIDER_MODE (mode
);
6373 init_sync_libfuncs (int max
)
6375 if (!flag_sync_libcalls
)
6378 init_sync_libfuncs_1 (sync_compare_and_swap_optab
,
6379 "__sync_val_compare_and_swap", max
);
6380 init_sync_libfuncs_1 (sync_lock_test_and_set_optab
,
6381 "__sync_lock_test_and_set", max
);
6383 init_sync_libfuncs_1 (sync_old_add_optab
, "__sync_fetch_and_add", max
);
6384 init_sync_libfuncs_1 (sync_old_sub_optab
, "__sync_fetch_and_sub", max
);
6385 init_sync_libfuncs_1 (sync_old_ior_optab
, "__sync_fetch_and_or", max
);
6386 init_sync_libfuncs_1 (sync_old_and_optab
, "__sync_fetch_and_and", max
);
6387 init_sync_libfuncs_1 (sync_old_xor_optab
, "__sync_fetch_and_xor", max
);
6388 init_sync_libfuncs_1 (sync_old_nand_optab
, "__sync_fetch_and_nand", max
);
6390 init_sync_libfuncs_1 (sync_new_add_optab
, "__sync_add_and_fetch", max
);
6391 init_sync_libfuncs_1 (sync_new_sub_optab
, "__sync_sub_and_fetch", max
);
6392 init_sync_libfuncs_1 (sync_new_ior_optab
, "__sync_or_and_fetch", max
);
6393 init_sync_libfuncs_1 (sync_new_and_optab
, "__sync_and_and_fetch", max
);
6394 init_sync_libfuncs_1 (sync_new_xor_optab
, "__sync_xor_and_fetch", max
);
6395 init_sync_libfuncs_1 (sync_new_nand_optab
, "__sync_nand_and_fetch", max
);
6398 /* Print information about the current contents of the optabs on
6402 debug_optab_libfuncs (void)
6406 /* Dump the arithmetic optabs. */
6407 for (i
= FIRST_NORM_OPTAB
; i
<= LAST_NORMLIB_OPTAB
; ++i
)
6408 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
6410 rtx l
= optab_libfunc ((optab
) i
, (enum machine_mode
) j
);
6413 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
6414 fprintf (stderr
, "%s\t%s:\t%s\n",
6415 GET_RTX_NAME (optab_to_code ((optab
) i
)),
6421 /* Dump the conversion optabs. */
6422 for (i
= FIRST_CONV_OPTAB
; i
<= LAST_CONVLIB_OPTAB
; ++i
)
6423 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
6424 for (k
= 0; k
< NUM_MACHINE_MODES
; ++k
)
6426 rtx l
= convert_optab_libfunc ((optab
) i
, (enum machine_mode
) j
,
6427 (enum machine_mode
) k
);
6430 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
6431 fprintf (stderr
, "%s\t%s\t%s:\t%s\n",
6432 GET_RTX_NAME (optab_to_code ((optab
) i
)),
6441 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6442 CODE. Return 0 on failure. */
6445 gen_cond_trap (enum rtx_code code
, rtx op1
, rtx op2
, rtx tcode
)
6447 enum machine_mode mode
= GET_MODE (op1
);
6448 enum insn_code icode
;
6452 if (mode
== VOIDmode
)
6455 icode
= optab_handler (ctrap_optab
, mode
);
6456 if (icode
== CODE_FOR_nothing
)
6459 /* Some targets only accept a zero trap code. */
6460 if (!insn_operand_matches (icode
, 3, tcode
))
6463 do_pending_stack_adjust ();
6465 prepare_cmp_insn (op1
, op2
, code
, NULL_RTX
, false, OPTAB_DIRECT
,
6470 insn
= GEN_FCN (icode
) (trap_rtx
, XEXP (trap_rtx
, 0), XEXP (trap_rtx
, 1),
6473 /* If that failed, then give up. */
6481 insn
= get_insns ();
6486 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6487 or unsigned operation code. */
6489 static enum rtx_code
6490 get_rtx_code (enum tree_code tcode
, bool unsignedp
)
6502 code
= unsignedp
? LTU
: LT
;
6505 code
= unsignedp
? LEU
: LE
;
6508 code
= unsignedp
? GTU
: GT
;
6511 code
= unsignedp
? GEU
: GE
;
6514 case UNORDERED_EXPR
:
6545 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6546 unsigned operators. Do not generate compare instruction. */
6549 vector_compare_rtx (enum tree_code tcode
, tree t_op0
, tree t_op1
,
6550 bool unsignedp
, enum insn_code icode
)
6552 struct expand_operand ops
[2];
6553 rtx rtx_op0
, rtx_op1
;
6554 enum rtx_code rcode
= get_rtx_code (tcode
, unsignedp
);
6556 gcc_assert (TREE_CODE_CLASS (tcode
) == tcc_comparison
);
6558 /* Expand operands. */
6559 rtx_op0
= expand_expr (t_op0
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op0
)),
6561 rtx_op1
= expand_expr (t_op1
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op1
)),
6564 create_input_operand (&ops
[0], rtx_op0
, GET_MODE (rtx_op0
));
6565 create_input_operand (&ops
[1], rtx_op1
, GET_MODE (rtx_op1
));
6566 if (!maybe_legitimize_operands (icode
, 4, 2, ops
))
6568 return gen_rtx_fmt_ee (rcode
, VOIDmode
, ops
[0].value
, ops
[1].value
);
6571 /* Return true if VEC_PERM_EXPR can be expanded using SIMD extensions
6572 of the CPU. SEL may be NULL, which stands for an unknown constant. */
6575 can_vec_perm_p (enum machine_mode mode
, bool variable
,
6576 const unsigned char *sel
)
6578 enum machine_mode qimode
;
6580 /* If the target doesn't implement a vector mode for the vector type,
6581 then no operations are supported. */
6582 if (!VECTOR_MODE_P (mode
))
6587 if (direct_optab_handler (vec_perm_const_optab
, mode
) != CODE_FOR_nothing
6589 || targetm
.vectorize
.vec_perm_const_ok
== NULL
6590 || targetm
.vectorize
.vec_perm_const_ok (mode
, sel
)))
6594 if (direct_optab_handler (vec_perm_optab
, mode
) != CODE_FOR_nothing
)
6597 /* We allow fallback to a QI vector mode, and adjust the mask. */
6598 if (GET_MODE_INNER (mode
) == QImode
)
6600 qimode
= mode_for_vector (QImode
, GET_MODE_SIZE (mode
));
6601 if (!VECTOR_MODE_P (qimode
))
6604 /* ??? For completeness, we ought to check the QImode version of
6605 vec_perm_const_optab. But all users of this implicit lowering
6606 feature implement the variable vec_perm_optab. */
6607 if (direct_optab_handler (vec_perm_optab
, qimode
) == CODE_FOR_nothing
)
6610 /* In order to support the lowering of variable permutations,
6611 we need to support shifts and adds. */
6614 if (GET_MODE_UNIT_SIZE (mode
) > 2
6615 && optab_handler (ashl_optab
, mode
) == CODE_FOR_nothing
6616 && optab_handler (vashl_optab
, mode
) == CODE_FOR_nothing
)
6618 if (optab_handler (add_optab
, qimode
) == CODE_FOR_nothing
)
6625 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
6628 expand_vec_perm_1 (enum insn_code icode
, rtx target
,
6629 rtx v0
, rtx v1
, rtx sel
)
6631 enum machine_mode tmode
= GET_MODE (target
);
6632 enum machine_mode smode
= GET_MODE (sel
);
6633 struct expand_operand ops
[4];
6635 create_output_operand (&ops
[0], target
, tmode
);
6636 create_input_operand (&ops
[3], sel
, smode
);
6638 /* Make an effort to preserve v0 == v1. The target expander is able to
6639 rely on this to determine if we're permuting a single input operand. */
6640 if (rtx_equal_p (v0
, v1
))
6642 if (!insn_operand_matches (icode
, 1, v0
))
6643 v0
= force_reg (tmode
, v0
);
6644 gcc_checking_assert (insn_operand_matches (icode
, 1, v0
));
6645 gcc_checking_assert (insn_operand_matches (icode
, 2, v0
));
6647 create_fixed_operand (&ops
[1], v0
);
6648 create_fixed_operand (&ops
[2], v0
);
6652 create_input_operand (&ops
[1], v0
, tmode
);
6653 create_input_operand (&ops
[2], v1
, tmode
);
6656 if (maybe_expand_insn (icode
, 4, ops
))
6657 return ops
[0].value
;
6661 /* Generate instructions for vec_perm optab given its mode
6662 and three operands. */
6665 expand_vec_perm (enum machine_mode mode
, rtx v0
, rtx v1
, rtx sel
, rtx target
)
6667 enum insn_code icode
;
6668 enum machine_mode qimode
;
6669 unsigned int i
, w
, e
, u
;
6670 rtx tmp
, sel_qi
= NULL
;
6673 if (!target
|| GET_MODE (target
) != mode
)
6674 target
= gen_reg_rtx (mode
);
6676 w
= GET_MODE_SIZE (mode
);
6677 e
= GET_MODE_NUNITS (mode
);
6678 u
= GET_MODE_UNIT_SIZE (mode
);
6680 /* Set QIMODE to a different vector mode with byte elements.
6681 If no such mode, or if MODE already has byte elements, use VOIDmode. */
6683 if (GET_MODE_INNER (mode
) != QImode
)
6685 qimode
= mode_for_vector (QImode
, w
);
6686 if (!VECTOR_MODE_P (qimode
))
6690 /* If the input is a constant, expand it specially. */
6691 gcc_assert (GET_MODE_CLASS (GET_MODE (sel
)) == MODE_VECTOR_INT
);
6692 if (GET_CODE (sel
) == CONST_VECTOR
)
6694 icode
= direct_optab_handler (vec_perm_const_optab
, mode
);
6695 if (icode
!= CODE_FOR_nothing
)
6697 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
6702 /* Fall back to a constant byte-based permutation. */
6703 if (qimode
!= VOIDmode
)
6705 vec
= rtvec_alloc (w
);
6706 for (i
= 0; i
< e
; ++i
)
6708 unsigned int j
, this_e
;
6710 this_e
= INTVAL (CONST_VECTOR_ELT (sel
, i
));
6711 this_e
&= 2 * e
- 1;
6714 for (j
= 0; j
< u
; ++j
)
6715 RTVEC_ELT (vec
, i
* u
+ j
) = GEN_INT (this_e
+ j
);
6717 sel_qi
= gen_rtx_CONST_VECTOR (qimode
, vec
);
6719 icode
= direct_optab_handler (vec_perm_const_optab
, qimode
);
6720 if (icode
!= CODE_FOR_nothing
)
6722 tmp
= mode
!= qimode
? gen_reg_rtx (qimode
) : target
;
6723 tmp
= expand_vec_perm_1 (icode
, tmp
, gen_lowpart (qimode
, v0
),
6724 gen_lowpart (qimode
, v1
), sel_qi
);
6726 return gen_lowpart (mode
, tmp
);
6731 /* Otherwise expand as a fully variable permuation. */
6732 icode
= direct_optab_handler (vec_perm_optab
, mode
);
6733 if (icode
!= CODE_FOR_nothing
)
6735 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
6740 /* As a special case to aid several targets, lower the element-based
6741 permutation to a byte-based permutation and try again. */
6742 if (qimode
== VOIDmode
)
6744 icode
= direct_optab_handler (vec_perm_optab
, qimode
);
6745 if (icode
== CODE_FOR_nothing
)
6750 /* Multiply each element by its byte size. */
6751 enum machine_mode selmode
= GET_MODE (sel
);
6753 sel
= expand_simple_binop (selmode
, PLUS
, sel
, sel
,
6754 sel
, 0, OPTAB_DIRECT
);
6756 sel
= expand_simple_binop (selmode
, ASHIFT
, sel
,
6757 GEN_INT (exact_log2 (u
)),
6758 sel
, 0, OPTAB_DIRECT
);
6759 gcc_assert (sel
!= NULL
);
6761 /* Broadcast the low byte each element into each of its bytes. */
6762 vec
= rtvec_alloc (w
);
6763 for (i
= 0; i
< w
; ++i
)
6765 int this_e
= i
/ u
* u
;
6766 if (BYTES_BIG_ENDIAN
)
6768 RTVEC_ELT (vec
, i
) = GEN_INT (this_e
);
6770 tmp
= gen_rtx_CONST_VECTOR (qimode
, vec
);
6771 sel
= gen_lowpart (qimode
, sel
);
6772 sel
= expand_vec_perm (qimode
, sel
, sel
, tmp
, NULL
);
6773 gcc_assert (sel
!= NULL
);
6775 /* Add the byte offset to each byte element. */
6776 /* Note that the definition of the indicies here is memory ordering,
6777 so there should be no difference between big and little endian. */
6778 vec
= rtvec_alloc (w
);
6779 for (i
= 0; i
< w
; ++i
)
6780 RTVEC_ELT (vec
, i
) = GEN_INT (i
% u
);
6781 tmp
= gen_rtx_CONST_VECTOR (qimode
, vec
);
6782 sel_qi
= expand_simple_binop (qimode
, PLUS
, sel
, tmp
,
6783 sel
, 0, OPTAB_DIRECT
);
6784 gcc_assert (sel_qi
!= NULL
);
6787 tmp
= mode
!= qimode
? gen_reg_rtx (qimode
) : target
;
6788 tmp
= expand_vec_perm_1 (icode
, tmp
, gen_lowpart (qimode
, v0
),
6789 gen_lowpart (qimode
, v1
), sel_qi
);
6791 tmp
= gen_lowpart (mode
, tmp
);
6795 /* Return insn code for a conditional operator with a comparison in
6796 mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE. */
6798 static inline enum insn_code
6799 get_vcond_icode (enum machine_mode vmode
, enum machine_mode cmode
, bool uns
)
6801 enum insn_code icode
= CODE_FOR_nothing
;
6803 icode
= convert_optab_handler (vcondu_optab
, vmode
, cmode
);
6805 icode
= convert_optab_handler (vcond_optab
, vmode
, cmode
);
6809 /* Return TRUE iff, appropriate vector insns are available
6810 for vector cond expr with vector type VALUE_TYPE and a comparison
6811 with operand vector types in CMP_OP_TYPE. */
6814 expand_vec_cond_expr_p (tree value_type
, tree cmp_op_type
)
6816 enum machine_mode value_mode
= TYPE_MODE (value_type
);
6817 enum machine_mode cmp_op_mode
= TYPE_MODE (cmp_op_type
);
6818 if (GET_MODE_SIZE (value_mode
) != GET_MODE_SIZE (cmp_op_mode
)
6819 || GET_MODE_NUNITS (value_mode
) != GET_MODE_NUNITS (cmp_op_mode
)
6820 || get_vcond_icode (TYPE_MODE (value_type
), TYPE_MODE (cmp_op_type
),
6821 TYPE_UNSIGNED (cmp_op_type
)) == CODE_FOR_nothing
)
6826 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
6830 expand_vec_cond_expr (tree vec_cond_type
, tree op0
, tree op1
, tree op2
,
6833 struct expand_operand ops
[6];
6834 enum insn_code icode
;
6835 rtx comparison
, rtx_op1
, rtx_op2
;
6836 enum machine_mode mode
= TYPE_MODE (vec_cond_type
);
6837 enum machine_mode cmp_op_mode
;
6840 enum tree_code tcode
;
6842 if (COMPARISON_CLASS_P (op0
))
6844 op0a
= TREE_OPERAND (op0
, 0);
6845 op0b
= TREE_OPERAND (op0
, 1);
6846 tcode
= TREE_CODE (op0
);
6851 gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (op0
)));
6853 op0b
= build_zero_cst (TREE_TYPE (op0
));
6856 unsignedp
= TYPE_UNSIGNED (TREE_TYPE (op0a
));
6857 cmp_op_mode
= TYPE_MODE (TREE_TYPE (op0a
));
6860 gcc_assert (GET_MODE_SIZE (mode
) == GET_MODE_SIZE (cmp_op_mode
)
6861 && GET_MODE_NUNITS (mode
) == GET_MODE_NUNITS (cmp_op_mode
));
6863 icode
= get_vcond_icode (mode
, cmp_op_mode
, unsignedp
);
6864 if (icode
== CODE_FOR_nothing
)
6867 comparison
= vector_compare_rtx (tcode
, op0a
, op0b
, unsignedp
, icode
);
6868 rtx_op1
= expand_normal (op1
);
6869 rtx_op2
= expand_normal (op2
);
6871 create_output_operand (&ops
[0], target
, mode
);
6872 create_input_operand (&ops
[1], rtx_op1
, mode
);
6873 create_input_operand (&ops
[2], rtx_op2
, mode
);
6874 create_fixed_operand (&ops
[3], comparison
);
6875 create_fixed_operand (&ops
[4], XEXP (comparison
, 0));
6876 create_fixed_operand (&ops
[5], XEXP (comparison
, 1));
6877 expand_insn (icode
, 6, ops
);
6878 return ops
[0].value
;
6881 /* Return non-zero if a highpart multiply is supported of can be synthisized.
6882 For the benefit of expand_mult_highpart, the return value is 1 for direct,
6883 2 for even/odd widening, and 3 for hi/lo widening. */
6886 can_mult_highpart_p (enum machine_mode mode
, bool uns_p
)
6892 op
= uns_p
? umul_highpart_optab
: smul_highpart_optab
;
6893 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6896 /* If the mode is an integral vector, synth from widening operations. */
6897 if (GET_MODE_CLASS (mode
) != MODE_VECTOR_INT
)
6900 nunits
= GET_MODE_NUNITS (mode
);
6901 sel
= XALLOCAVEC (unsigned char, nunits
);
6903 op
= uns_p
? vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
6904 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6906 op
= uns_p
? vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
6907 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6909 for (i
= 0; i
< nunits
; ++i
)
6910 sel
[i
] = !BYTES_BIG_ENDIAN
+ (i
& ~1) + ((i
& 1) ? nunits
: 0);
6911 if (can_vec_perm_p (mode
, false, sel
))
6916 op
= uns_p
? vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
6917 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6919 op
= uns_p
? vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
6920 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6922 for (i
= 0; i
< nunits
; ++i
)
6923 sel
[i
] = 2 * i
+ (BYTES_BIG_ENDIAN
? 0 : 1);
6924 if (can_vec_perm_p (mode
, false, sel
))
6932 /* Expand a highpart multiply. */
6935 expand_mult_highpart (enum machine_mode mode
, rtx op0
, rtx op1
,
6936 rtx target
, bool uns_p
)
6938 struct expand_operand eops
[3];
6939 enum insn_code icode
;
6940 int method
, i
, nunits
;
6941 enum machine_mode wmode
;
6946 method
= can_mult_highpart_p (mode
, uns_p
);
6952 tab1
= uns_p
? umul_highpart_optab
: smul_highpart_optab
;
6953 return expand_binop (mode
, tab1
, op0
, op1
, target
, uns_p
,
6956 tab1
= uns_p
? vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
6957 tab2
= uns_p
? vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
6960 tab1
= uns_p
? vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
6961 tab2
= uns_p
? vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
6962 if (BYTES_BIG_ENDIAN
)
6973 icode
= optab_handler (tab1
, mode
);
6974 nunits
= GET_MODE_NUNITS (mode
);
6975 wmode
= insn_data
[icode
].operand
[0].mode
;
6976 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode
) == nunits
);
6977 gcc_checking_assert (GET_MODE_SIZE (wmode
) == GET_MODE_SIZE (mode
));
6979 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
6980 create_input_operand (&eops
[1], op0
, mode
);
6981 create_input_operand (&eops
[2], op1
, mode
);
6982 expand_insn (icode
, 3, eops
);
6983 m1
= gen_lowpart (mode
, eops
[0].value
);
6985 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
6986 create_input_operand (&eops
[1], op0
, mode
);
6987 create_input_operand (&eops
[2], op1
, mode
);
6988 expand_insn (optab_handler (tab2
, mode
), 3, eops
);
6989 m2
= gen_lowpart (mode
, eops
[0].value
);
6991 v
= rtvec_alloc (nunits
);
6994 for (i
= 0; i
< nunits
; ++i
)
6995 RTVEC_ELT (v
, i
) = GEN_INT (!BYTES_BIG_ENDIAN
+ (i
& ~1)
6996 + ((i
& 1) ? nunits
: 0));
7000 for (i
= 0; i
< nunits
; ++i
)
7001 RTVEC_ELT (v
, i
) = GEN_INT (2 * i
+ (BYTES_BIG_ENDIAN
? 0 : 1));
7003 perm
= gen_rtx_CONST_VECTOR (mode
, v
);
7005 return expand_vec_perm (mode
, m1
, m2
, perm
, target
);
7008 /* Return true if target supports vector masked load/store for mode. */
7010 can_vec_mask_load_store_p (enum machine_mode mode
, bool is_load
)
7012 optab op
= is_load
? maskload_optab
: maskstore_optab
;
7013 enum machine_mode vmode
;
7014 unsigned int vector_sizes
;
7016 /* If mode is vector mode, check it directly. */
7017 if (VECTOR_MODE_P (mode
))
7018 return optab_handler (op
, mode
) != CODE_FOR_nothing
;
7020 /* Otherwise, return true if there is some vector mode with
7021 the mask load/store supported. */
7023 /* See if there is any chance the mask load or store might be
7024 vectorized. If not, punt. */
7025 vmode
= targetm
.vectorize
.preferred_simd_mode (mode
);
7026 if (!VECTOR_MODE_P (vmode
))
7029 if (optab_handler (op
, vmode
) != CODE_FOR_nothing
)
7032 vector_sizes
= targetm
.vectorize
.autovectorize_vector_sizes ();
7033 while (vector_sizes
!= 0)
7035 unsigned int cur
= 1 << floor_log2 (vector_sizes
);
7036 vector_sizes
&= ~cur
;
7037 if (cur
<= GET_MODE_SIZE (mode
))
7039 vmode
= mode_for_vector (mode
, cur
/ GET_MODE_SIZE (mode
));
7040 if (VECTOR_MODE_P (vmode
)
7041 && optab_handler (op
, vmode
) != CODE_FOR_nothing
)
7047 /* Return true if there is a compare_and_swap pattern. */
7050 can_compare_and_swap_p (enum machine_mode mode
, bool allow_libcall
)
7052 enum insn_code icode
;
7054 /* Check for __atomic_compare_and_swap. */
7055 icode
= direct_optab_handler (atomic_compare_and_swap_optab
, mode
);
7056 if (icode
!= CODE_FOR_nothing
)
7059 /* Check for __sync_compare_and_swap. */
7060 icode
= optab_handler (sync_compare_and_swap_optab
, mode
);
7061 if (icode
!= CODE_FOR_nothing
)
7063 if (allow_libcall
&& optab_libfunc (sync_compare_and_swap_optab
, mode
))
7066 /* No inline compare and swap. */
7070 /* Return true if an atomic exchange can be performed. */
7073 can_atomic_exchange_p (enum machine_mode mode
, bool allow_libcall
)
7075 enum insn_code icode
;
7077 /* Check for __atomic_exchange. */
7078 icode
= direct_optab_handler (atomic_exchange_optab
, mode
);
7079 if (icode
!= CODE_FOR_nothing
)
7082 /* Don't check __sync_test_and_set, as on some platforms that
7083 has reduced functionality. Targets that really do support
7084 a proper exchange should simply be updated to the __atomics. */
7086 return can_compare_and_swap_p (mode
, allow_libcall
);
7090 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
7094 find_cc_set (rtx x
, const_rtx pat
, void *data
)
7096 if (REG_P (x
) && GET_MODE_CLASS (GET_MODE (x
)) == MODE_CC
7097 && GET_CODE (pat
) == SET
)
7099 rtx
*p_cc_reg
= (rtx
*) data
;
7100 gcc_assert (!*p_cc_reg
);
7105 /* This is a helper function for the other atomic operations. This function
7106 emits a loop that contains SEQ that iterates until a compare-and-swap
7107 operation at the end succeeds. MEM is the memory to be modified. SEQ is
7108 a set of instructions that takes a value from OLD_REG as an input and
7109 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
7110 set to the current contents of MEM. After SEQ, a compare-and-swap will
7111 attempt to update MEM with NEW_REG. The function returns true when the
7112 loop was generated successfully. */
7115 expand_compare_and_swap_loop (rtx mem
, rtx old_reg
, rtx new_reg
, rtx seq
)
7117 enum machine_mode mode
= GET_MODE (mem
);
7118 rtx_code_label
*label
;
7119 rtx cmp_reg
, success
, oldval
;
7121 /* The loop we want to generate looks like
7127 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
7131 Note that we only do the plain load from memory once. Subsequent
7132 iterations use the value loaded by the compare-and-swap pattern. */
7134 label
= gen_label_rtx ();
7135 cmp_reg
= gen_reg_rtx (mode
);
7137 emit_move_insn (cmp_reg
, mem
);
7139 emit_move_insn (old_reg
, cmp_reg
);
7145 if (!expand_atomic_compare_and_swap (&success
, &oldval
, mem
, old_reg
,
7146 new_reg
, false, MEMMODEL_SEQ_CST
,
7150 if (oldval
!= cmp_reg
)
7151 emit_move_insn (cmp_reg
, oldval
);
7153 /* Mark this jump predicted not taken. */
7154 emit_cmp_and_jump_insns (success
, const0_rtx
, EQ
, const0_rtx
,
7155 GET_MODE (success
), 1, label
, 0);
7160 /* This function tries to emit an atomic_exchange intruction. VAL is written
7161 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
7162 using TARGET if possible. */
7165 maybe_emit_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
7167 enum machine_mode mode
= GET_MODE (mem
);
7168 enum insn_code icode
;
7170 /* If the target supports the exchange directly, great. */
7171 icode
= direct_optab_handler (atomic_exchange_optab
, mode
);
7172 if (icode
!= CODE_FOR_nothing
)
7174 struct expand_operand ops
[4];
7176 create_output_operand (&ops
[0], target
, mode
);
7177 create_fixed_operand (&ops
[1], mem
);
7178 create_input_operand (&ops
[2], val
, mode
);
7179 create_integer_operand (&ops
[3], model
);
7180 if (maybe_expand_insn (icode
, 4, ops
))
7181 return ops
[0].value
;
7187 /* This function tries to implement an atomic exchange operation using
7188 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
7189 The previous contents of *MEM are returned, using TARGET if possible.
7190 Since this instructionn is an acquire barrier only, stronger memory
7191 models may require additional barriers to be emitted. */
7194 maybe_emit_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
,
7195 enum memmodel model
)
7197 enum machine_mode mode
= GET_MODE (mem
);
7198 enum insn_code icode
;
7199 rtx_insn
*last_insn
= get_last_insn ();
7201 icode
= optab_handler (sync_lock_test_and_set_optab
, mode
);
7203 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
7204 exists, and the memory model is stronger than acquire, add a release
7205 barrier before the instruction. */
7207 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
7208 || (model
& MEMMODEL_MASK
) == MEMMODEL_RELEASE
7209 || (model
& MEMMODEL_MASK
) == MEMMODEL_ACQ_REL
)
7210 expand_mem_thread_fence (model
);
7212 if (icode
!= CODE_FOR_nothing
)
7214 struct expand_operand ops
[3];
7215 create_output_operand (&ops
[0], target
, mode
);
7216 create_fixed_operand (&ops
[1], mem
);
7217 create_input_operand (&ops
[2], val
, mode
);
7218 if (maybe_expand_insn (icode
, 3, ops
))
7219 return ops
[0].value
;
7222 /* If an external test-and-set libcall is provided, use that instead of
7223 any external compare-and-swap that we might get from the compare-and-
7224 swap-loop expansion later. */
7225 if (!can_compare_and_swap_p (mode
, false))
7227 rtx libfunc
= optab_libfunc (sync_lock_test_and_set_optab
, mode
);
7228 if (libfunc
!= NULL
)
7232 addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
7233 return emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
7234 mode
, 2, addr
, ptr_mode
,
7239 /* If the test_and_set can't be emitted, eliminate any barrier that might
7240 have been emitted. */
7241 delete_insns_since (last_insn
);
7245 /* This function tries to implement an atomic exchange operation using a
7246 compare_and_swap loop. VAL is written to *MEM. The previous contents of
7247 *MEM are returned, using TARGET if possible. No memory model is required
7248 since a compare_and_swap loop is seq-cst. */
7251 maybe_emit_compare_and_swap_exchange_loop (rtx target
, rtx mem
, rtx val
)
7253 enum machine_mode mode
= GET_MODE (mem
);
7255 if (can_compare_and_swap_p (mode
, true))
7257 if (!target
|| !register_operand (target
, mode
))
7258 target
= gen_reg_rtx (mode
);
7259 if (expand_compare_and_swap_loop (mem
, target
, val
, NULL_RTX
))
7266 /* This function tries to implement an atomic test-and-set operation
7267 using the atomic_test_and_set instruction pattern. A boolean value
7268 is returned from the operation, using TARGET if possible. */
7270 #ifndef HAVE_atomic_test_and_set
7271 #define HAVE_atomic_test_and_set 0
7272 #define CODE_FOR_atomic_test_and_set CODE_FOR_nothing
7276 maybe_emit_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
7278 enum machine_mode pat_bool_mode
;
7279 struct expand_operand ops
[3];
7281 if (!HAVE_atomic_test_and_set
)
7284 /* While we always get QImode from __atomic_test_and_set, we get
7285 other memory modes from __sync_lock_test_and_set. Note that we
7286 use no endian adjustment here. This matches the 4.6 behavior
7287 in the Sparc backend. */
7289 (insn_data
[CODE_FOR_atomic_test_and_set
].operand
[1].mode
== QImode
);
7290 if (GET_MODE (mem
) != QImode
)
7291 mem
= adjust_address_nv (mem
, QImode
, 0);
7293 pat_bool_mode
= insn_data
[CODE_FOR_atomic_test_and_set
].operand
[0].mode
;
7294 create_output_operand (&ops
[0], target
, pat_bool_mode
);
7295 create_fixed_operand (&ops
[1], mem
);
7296 create_integer_operand (&ops
[2], model
);
7298 if (maybe_expand_insn (CODE_FOR_atomic_test_and_set
, 3, ops
))
7299 return ops
[0].value
;
7303 /* This function expands the legacy _sync_lock test_and_set operation which is
7304 generally an atomic exchange. Some limited targets only allow the
7305 constant 1 to be stored. This is an ACQUIRE operation.
7307 TARGET is an optional place to stick the return value.
7308 MEM is where VAL is stored. */
7311 expand_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
)
7315 /* Try an atomic_exchange first. */
7316 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, MEMMODEL_ACQUIRE
);
7320 ret
= maybe_emit_sync_lock_test_and_set (target
, mem
, val
, MEMMODEL_ACQUIRE
);
7324 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
7328 /* If there are no other options, try atomic_test_and_set if the value
7329 being stored is 1. */
7330 if (val
== const1_rtx
)
7331 ret
= maybe_emit_atomic_test_and_set (target
, mem
, MEMMODEL_ACQUIRE
);
7336 /* This function expands the atomic test_and_set operation:
7337 atomically store a boolean TRUE into MEM and return the previous value.
7339 MEMMODEL is the memory model variant to use.
7340 TARGET is an optional place to stick the return value. */
7343 expand_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
7345 enum machine_mode mode
= GET_MODE (mem
);
7346 rtx ret
, trueval
, subtarget
;
7348 ret
= maybe_emit_atomic_test_and_set (target
, mem
, model
);
7352 /* Be binary compatible with non-default settings of trueval, and different
7353 cpu revisions. E.g. one revision may have atomic-test-and-set, but
7354 another only has atomic-exchange. */
7355 if (targetm
.atomic_test_and_set_trueval
== 1)
7357 trueval
= const1_rtx
;
7358 subtarget
= target
? target
: gen_reg_rtx (mode
);
7362 trueval
= gen_int_mode (targetm
.atomic_test_and_set_trueval
, mode
);
7363 subtarget
= gen_reg_rtx (mode
);
7366 /* Try the atomic-exchange optab... */
7367 ret
= maybe_emit_atomic_exchange (subtarget
, mem
, trueval
, model
);
7369 /* ... then an atomic-compare-and-swap loop ... */
7371 ret
= maybe_emit_compare_and_swap_exchange_loop (subtarget
, mem
, trueval
);
7373 /* ... before trying the vaguely defined legacy lock_test_and_set. */
7375 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, trueval
, model
);
7377 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
7378 things with the value 1. Thus we try again without trueval. */
7379 if (!ret
&& targetm
.atomic_test_and_set_trueval
!= 1)
7380 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, const1_rtx
, model
);
7382 /* Failing all else, assume a single threaded environment and simply
7383 perform the operation. */
7386 /* If the result is ignored skip the move to target. */
7387 if (subtarget
!= const0_rtx
)
7388 emit_move_insn (subtarget
, mem
);
7390 emit_move_insn (mem
, trueval
);
7394 /* Recall that have to return a boolean value; rectify if trueval
7395 is not exactly one. */
7396 if (targetm
.atomic_test_and_set_trueval
!= 1)
7397 ret
= emit_store_flag_force (target
, NE
, ret
, const0_rtx
, mode
, 0, 1);
7402 /* This function expands the atomic exchange operation:
7403 atomically store VAL in MEM and return the previous value in MEM.
7405 MEMMODEL is the memory model variant to use.
7406 TARGET is an optional place to stick the return value. */
7409 expand_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
7413 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, model
);
7415 /* Next try a compare-and-swap loop for the exchange. */
7417 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
7422 /* This function expands the atomic compare exchange operation:
7424 *PTARGET_BOOL is an optional place to store the boolean success/failure.
7425 *PTARGET_OVAL is an optional place to store the old value from memory.
7426 Both target parameters may be NULL to indicate that we do not care about
7427 that return value. Both target parameters are updated on success to
7428 the actual location of the corresponding result.
7430 MEMMODEL is the memory model variant to use.
7432 The return value of the function is true for success. */
7435 expand_atomic_compare_and_swap (rtx
*ptarget_bool
, rtx
*ptarget_oval
,
7436 rtx mem
, rtx expected
, rtx desired
,
7437 bool is_weak
, enum memmodel succ_model
,
7438 enum memmodel fail_model
)
7440 enum machine_mode mode
= GET_MODE (mem
);
7441 struct expand_operand ops
[8];
7442 enum insn_code icode
;
7443 rtx target_oval
, target_bool
= NULL_RTX
;
7446 /* Load expected into a register for the compare and swap. */
7447 if (MEM_P (expected
))
7448 expected
= copy_to_reg (expected
);
7450 /* Make sure we always have some place to put the return oldval.
7451 Further, make sure that place is distinct from the input expected,
7452 just in case we need that path down below. */
7453 if (ptarget_oval
== NULL
7454 || (target_oval
= *ptarget_oval
) == NULL
7455 || reg_overlap_mentioned_p (expected
, target_oval
))
7456 target_oval
= gen_reg_rtx (mode
);
7458 icode
= direct_optab_handler (atomic_compare_and_swap_optab
, mode
);
7459 if (icode
!= CODE_FOR_nothing
)
7461 enum machine_mode bool_mode
= insn_data
[icode
].operand
[0].mode
;
7463 /* Make sure we always have a place for the bool operand. */
7464 if (ptarget_bool
== NULL
7465 || (target_bool
= *ptarget_bool
) == NULL
7466 || GET_MODE (target_bool
) != bool_mode
)
7467 target_bool
= gen_reg_rtx (bool_mode
);
7469 /* Emit the compare_and_swap. */
7470 create_output_operand (&ops
[0], target_bool
, bool_mode
);
7471 create_output_operand (&ops
[1], target_oval
, mode
);
7472 create_fixed_operand (&ops
[2], mem
);
7473 create_input_operand (&ops
[3], expected
, mode
);
7474 create_input_operand (&ops
[4], desired
, mode
);
7475 create_integer_operand (&ops
[5], is_weak
);
7476 create_integer_operand (&ops
[6], succ_model
);
7477 create_integer_operand (&ops
[7], fail_model
);
7478 if (maybe_expand_insn (icode
, 8, ops
))
7480 /* Return success/failure. */
7481 target_bool
= ops
[0].value
;
7482 target_oval
= ops
[1].value
;
7487 /* Otherwise fall back to the original __sync_val_compare_and_swap
7488 which is always seq-cst. */
7489 icode
= optab_handler (sync_compare_and_swap_optab
, mode
);
7490 if (icode
!= CODE_FOR_nothing
)
7494 create_output_operand (&ops
[0], target_oval
, mode
);
7495 create_fixed_operand (&ops
[1], mem
);
7496 create_input_operand (&ops
[2], expected
, mode
);
7497 create_input_operand (&ops
[3], desired
, mode
);
7498 if (!maybe_expand_insn (icode
, 4, ops
))
7501 target_oval
= ops
[0].value
;
7503 /* If the caller isn't interested in the boolean return value,
7504 skip the computation of it. */
7505 if (ptarget_bool
== NULL
)
7508 /* Otherwise, work out if the compare-and-swap succeeded. */
7510 if (have_insn_for (COMPARE
, CCmode
))
7511 note_stores (PATTERN (get_last_insn ()), find_cc_set
, &cc_reg
);
7514 target_bool
= emit_store_flag_force (target_bool
, EQ
, cc_reg
,
7515 const0_rtx
, VOIDmode
, 0, 1);
7518 goto success_bool_from_val
;
7521 /* Also check for library support for __sync_val_compare_and_swap. */
7522 libfunc
= optab_libfunc (sync_compare_and_swap_optab
, mode
);
7523 if (libfunc
!= NULL
)
7525 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
7526 target_oval
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
7527 mode
, 3, addr
, ptr_mode
,
7528 expected
, mode
, desired
, mode
);
7530 /* Compute the boolean return value only if requested. */
7532 goto success_bool_from_val
;
7540 success_bool_from_val
:
7541 target_bool
= emit_store_flag_force (target_bool
, EQ
, target_oval
,
7542 expected
, VOIDmode
, 1, 1);
7544 /* Make sure that the oval output winds up where the caller asked. */
7546 *ptarget_oval
= target_oval
;
7548 *ptarget_bool
= target_bool
;
7552 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
7555 expand_asm_memory_barrier (void)
7559 asm_op
= gen_rtx_ASM_OPERANDS (VOIDmode
, empty_string
, empty_string
, 0,
7560 rtvec_alloc (0), rtvec_alloc (0),
7561 rtvec_alloc (0), UNKNOWN_LOCATION
);
7562 MEM_VOLATILE_P (asm_op
) = 1;
7564 clob
= gen_rtx_SCRATCH (VOIDmode
);
7565 clob
= gen_rtx_MEM (BLKmode
, clob
);
7566 clob
= gen_rtx_CLOBBER (VOIDmode
, clob
);
7568 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, asm_op
, clob
)));
7571 /* This routine will either emit the mem_thread_fence pattern or issue a
7572 sync_synchronize to generate a fence for memory model MEMMODEL. */
7574 #ifndef HAVE_mem_thread_fence
7575 # define HAVE_mem_thread_fence 0
7576 # define gen_mem_thread_fence(x) (gcc_unreachable (), NULL_RTX)
7578 #ifndef HAVE_memory_barrier
7579 # define HAVE_memory_barrier 0
7580 # define gen_memory_barrier() (gcc_unreachable (), NULL_RTX)
7584 expand_mem_thread_fence (enum memmodel model
)
7586 if (HAVE_mem_thread_fence
)
7587 emit_insn (gen_mem_thread_fence (GEN_INT (model
)));
7588 else if ((model
& MEMMODEL_MASK
) != MEMMODEL_RELAXED
)
7590 if (HAVE_memory_barrier
)
7591 emit_insn (gen_memory_barrier ());
7592 else if (synchronize_libfunc
!= NULL_RTX
)
7593 emit_library_call (synchronize_libfunc
, LCT_NORMAL
, VOIDmode
, 0);
7595 expand_asm_memory_barrier ();
7599 /* This routine will either emit the mem_signal_fence pattern or issue a
7600 sync_synchronize to generate a fence for memory model MEMMODEL. */
7602 #ifndef HAVE_mem_signal_fence
7603 # define HAVE_mem_signal_fence 0
7604 # define gen_mem_signal_fence(x) (gcc_unreachable (), NULL_RTX)
7608 expand_mem_signal_fence (enum memmodel model
)
7610 if (HAVE_mem_signal_fence
)
7611 emit_insn (gen_mem_signal_fence (GEN_INT (model
)));
7612 else if ((model
& MEMMODEL_MASK
) != MEMMODEL_RELAXED
)
7614 /* By default targets are coherent between a thread and the signal
7615 handler running on the same thread. Thus this really becomes a
7616 compiler barrier, in that stores must not be sunk past
7617 (or raised above) a given point. */
7618 expand_asm_memory_barrier ();
7622 /* This function expands the atomic load operation:
7623 return the atomically loaded value in MEM.
7625 MEMMODEL is the memory model variant to use.
7626 TARGET is an option place to stick the return value. */
7629 expand_atomic_load (rtx target
, rtx mem
, enum memmodel model
)
7631 enum machine_mode mode
= GET_MODE (mem
);
7632 enum insn_code icode
;
7634 /* If the target supports the load directly, great. */
7635 icode
= direct_optab_handler (atomic_load_optab
, mode
);
7636 if (icode
!= CODE_FOR_nothing
)
7638 struct expand_operand ops
[3];
7640 create_output_operand (&ops
[0], target
, mode
);
7641 create_fixed_operand (&ops
[1], mem
);
7642 create_integer_operand (&ops
[2], model
);
7643 if (maybe_expand_insn (icode
, 3, ops
))
7644 return ops
[0].value
;
7647 /* If the size of the object is greater than word size on this target,
7648 then we assume that a load will not be atomic. */
7649 if (GET_MODE_PRECISION (mode
) > BITS_PER_WORD
)
7651 /* Issue val = compare_and_swap (mem, 0, 0).
7652 This may cause the occasional harmless store of 0 when the value is
7653 already 0, but it seems to be OK according to the standards guys. */
7654 if (expand_atomic_compare_and_swap (NULL
, &target
, mem
, const0_rtx
,
7655 const0_rtx
, false, model
, model
))
7658 /* Otherwise there is no atomic load, leave the library call. */
7662 /* Otherwise assume loads are atomic, and emit the proper barriers. */
7663 if (!target
|| target
== const0_rtx
)
7664 target
= gen_reg_rtx (mode
);
7666 /* For SEQ_CST, emit a barrier before the load. */
7667 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
)
7668 expand_mem_thread_fence (model
);
7670 emit_move_insn (target
, mem
);
7672 /* Emit the appropriate barrier after the load. */
7673 expand_mem_thread_fence (model
);
7678 /* This function expands the atomic store operation:
7679 Atomically store VAL in MEM.
7680 MEMMODEL is the memory model variant to use.
7681 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
7682 function returns const0_rtx if a pattern was emitted. */
7685 expand_atomic_store (rtx mem
, rtx val
, enum memmodel model
, bool use_release
)
7687 enum machine_mode mode
= GET_MODE (mem
);
7688 enum insn_code icode
;
7689 struct expand_operand ops
[3];
7691 /* If the target supports the store directly, great. */
7692 icode
= direct_optab_handler (atomic_store_optab
, mode
);
7693 if (icode
!= CODE_FOR_nothing
)
7695 create_fixed_operand (&ops
[0], mem
);
7696 create_input_operand (&ops
[1], val
, mode
);
7697 create_integer_operand (&ops
[2], model
);
7698 if (maybe_expand_insn (icode
, 3, ops
))
7702 /* If using __sync_lock_release is a viable alternative, try it. */
7705 icode
= direct_optab_handler (sync_lock_release_optab
, mode
);
7706 if (icode
!= CODE_FOR_nothing
)
7708 create_fixed_operand (&ops
[0], mem
);
7709 create_input_operand (&ops
[1], const0_rtx
, mode
);
7710 if (maybe_expand_insn (icode
, 2, ops
))
7712 /* lock_release is only a release barrier. */
7713 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
)
7714 expand_mem_thread_fence (model
);
7720 /* If the size of the object is greater than word size on this target,
7721 a default store will not be atomic, Try a mem_exchange and throw away
7722 the result. If that doesn't work, don't do anything. */
7723 if (GET_MODE_PRECISION (mode
) > BITS_PER_WORD
)
7725 rtx target
= maybe_emit_atomic_exchange (NULL_RTX
, mem
, val
, model
);
7727 target
= maybe_emit_compare_and_swap_exchange_loop (NULL_RTX
, mem
, val
);
7734 /* Otherwise assume stores are atomic, and emit the proper barriers. */
7735 expand_mem_thread_fence (model
);
7737 emit_move_insn (mem
, val
);
7739 /* For SEQ_CST, also emit a barrier after the store. */
7740 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
)
7741 expand_mem_thread_fence (model
);
7747 /* Structure containing the pointers and values required to process the
7748 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
7750 struct atomic_op_functions
7752 direct_optab mem_fetch_before
;
7753 direct_optab mem_fetch_after
;
7754 direct_optab mem_no_result
;
7757 direct_optab no_result
;
7758 enum rtx_code reverse_code
;
7762 /* Fill in structure pointed to by OP with the various optab entries for an
7763 operation of type CODE. */
7766 get_atomic_op_for_code (struct atomic_op_functions
*op
, enum rtx_code code
)
7768 gcc_assert (op
!= NULL
);
7770 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
7771 in the source code during compilation, and the optab entries are not
7772 computable until runtime. Fill in the values at runtime. */
7776 op
->mem_fetch_before
= atomic_fetch_add_optab
;
7777 op
->mem_fetch_after
= atomic_add_fetch_optab
;
7778 op
->mem_no_result
= atomic_add_optab
;
7779 op
->fetch_before
= sync_old_add_optab
;
7780 op
->fetch_after
= sync_new_add_optab
;
7781 op
->no_result
= sync_add_optab
;
7782 op
->reverse_code
= MINUS
;
7785 op
->mem_fetch_before
= atomic_fetch_sub_optab
;
7786 op
->mem_fetch_after
= atomic_sub_fetch_optab
;
7787 op
->mem_no_result
= atomic_sub_optab
;
7788 op
->fetch_before
= sync_old_sub_optab
;
7789 op
->fetch_after
= sync_new_sub_optab
;
7790 op
->no_result
= sync_sub_optab
;
7791 op
->reverse_code
= PLUS
;
7794 op
->mem_fetch_before
= atomic_fetch_xor_optab
;
7795 op
->mem_fetch_after
= atomic_xor_fetch_optab
;
7796 op
->mem_no_result
= atomic_xor_optab
;
7797 op
->fetch_before
= sync_old_xor_optab
;
7798 op
->fetch_after
= sync_new_xor_optab
;
7799 op
->no_result
= sync_xor_optab
;
7800 op
->reverse_code
= XOR
;
7803 op
->mem_fetch_before
= atomic_fetch_and_optab
;
7804 op
->mem_fetch_after
= atomic_and_fetch_optab
;
7805 op
->mem_no_result
= atomic_and_optab
;
7806 op
->fetch_before
= sync_old_and_optab
;
7807 op
->fetch_after
= sync_new_and_optab
;
7808 op
->no_result
= sync_and_optab
;
7809 op
->reverse_code
= UNKNOWN
;
7812 op
->mem_fetch_before
= atomic_fetch_or_optab
;
7813 op
->mem_fetch_after
= atomic_or_fetch_optab
;
7814 op
->mem_no_result
= atomic_or_optab
;
7815 op
->fetch_before
= sync_old_ior_optab
;
7816 op
->fetch_after
= sync_new_ior_optab
;
7817 op
->no_result
= sync_ior_optab
;
7818 op
->reverse_code
= UNKNOWN
;
7821 op
->mem_fetch_before
= atomic_fetch_nand_optab
;
7822 op
->mem_fetch_after
= atomic_nand_fetch_optab
;
7823 op
->mem_no_result
= atomic_nand_optab
;
7824 op
->fetch_before
= sync_old_nand_optab
;
7825 op
->fetch_after
= sync_new_nand_optab
;
7826 op
->no_result
= sync_nand_optab
;
7827 op
->reverse_code
= UNKNOWN
;
7834 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
7835 using memory order MODEL. If AFTER is true the operation needs to return
7836 the value of *MEM after the operation, otherwise the previous value.
7837 TARGET is an optional place to place the result. The result is unused if
7839 Return the result if there is a better sequence, otherwise NULL_RTX. */
7842 maybe_optimize_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
7843 enum memmodel model
, bool after
)
7845 /* If the value is prefetched, or not used, it may be possible to replace
7846 the sequence with a native exchange operation. */
7847 if (!after
|| target
== const0_rtx
)
7849 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
7850 if (code
== AND
&& val
== const0_rtx
)
7852 if (target
== const0_rtx
)
7853 target
= gen_reg_rtx (GET_MODE (mem
));
7854 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
7857 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
7858 if (code
== IOR
&& val
== constm1_rtx
)
7860 if (target
== const0_rtx
)
7861 target
= gen_reg_rtx (GET_MODE (mem
));
7862 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
7869 /* Try to emit an instruction for a specific operation varaition.
7870 OPTAB contains the OP functions.
7871 TARGET is an optional place to return the result. const0_rtx means unused.
7872 MEM is the memory location to operate on.
7873 VAL is the value to use in the operation.
7874 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
7875 MODEL is the memory model, if used.
7876 AFTER is true if the returned result is the value after the operation. */
7879 maybe_emit_op (const struct atomic_op_functions
*optab
, rtx target
, rtx mem
,
7880 rtx val
, bool use_memmodel
, enum memmodel model
, bool after
)
7882 enum machine_mode mode
= GET_MODE (mem
);
7883 struct expand_operand ops
[4];
7884 enum insn_code icode
;
7888 /* Check to see if there is a result returned. */
7889 if (target
== const0_rtx
)
7893 icode
= direct_optab_handler (optab
->mem_no_result
, mode
);
7894 create_integer_operand (&ops
[2], model
);
7899 icode
= direct_optab_handler (optab
->no_result
, mode
);
7903 /* Otherwise, we need to generate a result. */
7908 icode
= direct_optab_handler (after
? optab
->mem_fetch_after
7909 : optab
->mem_fetch_before
, mode
);
7910 create_integer_operand (&ops
[3], model
);
7915 icode
= optab_handler (after
? optab
->fetch_after
7916 : optab
->fetch_before
, mode
);
7919 create_output_operand (&ops
[op_counter
++], target
, mode
);
7921 if (icode
== CODE_FOR_nothing
)
7924 create_fixed_operand (&ops
[op_counter
++], mem
);
7925 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7926 create_convert_operand_to (&ops
[op_counter
++], val
, mode
, true);
7928 if (maybe_expand_insn (icode
, num_ops
, ops
))
7929 return (target
== const0_rtx
? const0_rtx
: ops
[0].value
);
7935 /* This function expands an atomic fetch_OP or OP_fetch operation:
7936 TARGET is an option place to stick the return value. const0_rtx indicates
7937 the result is unused.
7938 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7939 CODE is the operation being performed (OP)
7940 MEMMODEL is the memory model variant to use.
7941 AFTER is true to return the result of the operation (OP_fetch).
7942 AFTER is false to return the value before the operation (fetch_OP).
7944 This function will *only* generate instructions if there is a direct
7945 optab. No compare and swap loops or libcalls will be generated. */
7948 expand_atomic_fetch_op_no_fallback (rtx target
, rtx mem
, rtx val
,
7949 enum rtx_code code
, enum memmodel model
,
7952 enum machine_mode mode
= GET_MODE (mem
);
7953 struct atomic_op_functions optab
;
7955 bool unused_result
= (target
== const0_rtx
);
7957 get_atomic_op_for_code (&optab
, code
);
7959 /* Check to see if there are any better instructions. */
7960 result
= maybe_optimize_fetch_op (target
, mem
, val
, code
, model
, after
);
7964 /* Check for the case where the result isn't used and try those patterns. */
7967 /* Try the memory model variant first. */
7968 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, true);
7972 /* Next try the old style withuot a memory model. */
7973 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, true);
7977 /* There is no no-result pattern, so try patterns with a result. */
7981 /* Try the __atomic version. */
7982 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, after
);
7986 /* Try the older __sync version. */
7987 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, after
);
7991 /* If the fetch value can be calculated from the other variation of fetch,
7992 try that operation. */
7993 if (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
)
7995 /* Try the __atomic version, then the older __sync version. */
7996 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, !after
);
7998 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, !after
);
8002 /* If the result isn't used, no need to do compensation code. */
8006 /* Issue compensation code. Fetch_after == fetch_before OP val.
8007 Fetch_before == after REVERSE_OP val. */
8009 code
= optab
.reverse_code
;
8012 result
= expand_simple_binop (mode
, AND
, result
, val
, NULL_RTX
,
8013 true, OPTAB_LIB_WIDEN
);
8014 result
= expand_simple_unop (mode
, NOT
, result
, target
, true);
8017 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
8018 true, OPTAB_LIB_WIDEN
);
8023 /* No direct opcode can be generated. */
8029 /* This function expands an atomic fetch_OP or OP_fetch operation:
8030 TARGET is an option place to stick the return value. const0_rtx indicates
8031 the result is unused.
8032 atomically fetch MEM, perform the operation with VAL and return it to MEM.
8033 CODE is the operation being performed (OP)
8034 MEMMODEL is the memory model variant to use.
8035 AFTER is true to return the result of the operation (OP_fetch).
8036 AFTER is false to return the value before the operation (fetch_OP). */
8038 expand_atomic_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
8039 enum memmodel model
, bool after
)
8041 enum machine_mode mode
= GET_MODE (mem
);
8043 bool unused_result
= (target
== const0_rtx
);
8045 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, val
, code
, model
,
8051 /* Add/sub can be implemented by doing the reverse operation with -(val). */
8052 if (code
== PLUS
|| code
== MINUS
)
8055 enum rtx_code reverse
= (code
== PLUS
? MINUS
: PLUS
);
8058 tmp
= expand_simple_unop (mode
, NEG
, val
, NULL_RTX
, true);
8059 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, tmp
, reverse
,
8063 /* PLUS worked so emit the insns and return. */
8070 /* PLUS did not work, so throw away the negation code and continue. */
8074 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
8075 if (!can_compare_and_swap_p (mode
, false))
8079 enum rtx_code orig_code
= code
;
8080 struct atomic_op_functions optab
;
8082 get_atomic_op_for_code (&optab
, code
);
8083 libfunc
= optab_libfunc (after
? optab
.fetch_after
8084 : optab
.fetch_before
, mode
);
8086 && (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
))
8090 code
= optab
.reverse_code
;
8091 libfunc
= optab_libfunc (after
? optab
.fetch_before
8092 : optab
.fetch_after
, mode
);
8094 if (libfunc
!= NULL
)
8096 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
8097 result
= emit_library_call_value (libfunc
, NULL
, LCT_NORMAL
, mode
,
8098 2, addr
, ptr_mode
, val
, mode
);
8100 if (!unused_result
&& fixup
)
8101 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
8102 true, OPTAB_LIB_WIDEN
);
8106 /* We need the original code for any further attempts. */
8110 /* If nothing else has succeeded, default to a compare and swap loop. */
8111 if (can_compare_and_swap_p (mode
, true))
8114 rtx t0
= gen_reg_rtx (mode
), t1
;
8118 /* If the result is used, get a register for it. */
8121 if (!target
|| !register_operand (target
, mode
))
8122 target
= gen_reg_rtx (mode
);
8123 /* If fetch_before, copy the value now. */
8125 emit_move_insn (target
, t0
);
8128 target
= const0_rtx
;
8133 t1
= expand_simple_binop (mode
, AND
, t1
, val
, NULL_RTX
,
8134 true, OPTAB_LIB_WIDEN
);
8135 t1
= expand_simple_unop (mode
, code
, t1
, NULL_RTX
, true);
8138 t1
= expand_simple_binop (mode
, code
, t1
, val
, NULL_RTX
, true,
8141 /* For after, copy the value now. */
8142 if (!unused_result
&& after
)
8143 emit_move_insn (target
, t1
);
8144 insn
= get_insns ();
8147 if (t1
!= NULL
&& expand_compare_and_swap_loop (mem
, t0
, t1
, insn
))
8154 /* Return true if OPERAND is suitable for operand number OPNO of
8155 instruction ICODE. */
8158 insn_operand_matches (enum insn_code icode
, unsigned int opno
, rtx operand
)
8160 return (!insn_data
[(int) icode
].operand
[opno
].predicate
8161 || (insn_data
[(int) icode
].operand
[opno
].predicate
8162 (operand
, insn_data
[(int) icode
].operand
[opno
].mode
)));
8165 /* TARGET is a target of a multiword operation that we are going to
8166 implement as a series of word-mode operations. Return true if
8167 TARGET is suitable for this purpose. */
8170 valid_multiword_target_p (rtx target
)
8172 enum machine_mode mode
;
8175 mode
= GET_MODE (target
);
8176 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
+= UNITS_PER_WORD
)
8177 if (!validate_subreg (word_mode
, mode
, target
, i
))
8182 /* Like maybe_legitimize_operand, but do not change the code of the
8183 current rtx value. */
8186 maybe_legitimize_operand_same_code (enum insn_code icode
, unsigned int opno
,
8187 struct expand_operand
*op
)
8189 /* See if the operand matches in its current form. */
8190 if (insn_operand_matches (icode
, opno
, op
->value
))
8193 /* If the operand is a memory whose address has no side effects,
8194 try forcing the address into a non-virtual pseudo register.
8195 The check for side effects is important because copy_to_mode_reg
8196 cannot handle things like auto-modified addresses. */
8197 if (insn_data
[(int) icode
].operand
[opno
].allows_mem
&& MEM_P (op
->value
))
8202 addr
= XEXP (mem
, 0);
8203 if (!(REG_P (addr
) && REGNO (addr
) > LAST_VIRTUAL_REGISTER
)
8204 && !side_effects_p (addr
))
8207 enum machine_mode mode
;
8209 last
= get_last_insn ();
8210 mode
= get_address_mode (mem
);
8211 mem
= replace_equiv_address (mem
, copy_to_mode_reg (mode
, addr
));
8212 if (insn_operand_matches (icode
, opno
, mem
))
8217 delete_insns_since (last
);
8224 /* Try to make OP match operand OPNO of instruction ICODE. Return true
8225 on success, storing the new operand value back in OP. */
8228 maybe_legitimize_operand (enum insn_code icode
, unsigned int opno
,
8229 struct expand_operand
*op
)
8231 enum machine_mode mode
, imode
;
8232 bool old_volatile_ok
, result
;
8238 old_volatile_ok
= volatile_ok
;
8240 result
= maybe_legitimize_operand_same_code (icode
, opno
, op
);
8241 volatile_ok
= old_volatile_ok
;
8245 gcc_assert (mode
!= VOIDmode
);
8247 && op
->value
!= const0_rtx
8248 && GET_MODE (op
->value
) == mode
8249 && maybe_legitimize_operand_same_code (icode
, opno
, op
))
8252 op
->value
= gen_reg_rtx (mode
);
8257 gcc_assert (mode
!= VOIDmode
);
8258 gcc_assert (GET_MODE (op
->value
) == VOIDmode
8259 || GET_MODE (op
->value
) == mode
);
8260 if (maybe_legitimize_operand_same_code (icode
, opno
, op
))
8263 op
->value
= copy_to_mode_reg (mode
, op
->value
);
8266 case EXPAND_CONVERT_TO
:
8267 gcc_assert (mode
!= VOIDmode
);
8268 op
->value
= convert_to_mode (mode
, op
->value
, op
->unsigned_p
);
8271 case EXPAND_CONVERT_FROM
:
8272 if (GET_MODE (op
->value
) != VOIDmode
)
8273 mode
= GET_MODE (op
->value
);
8275 /* The caller must tell us what mode this value has. */
8276 gcc_assert (mode
!= VOIDmode
);
8278 imode
= insn_data
[(int) icode
].operand
[opno
].mode
;
8279 if (imode
!= VOIDmode
&& imode
!= mode
)
8281 op
->value
= convert_modes (imode
, mode
, op
->value
, op
->unsigned_p
);
8286 case EXPAND_ADDRESS
:
8287 gcc_assert (mode
!= VOIDmode
);
8288 op
->value
= convert_memory_address (mode
, op
->value
);
8291 case EXPAND_INTEGER
:
8292 mode
= insn_data
[(int) icode
].operand
[opno
].mode
;
8293 if (mode
!= VOIDmode
&& const_int_operand (op
->value
, mode
))
8297 return insn_operand_matches (icode
, opno
, op
->value
);
8300 /* Make OP describe an input operand that should have the same value
8301 as VALUE, after any mode conversion that the target might request.
8302 TYPE is the type of VALUE. */
8305 create_convert_operand_from_type (struct expand_operand
*op
,
8306 rtx value
, tree type
)
8308 create_convert_operand_from (op
, value
, TYPE_MODE (type
),
8309 TYPE_UNSIGNED (type
));
8312 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
8313 of instruction ICODE. Return true on success, leaving the new operand
8314 values in the OPS themselves. Emit no code on failure. */
8317 maybe_legitimize_operands (enum insn_code icode
, unsigned int opno
,
8318 unsigned int nops
, struct expand_operand
*ops
)
8323 last
= get_last_insn ();
8324 for (i
= 0; i
< nops
; i
++)
8325 if (!maybe_legitimize_operand (icode
, opno
+ i
, &ops
[i
]))
8327 delete_insns_since (last
);
8333 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
8334 as its operands. Return the instruction pattern on success,
8335 and emit any necessary set-up code. Return null and emit no
8339 maybe_gen_insn (enum insn_code icode
, unsigned int nops
,
8340 struct expand_operand
*ops
)
8342 gcc_assert (nops
== (unsigned int) insn_data
[(int) icode
].n_generator_args
);
8343 if (!maybe_legitimize_operands (icode
, 0, nops
, ops
))
8349 return GEN_FCN (icode
) (ops
[0].value
);
8351 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
);
8353 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
);
8355 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8358 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8359 ops
[3].value
, ops
[4].value
);
8361 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8362 ops
[3].value
, ops
[4].value
, ops
[5].value
);
8364 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8365 ops
[3].value
, ops
[4].value
, ops
[5].value
,
8368 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8369 ops
[3].value
, ops
[4].value
, ops
[5].value
,
8370 ops
[6].value
, ops
[7].value
);
8372 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8373 ops
[3].value
, ops
[4].value
, ops
[5].value
,
8374 ops
[6].value
, ops
[7].value
, ops
[8].value
);
8379 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
8380 as its operands. Return true on success and emit no code on failure. */
8383 maybe_expand_insn (enum insn_code icode
, unsigned int nops
,
8384 struct expand_operand
*ops
)
8386 rtx pat
= maybe_gen_insn (icode
, nops
, ops
);
8395 /* Like maybe_expand_insn, but for jumps. */
8398 maybe_expand_jump_insn (enum insn_code icode
, unsigned int nops
,
8399 struct expand_operand
*ops
)
8401 rtx pat
= maybe_gen_insn (icode
, nops
, ops
);
8404 emit_jump_insn (pat
);
8410 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
8414 expand_insn (enum insn_code icode
, unsigned int nops
,
8415 struct expand_operand
*ops
)
8417 if (!maybe_expand_insn (icode
, nops
, ops
))
8421 /* Like expand_insn, but for jumps. */
8424 expand_jump_insn (enum insn_code icode
, unsigned int nops
,
8425 struct expand_operand
*ops
)
8427 if (!maybe_expand_jump_insn (icode
, nops
, ops
))
8431 /* Reduce conditional compilation elsewhere. */
8434 #define CODE_FOR_insv CODE_FOR_nothing
8438 #define CODE_FOR_extv CODE_FOR_nothing
8441 #define HAVE_extzv 0
8442 #define CODE_FOR_extzv CODE_FOR_nothing
8445 /* Enumerates the possible types of structure operand to an
8447 enum extraction_type
{ ET_unaligned_mem
, ET_reg
};
8449 /* Check whether insv, extv or extzv pattern ICODE can be used for an
8450 insertion or extraction of type TYPE on a structure of mode MODE.
8451 Return true if so and fill in *INSN accordingly. STRUCT_OP is the
8452 operand number of the structure (the first sign_extract or zero_extract
8453 operand) and FIELD_OP is the operand number of the field (the other
8454 side of the set from the sign_extract or zero_extract). */
8457 get_traditional_extraction_insn (extraction_insn
*insn
,
8458 enum extraction_type type
,
8459 enum machine_mode mode
,
8460 enum insn_code icode
,
8461 int struct_op
, int field_op
)
8463 const struct insn_data_d
*data
= &insn_data
[icode
];
8465 enum machine_mode struct_mode
= data
->operand
[struct_op
].mode
;
8466 if (struct_mode
== VOIDmode
)
8467 struct_mode
= word_mode
;
8468 if (mode
!= struct_mode
)
8471 enum machine_mode field_mode
= data
->operand
[field_op
].mode
;
8472 if (field_mode
== VOIDmode
)
8473 field_mode
= word_mode
;
8475 enum machine_mode pos_mode
= data
->operand
[struct_op
+ 2].mode
;
8476 if (pos_mode
== VOIDmode
)
8477 pos_mode
= word_mode
;
8479 insn
->icode
= icode
;
8480 insn
->field_mode
= field_mode
;
8481 insn
->struct_mode
= (type
== ET_unaligned_mem
? byte_mode
: struct_mode
);
8482 insn
->pos_mode
= pos_mode
;
8486 /* Return true if an optab exists to perform an insertion or extraction
8487 of type TYPE in mode MODE. Describe the instruction in *INSN if so.
8489 REG_OPTAB is the optab to use for register structures and
8490 MISALIGN_OPTAB is the optab to use for misaligned memory structures.
8491 POS_OP is the operand number of the bit position. */
8494 get_optab_extraction_insn (struct extraction_insn
*insn
,
8495 enum extraction_type type
,
8496 enum machine_mode mode
, direct_optab reg_optab
,
8497 direct_optab misalign_optab
, int pos_op
)
8499 direct_optab optab
= (type
== ET_unaligned_mem
? misalign_optab
: reg_optab
);
8500 enum insn_code icode
= direct_optab_handler (optab
, mode
);
8501 if (icode
== CODE_FOR_nothing
)
8504 const struct insn_data_d
*data
= &insn_data
[icode
];
8506 insn
->icode
= icode
;
8507 insn
->field_mode
= mode
;
8508 insn
->struct_mode
= (type
== ET_unaligned_mem
? BLKmode
: mode
);
8509 insn
->pos_mode
= data
->operand
[pos_op
].mode
;
8510 if (insn
->pos_mode
== VOIDmode
)
8511 insn
->pos_mode
= word_mode
;
8515 /* Return true if an instruction exists to perform an insertion or
8516 extraction (PATTERN says which) of type TYPE in mode MODE.
8517 Describe the instruction in *INSN if so. */
8520 get_extraction_insn (extraction_insn
*insn
,
8521 enum extraction_pattern pattern
,
8522 enum extraction_type type
,
8523 enum machine_mode mode
)
8529 && get_traditional_extraction_insn (insn
, type
, mode
,
8530 CODE_FOR_insv
, 0, 3))
8532 return get_optab_extraction_insn (insn
, type
, mode
, insv_optab
,
8533 insvmisalign_optab
, 2);
8537 && get_traditional_extraction_insn (insn
, type
, mode
,
8538 CODE_FOR_extv
, 1, 0))
8540 return get_optab_extraction_insn (insn
, type
, mode
, extv_optab
,
8541 extvmisalign_optab
, 3);
8545 && get_traditional_extraction_insn (insn
, type
, mode
,
8546 CODE_FOR_extzv
, 1, 0))
8548 return get_optab_extraction_insn (insn
, type
, mode
, extzv_optab
,
8549 extzvmisalign_optab
, 3);
8556 /* Return true if an instruction exists to access a field of mode
8557 FIELDMODE in a structure that has STRUCT_BITS significant bits.
8558 Describe the "best" such instruction in *INSN if so. PATTERN and
8559 TYPE describe the type of insertion or extraction we want to perform.
8561 For an insertion, the number of significant structure bits includes
8562 all bits of the target. For an extraction, it need only include the
8563 most significant bit of the field. Larger widths are acceptable
8567 get_best_extraction_insn (extraction_insn
*insn
,
8568 enum extraction_pattern pattern
,
8569 enum extraction_type type
,
8570 unsigned HOST_WIDE_INT struct_bits
,
8571 enum machine_mode field_mode
)
8573 enum machine_mode mode
= smallest_mode_for_size (struct_bits
, MODE_INT
);
8574 while (mode
!= VOIDmode
)
8576 if (get_extraction_insn (insn
, pattern
, type
, mode
))
8578 while (mode
!= VOIDmode
8579 && GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (field_mode
)
8580 && !TRULY_NOOP_TRUNCATION_MODES_P (insn
->field_mode
,
8583 get_extraction_insn (insn
, pattern
, type
, mode
);
8584 mode
= GET_MODE_WIDER_MODE (mode
);
8588 mode
= GET_MODE_WIDER_MODE (mode
);
8593 /* Return true if an instruction exists to access a field of mode
8594 FIELDMODE in a register structure that has STRUCT_BITS significant bits.
8595 Describe the "best" such instruction in *INSN if so. PATTERN describes
8596 the type of insertion or extraction we want to perform.
8598 For an insertion, the number of significant structure bits includes
8599 all bits of the target. For an extraction, it need only include the
8600 most significant bit of the field. Larger widths are acceptable
8604 get_best_reg_extraction_insn (extraction_insn
*insn
,
8605 enum extraction_pattern pattern
,
8606 unsigned HOST_WIDE_INT struct_bits
,
8607 enum machine_mode field_mode
)
8609 return get_best_extraction_insn (insn
, pattern
, ET_reg
, struct_bits
,
8613 /* Return true if an instruction exists to access a field of BITSIZE
8614 bits starting BITNUM bits into a memory structure. Describe the
8615 "best" such instruction in *INSN if so. PATTERN describes the type
8616 of insertion or extraction we want to perform and FIELDMODE is the
8617 natural mode of the extracted field.
8619 The instructions considered here only access bytes that overlap
8620 the bitfield; they do not touch any surrounding bytes. */
8623 get_best_mem_extraction_insn (extraction_insn
*insn
,
8624 enum extraction_pattern pattern
,
8625 HOST_WIDE_INT bitsize
, HOST_WIDE_INT bitnum
,
8626 enum machine_mode field_mode
)
8628 unsigned HOST_WIDE_INT struct_bits
= (bitnum
% BITS_PER_UNIT
8630 + BITS_PER_UNIT
- 1);
8631 struct_bits
-= struct_bits
% BITS_PER_UNIT
;
8632 return get_best_extraction_insn (insn
, pattern
, ET_unaligned_mem
,
8633 struct_bits
, field_mode
);
8636 /* Determine whether "1 << x" is relatively cheap in word_mode. */
8639 lshift_cheap_p (bool speed_p
)
8641 /* FIXME: This should be made target dependent via this "this_target"
8642 mechanism, similar to e.g. can_copy_init_p in gcse.c. */
8643 static bool init
[2] = { false, false };
8644 static bool cheap
[2] = { true, true };
8646 /* If the targer has no lshift in word_mode, the operation will most
8647 probably not be cheap. ??? Does GCC even work for such targets? */
8648 if (optab_handler (ashl_optab
, word_mode
) == CODE_FOR_nothing
)
8653 rtx reg
= gen_raw_REG (word_mode
, 10000);
8654 int cost
= set_src_cost (gen_rtx_ASHIFT (word_mode
, const1_rtx
, reg
),
8656 cheap
[speed_p
] = cost
< COSTS_N_INSNS (3);
8657 init
[speed_p
] = true;
8660 return cheap
[speed_p
];
8663 #include "gt-optabs.h"