1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2015 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"
34 #include "double-int.h"
41 #include "tree-hasher.h"
42 #include "stor-layout.h"
43 #include "stringpool.h"
47 #include "hard-reg-set.h"
52 #include "insn-codes.h"
59 #include "dominance.h"
61 #include "basic-block.h"
64 struct target_optabs default_target_optabs
;
65 struct target_libfuncs default_target_libfuncs
;
66 struct target_optabs
*this_fn_optabs
= &default_target_optabs
;
68 struct target_optabs
*this_target_optabs
= &default_target_optabs
;
69 struct target_libfuncs
*this_target_libfuncs
= &default_target_libfuncs
;
72 #define libfunc_hash \
73 (this_target_libfuncs->x_libfunc_hash)
75 static void prepare_float_lib_cmp (rtx
, rtx
, enum rtx_code
, rtx
*,
77 static rtx
expand_unop_direct (machine_mode
, optab
, rtx
, rtx
, int);
78 static void emit_libcall_block_1 (rtx_insn
*, rtx
, rtx
, rtx
, bool);
80 /* Debug facility for use in GDB. */
81 void debug_optab_libfuncs (void);
83 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
84 #if ENABLE_DECIMAL_BID_FORMAT
85 #define DECIMAL_PREFIX "bid_"
87 #define DECIMAL_PREFIX "dpd_"
90 /* Used for libfunc_hash. */
93 libfunc_hasher::hash (libfunc_entry
*e
)
95 return ((e
->mode1
+ e
->mode2
* NUM_MACHINE_MODES
) ^ e
->op
);
98 /* Used for libfunc_hash. */
101 libfunc_hasher::equal (libfunc_entry
*e1
, libfunc_entry
*e2
)
103 return e1
->op
== e2
->op
&& e1
->mode1
== e2
->mode1
&& e1
->mode2
== e2
->mode2
;
106 /* Return libfunc corresponding operation defined by OPTAB converting
107 from MODE2 to MODE1. Trigger lazy initialization if needed, return NULL
108 if no libfunc is available. */
110 convert_optab_libfunc (convert_optab optab
, machine_mode mode1
,
113 struct libfunc_entry e
;
114 struct libfunc_entry
**slot
;
116 /* ??? This ought to be an assert, but not all of the places
117 that we expand optabs know about the optabs that got moved
119 if (!(optab
>= FIRST_CONV_OPTAB
&& optab
<= LAST_CONVLIB_OPTAB
))
125 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
128 const struct convert_optab_libcall_d
*d
129 = &convlib_def
[optab
- FIRST_CONV_OPTAB
];
131 if (d
->libcall_gen
== NULL
)
134 d
->libcall_gen (optab
, d
->libcall_basename
, mode1
, mode2
);
135 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
139 return (*slot
)->libfunc
;
142 /* Return libfunc corresponding operation defined by OPTAB in MODE.
143 Trigger lazy initialization if needed, return NULL if no libfunc is
146 optab_libfunc (optab optab
, machine_mode mode
)
148 struct libfunc_entry e
;
149 struct libfunc_entry
**slot
;
151 /* ??? This ought to be an assert, but not all of the places
152 that we expand optabs know about the optabs that got moved
154 if (!(optab
>= FIRST_NORM_OPTAB
&& optab
<= LAST_NORMLIB_OPTAB
))
160 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
163 const struct optab_libcall_d
*d
164 = &normlib_def
[optab
- FIRST_NORM_OPTAB
];
166 if (d
->libcall_gen
== NULL
)
169 d
->libcall_gen (optab
, d
->libcall_basename
, d
->libcall_suffix
, mode
);
170 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
174 return (*slot
)->libfunc
;
178 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
179 the result of operation CODE applied to OP0 (and OP1 if it is a binary
182 If the last insn does not set TARGET, don't do anything, but return 1.
184 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
185 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
186 try again, ensuring that TARGET is not one of the operands. */
189 add_equal_note (rtx_insn
*insns
, rtx target
, enum rtx_code code
, rtx op0
, rtx op1
)
195 gcc_assert (insns
&& INSN_P (insns
) && NEXT_INSN (insns
));
197 if (GET_RTX_CLASS (code
) != RTX_COMM_ARITH
198 && GET_RTX_CLASS (code
) != RTX_BIN_ARITH
199 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
200 && GET_RTX_CLASS (code
) != RTX_COMPARE
201 && GET_RTX_CLASS (code
) != RTX_UNARY
)
204 if (GET_CODE (target
) == ZERO_EXTRACT
)
207 for (last_insn
= insns
;
208 NEXT_INSN (last_insn
) != NULL_RTX
;
209 last_insn
= NEXT_INSN (last_insn
))
212 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
213 a value changing in the insn, so the note would be invalid for CSE. */
214 if (reg_overlap_mentioned_p (target
, op0
)
215 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
218 && (rtx_equal_p (target
, op0
)
219 || (op1
&& rtx_equal_p (target
, op1
))))
221 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
222 over expanding it as temp = MEM op X, MEM = temp. If the target
223 supports MEM = MEM op X instructions, it is sometimes too hard
224 to reconstruct that form later, especially if X is also a memory,
225 and due to multiple occurrences of addresses the address might
226 be forced into register unnecessarily.
227 Note that not emitting the REG_EQUIV note might inhibit
228 CSE in some cases. */
229 set
= single_set (last_insn
);
231 && GET_CODE (SET_SRC (set
)) == code
232 && MEM_P (SET_DEST (set
))
233 && (rtx_equal_p (SET_DEST (set
), XEXP (SET_SRC (set
), 0))
234 || (op1
&& rtx_equal_p (SET_DEST (set
),
235 XEXP (SET_SRC (set
), 1)))))
241 set
= set_for_reg_notes (last_insn
);
245 if (! rtx_equal_p (SET_DEST (set
), target
)
246 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
247 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
248 || ! rtx_equal_p (XEXP (SET_DEST (set
), 0), target
)))
251 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
261 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (target
) != GET_MODE (op0
))
263 note
= gen_rtx_fmt_e (code
, GET_MODE (op0
), copy_rtx (op0
));
264 if (GET_MODE_SIZE (GET_MODE (op0
))
265 > GET_MODE_SIZE (GET_MODE (target
)))
266 note
= simplify_gen_unary (TRUNCATE
, GET_MODE (target
),
267 note
, GET_MODE (op0
));
269 note
= simplify_gen_unary (ZERO_EXTEND
, GET_MODE (target
),
270 note
, GET_MODE (op0
));
275 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
279 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
281 set_unique_reg_note (last_insn
, REG_EQUAL
, note
);
286 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
287 for a widening operation would be. In most cases this would be OP0, but if
288 that's a constant it'll be VOIDmode, which isn't useful. */
291 widened_mode (machine_mode to_mode
, rtx op0
, rtx op1
)
293 machine_mode m0
= GET_MODE (op0
);
294 machine_mode m1
= GET_MODE (op1
);
297 if (m0
== VOIDmode
&& m1
== VOIDmode
)
299 else if (m0
== VOIDmode
|| GET_MODE_SIZE (m0
) < GET_MODE_SIZE (m1
))
304 if (GET_MODE_SIZE (result
) > GET_MODE_SIZE (to_mode
))
310 /* Like optab_handler, but for widening_operations that have a
311 TO_MODE and a FROM_MODE. */
314 widening_optab_handler (optab op
, machine_mode to_mode
,
315 machine_mode from_mode
)
317 unsigned scode
= (op
<< 16) | to_mode
;
318 if (to_mode
!= from_mode
&& from_mode
!= VOIDmode
)
320 /* ??? Why does find_widening_optab_handler_and_mode attempt to
321 widen things that can't be widened? E.g. add_optab... */
322 if (op
> LAST_CONV_OPTAB
)
323 return CODE_FOR_nothing
;
324 scode
|= from_mode
<< 8;
326 return raw_optab_handler (scode
);
329 /* Find a widening optab even if it doesn't widen as much as we want.
330 E.g. if from_mode is HImode, and to_mode is DImode, and there is no
331 direct HI->SI insn, then return SI->DI, if that exists.
332 If PERMIT_NON_WIDENING is non-zero then this can be used with
333 non-widening optabs also. */
336 find_widening_optab_handler_and_mode (optab op
, machine_mode to_mode
,
337 machine_mode from_mode
,
338 int permit_non_widening
,
339 machine_mode
*found_mode
)
341 for (; (permit_non_widening
|| from_mode
!= to_mode
)
342 && GET_MODE_SIZE (from_mode
) <= GET_MODE_SIZE (to_mode
)
343 && from_mode
!= VOIDmode
;
344 from_mode
= GET_MODE_WIDER_MODE (from_mode
))
346 enum insn_code handler
= widening_optab_handler (op
, to_mode
,
349 if (handler
!= CODE_FOR_nothing
)
352 *found_mode
= from_mode
;
357 return CODE_FOR_nothing
;
360 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
361 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
362 not actually do a sign-extend or zero-extend, but can leave the
363 higher-order bits of the result rtx undefined, for example, in the case
364 of logical operations, but not right shifts. */
367 widen_operand (rtx op
, machine_mode mode
, machine_mode oldmode
,
368 int unsignedp
, int no_extend
)
372 /* If we don't have to extend and this is a constant, return it. */
373 if (no_extend
&& GET_MODE (op
) == VOIDmode
)
376 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
377 extend since it will be more efficient to do so unless the signedness of
378 a promoted object differs from our extension. */
380 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)
381 && SUBREG_CHECK_PROMOTED_SIGN (op
, unsignedp
)))
382 return convert_modes (mode
, oldmode
, op
, unsignedp
);
384 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
386 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
387 return gen_lowpart (mode
, force_reg (GET_MODE (op
), op
));
389 /* Otherwise, get an object of MODE, clobber it, and set the low-order
392 result
= gen_reg_rtx (mode
);
393 emit_clobber (result
);
394 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
398 /* Return the optab used for computing the operation given by the tree code,
399 CODE and the tree EXP. This function is not always usable (for example, it
400 cannot give complete results for multiplication or division) but probably
401 ought to be relied on more widely throughout the expander. */
403 optab_for_tree_code (enum tree_code code
, const_tree type
,
404 enum optab_subtype subtype
)
416 return one_cmpl_optab
;
421 case MULT_HIGHPART_EXPR
:
422 return TYPE_UNSIGNED (type
) ? umul_highpart_optab
: smul_highpart_optab
;
428 return TYPE_UNSIGNED (type
) ? umod_optab
: smod_optab
;
436 if (TYPE_SATURATING (type
))
437 return TYPE_UNSIGNED (type
) ? usdiv_optab
: ssdiv_optab
;
438 return TYPE_UNSIGNED (type
) ? udiv_optab
: sdiv_optab
;
441 if (TREE_CODE (type
) == VECTOR_TYPE
)
443 if (subtype
== optab_vector
)
444 return TYPE_SATURATING (type
) ? unknown_optab
: vashl_optab
;
446 gcc_assert (subtype
== optab_scalar
);
448 if (TYPE_SATURATING (type
))
449 return TYPE_UNSIGNED (type
) ? usashl_optab
: ssashl_optab
;
453 if (TREE_CODE (type
) == VECTOR_TYPE
)
455 if (subtype
== optab_vector
)
456 return TYPE_UNSIGNED (type
) ? vlshr_optab
: vashr_optab
;
458 gcc_assert (subtype
== optab_scalar
);
460 return TYPE_UNSIGNED (type
) ? lshr_optab
: ashr_optab
;
463 if (TREE_CODE (type
) == VECTOR_TYPE
)
465 if (subtype
== optab_vector
)
468 gcc_assert (subtype
== optab_scalar
);
473 if (TREE_CODE (type
) == VECTOR_TYPE
)
475 if (subtype
== optab_vector
)
478 gcc_assert (subtype
== optab_scalar
);
483 return TYPE_UNSIGNED (type
) ? umax_optab
: smax_optab
;
486 return TYPE_UNSIGNED (type
) ? umin_optab
: smin_optab
;
488 case REALIGN_LOAD_EXPR
:
489 return vec_realign_load_optab
;
492 return TYPE_UNSIGNED (type
) ? usum_widen_optab
: ssum_widen_optab
;
495 return TYPE_UNSIGNED (type
) ? udot_prod_optab
: sdot_prod_optab
;
498 return TYPE_UNSIGNED (type
) ? usad_optab
: ssad_optab
;
500 case WIDEN_MULT_PLUS_EXPR
:
501 return (TYPE_UNSIGNED (type
)
502 ? (TYPE_SATURATING (type
)
503 ? usmadd_widen_optab
: umadd_widen_optab
)
504 : (TYPE_SATURATING (type
)
505 ? ssmadd_widen_optab
: smadd_widen_optab
));
507 case WIDEN_MULT_MINUS_EXPR
:
508 return (TYPE_UNSIGNED (type
)
509 ? (TYPE_SATURATING (type
)
510 ? usmsub_widen_optab
: umsub_widen_optab
)
511 : (TYPE_SATURATING (type
)
512 ? ssmsub_widen_optab
: smsub_widen_optab
));
518 return TYPE_UNSIGNED (type
)
519 ? reduc_umax_scal_optab
: reduc_smax_scal_optab
;
522 return TYPE_UNSIGNED (type
)
523 ? reduc_umin_scal_optab
: reduc_smin_scal_optab
;
525 case REDUC_PLUS_EXPR
:
526 return reduc_plus_scal_optab
;
528 case VEC_WIDEN_MULT_HI_EXPR
:
529 return TYPE_UNSIGNED (type
) ?
530 vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
532 case VEC_WIDEN_MULT_LO_EXPR
:
533 return TYPE_UNSIGNED (type
) ?
534 vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
536 case VEC_WIDEN_MULT_EVEN_EXPR
:
537 return TYPE_UNSIGNED (type
) ?
538 vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
540 case VEC_WIDEN_MULT_ODD_EXPR
:
541 return TYPE_UNSIGNED (type
) ?
542 vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
544 case VEC_WIDEN_LSHIFT_HI_EXPR
:
545 return TYPE_UNSIGNED (type
) ?
546 vec_widen_ushiftl_hi_optab
: vec_widen_sshiftl_hi_optab
;
548 case VEC_WIDEN_LSHIFT_LO_EXPR
:
549 return TYPE_UNSIGNED (type
) ?
550 vec_widen_ushiftl_lo_optab
: vec_widen_sshiftl_lo_optab
;
552 case VEC_UNPACK_HI_EXPR
:
553 return TYPE_UNSIGNED (type
) ?
554 vec_unpacku_hi_optab
: vec_unpacks_hi_optab
;
556 case VEC_UNPACK_LO_EXPR
:
557 return TYPE_UNSIGNED (type
) ?
558 vec_unpacku_lo_optab
: vec_unpacks_lo_optab
;
560 case VEC_UNPACK_FLOAT_HI_EXPR
:
561 /* The signedness is determined from input operand. */
562 return TYPE_UNSIGNED (type
) ?
563 vec_unpacku_float_hi_optab
: vec_unpacks_float_hi_optab
;
565 case VEC_UNPACK_FLOAT_LO_EXPR
:
566 /* The signedness is determined from input operand. */
567 return TYPE_UNSIGNED (type
) ?
568 vec_unpacku_float_lo_optab
: vec_unpacks_float_lo_optab
;
570 case VEC_PACK_TRUNC_EXPR
:
571 return vec_pack_trunc_optab
;
573 case VEC_PACK_SAT_EXPR
:
574 return TYPE_UNSIGNED (type
) ? vec_pack_usat_optab
: vec_pack_ssat_optab
;
576 case VEC_PACK_FIX_TRUNC_EXPR
:
577 /* The signedness is determined from output operand. */
578 return TYPE_UNSIGNED (type
) ?
579 vec_pack_ufix_trunc_optab
: vec_pack_sfix_trunc_optab
;
585 trapv
= INTEGRAL_TYPE_P (type
) && TYPE_OVERFLOW_TRAPS (type
);
588 case POINTER_PLUS_EXPR
:
590 if (TYPE_SATURATING (type
))
591 return TYPE_UNSIGNED (type
) ? usadd_optab
: ssadd_optab
;
592 return trapv
? addv_optab
: add_optab
;
595 if (TYPE_SATURATING (type
))
596 return TYPE_UNSIGNED (type
) ? ussub_optab
: sssub_optab
;
597 return trapv
? subv_optab
: sub_optab
;
600 if (TYPE_SATURATING (type
))
601 return TYPE_UNSIGNED (type
) ? usmul_optab
: ssmul_optab
;
602 return trapv
? smulv_optab
: smul_optab
;
605 if (TYPE_SATURATING (type
))
606 return TYPE_UNSIGNED (type
) ? usneg_optab
: ssneg_optab
;
607 return trapv
? negv_optab
: neg_optab
;
610 return trapv
? absv_optab
: abs_optab
;
613 return unknown_optab
;
617 /* Given optab UNOPTAB that reduces a vector to a scalar, find instead the old
618 optab that produces a vector with the reduction result in one element,
619 for a tree with type TYPE. */
622 scalar_reduc_to_vector (optab unoptab
, const_tree type
)
626 case reduc_plus_scal_optab
:
627 return TYPE_UNSIGNED (type
) ? reduc_uplus_optab
: reduc_splus_optab
;
629 case reduc_smin_scal_optab
: return reduc_smin_optab
;
630 case reduc_umin_scal_optab
: return reduc_umin_optab
;
631 case reduc_smax_scal_optab
: return reduc_smax_optab
;
632 case reduc_umax_scal_optab
: return reduc_umax_optab
;
633 default: return unknown_optab
;
637 /* Expand vector widening operations.
639 There are two different classes of operations handled here:
640 1) Operations whose result is wider than all the arguments to the operation.
641 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
642 In this case OP0 and optionally OP1 would be initialized,
643 but WIDE_OP wouldn't (not relevant for this case).
644 2) Operations whose result is of the same size as the last argument to the
645 operation, but wider than all the other arguments to the operation.
646 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
647 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
649 E.g, when called to expand the following operations, this is how
650 the arguments will be initialized:
652 widening-sum 2 oprnd0 - oprnd1
653 widening-dot-product 3 oprnd0 oprnd1 oprnd2
654 widening-mult 2 oprnd0 oprnd1 -
655 type-promotion (vec-unpack) 1 oprnd0 - - */
658 expand_widen_pattern_expr (sepops ops
, rtx op0
, rtx op1
, rtx wide_op
,
659 rtx target
, int unsignedp
)
661 struct expand_operand eops
[4];
662 tree oprnd0
, oprnd1
, oprnd2
;
663 machine_mode wmode
= VOIDmode
, tmode0
, tmode1
= VOIDmode
;
664 optab widen_pattern_optab
;
665 enum insn_code icode
;
666 int nops
= TREE_CODE_LENGTH (ops
->code
);
670 tmode0
= TYPE_MODE (TREE_TYPE (oprnd0
));
671 widen_pattern_optab
=
672 optab_for_tree_code (ops
->code
, TREE_TYPE (oprnd0
), optab_default
);
673 if (ops
->code
== WIDEN_MULT_PLUS_EXPR
674 || ops
->code
== WIDEN_MULT_MINUS_EXPR
)
675 icode
= find_widening_optab_handler (widen_pattern_optab
,
676 TYPE_MODE (TREE_TYPE (ops
->op2
)),
679 icode
= optab_handler (widen_pattern_optab
, tmode0
);
680 gcc_assert (icode
!= CODE_FOR_nothing
);
685 tmode1
= TYPE_MODE (TREE_TYPE (oprnd1
));
688 /* The last operand is of a wider mode than the rest of the operands. */
693 gcc_assert (tmode1
== tmode0
);
696 wmode
= TYPE_MODE (TREE_TYPE (oprnd2
));
700 create_output_operand (&eops
[op
++], target
, TYPE_MODE (ops
->type
));
701 create_convert_operand_from (&eops
[op
++], op0
, tmode0
, unsignedp
);
703 create_convert_operand_from (&eops
[op
++], op1
, tmode1
, unsignedp
);
705 create_convert_operand_from (&eops
[op
++], wide_op
, wmode
, unsignedp
);
706 expand_insn (icode
, op
, eops
);
707 return eops
[0].value
;
710 /* Generate code to perform an operation specified by TERNARY_OPTAB
711 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
713 UNSIGNEDP is for the case where we have to widen the operands
714 to perform the operation. It says to use zero-extension.
716 If TARGET is nonzero, the value
717 is generated there, if it is convenient to do so.
718 In all cases an rtx is returned for the locus of the value;
719 this may or may not be TARGET. */
722 expand_ternary_op (machine_mode mode
, optab ternary_optab
, rtx op0
,
723 rtx op1
, rtx op2
, rtx target
, int unsignedp
)
725 struct expand_operand ops
[4];
726 enum insn_code icode
= optab_handler (ternary_optab
, mode
);
728 gcc_assert (optab_handler (ternary_optab
, mode
) != CODE_FOR_nothing
);
730 create_output_operand (&ops
[0], target
, mode
);
731 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
732 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
733 create_convert_operand_from (&ops
[3], op2
, mode
, unsignedp
);
734 expand_insn (icode
, 4, ops
);
739 /* Like expand_binop, but return a constant rtx if the result can be
740 calculated at compile time. The arguments and return value are
741 otherwise the same as for expand_binop. */
744 simplify_expand_binop (machine_mode mode
, optab binoptab
,
745 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
746 enum optab_methods methods
)
748 if (CONSTANT_P (op0
) && CONSTANT_P (op1
))
750 rtx x
= simplify_binary_operation (optab_to_code (binoptab
),
756 return expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
);
759 /* Like simplify_expand_binop, but always put the result in TARGET.
760 Return true if the expansion succeeded. */
763 force_expand_binop (machine_mode mode
, optab binoptab
,
764 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
765 enum optab_methods methods
)
767 rtx x
= simplify_expand_binop (mode
, binoptab
, op0
, op1
,
768 target
, unsignedp
, methods
);
772 emit_move_insn (target
, x
);
776 /* Create a new vector value in VMODE with all elements set to OP. The
777 mode of OP must be the element mode of VMODE. If OP is a constant,
778 then the return value will be a constant. */
781 expand_vector_broadcast (machine_mode vmode
, rtx op
)
783 enum insn_code icode
;
788 gcc_checking_assert (VECTOR_MODE_P (vmode
));
790 n
= GET_MODE_NUNITS (vmode
);
791 vec
= rtvec_alloc (n
);
792 for (i
= 0; i
< n
; ++i
)
793 RTVEC_ELT (vec
, i
) = op
;
796 return gen_rtx_CONST_VECTOR (vmode
, vec
);
798 /* ??? If the target doesn't have a vec_init, then we have no easy way
799 of performing this operation. Most of this sort of generic support
800 is hidden away in the vector lowering support in gimple. */
801 icode
= optab_handler (vec_init_optab
, vmode
);
802 if (icode
== CODE_FOR_nothing
)
805 ret
= gen_reg_rtx (vmode
);
806 emit_insn (GEN_FCN (icode
) (ret
, gen_rtx_PARALLEL (vmode
, vec
)));
811 /* This subroutine of expand_doubleword_shift handles the cases in which
812 the effective shift value is >= BITS_PER_WORD. The arguments and return
813 value are the same as for the parent routine, except that SUPERWORD_OP1
814 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
815 INTO_TARGET may be null if the caller has decided to calculate it. */
818 expand_superword_shift (optab binoptab
, rtx outof_input
, rtx superword_op1
,
819 rtx outof_target
, rtx into_target
,
820 int unsignedp
, enum optab_methods methods
)
822 if (into_target
!= 0)
823 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, superword_op1
,
824 into_target
, unsignedp
, methods
))
827 if (outof_target
!= 0)
829 /* For a signed right shift, we must fill OUTOF_TARGET with copies
830 of the sign bit, otherwise we must fill it with zeros. */
831 if (binoptab
!= ashr_optab
)
832 emit_move_insn (outof_target
, CONST0_RTX (word_mode
));
834 if (!force_expand_binop (word_mode
, binoptab
,
835 outof_input
, GEN_INT (BITS_PER_WORD
- 1),
836 outof_target
, unsignedp
, methods
))
842 /* This subroutine of expand_doubleword_shift handles the cases in which
843 the effective shift value is < BITS_PER_WORD. The arguments and return
844 value are the same as for the parent routine. */
847 expand_subword_shift (machine_mode op1_mode
, optab binoptab
,
848 rtx outof_input
, rtx into_input
, rtx op1
,
849 rtx outof_target
, rtx into_target
,
850 int unsignedp
, enum optab_methods methods
,
851 unsigned HOST_WIDE_INT shift_mask
)
853 optab reverse_unsigned_shift
, unsigned_shift
;
856 reverse_unsigned_shift
= (binoptab
== ashl_optab
? lshr_optab
: ashl_optab
);
857 unsigned_shift
= (binoptab
== ashl_optab
? ashl_optab
: lshr_optab
);
859 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
860 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
861 the opposite direction to BINOPTAB. */
862 if (CONSTANT_P (op1
) || shift_mask
>= BITS_PER_WORD
)
864 carries
= outof_input
;
865 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
,
866 op1_mode
), op1_mode
);
867 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
872 /* We must avoid shifting by BITS_PER_WORD bits since that is either
873 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
874 has unknown behavior. Do a single shift first, then shift by the
875 remainder. It's OK to use ~OP1 as the remainder if shift counts
876 are truncated to the mode size. */
877 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
878 outof_input
, const1_rtx
, 0, unsignedp
, methods
);
879 if (shift_mask
== BITS_PER_WORD
- 1)
881 tmp
= immed_wide_int_const
882 (wi::minus_one (GET_MODE_PRECISION (op1_mode
)), op1_mode
);
883 tmp
= simplify_expand_binop (op1_mode
, xor_optab
, op1
, tmp
,
888 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
- 1,
889 op1_mode
), op1_mode
);
890 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
894 if (tmp
== 0 || carries
== 0)
896 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
897 carries
, tmp
, 0, unsignedp
, methods
);
901 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
902 so the result can go directly into INTO_TARGET if convenient. */
903 tmp
= expand_binop (word_mode
, unsigned_shift
, into_input
, op1
,
904 into_target
, unsignedp
, methods
);
908 /* Now OR in the bits carried over from OUTOF_INPUT. */
909 if (!force_expand_binop (word_mode
, ior_optab
, tmp
, carries
,
910 into_target
, unsignedp
, methods
))
913 /* Use a standard word_mode shift for the out-of half. */
914 if (outof_target
!= 0)
915 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
916 outof_target
, unsignedp
, methods
))
923 #ifdef HAVE_conditional_move
924 /* Try implementing expand_doubleword_shift using conditional moves.
925 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
926 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
927 are the shift counts to use in the former and latter case. All other
928 arguments are the same as the parent routine. */
931 expand_doubleword_shift_condmove (machine_mode op1_mode
, optab binoptab
,
932 enum rtx_code cmp_code
, rtx cmp1
, rtx cmp2
,
933 rtx outof_input
, rtx into_input
,
934 rtx subword_op1
, rtx superword_op1
,
935 rtx outof_target
, rtx into_target
,
936 int unsignedp
, enum optab_methods methods
,
937 unsigned HOST_WIDE_INT shift_mask
)
939 rtx outof_superword
, into_superword
;
941 /* Put the superword version of the output into OUTOF_SUPERWORD and
943 outof_superword
= outof_target
!= 0 ? gen_reg_rtx (word_mode
) : 0;
944 if (outof_target
!= 0 && subword_op1
== superword_op1
)
946 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
947 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
948 into_superword
= outof_target
;
949 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
950 outof_superword
, 0, unsignedp
, methods
))
955 into_superword
= gen_reg_rtx (word_mode
);
956 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
957 outof_superword
, into_superword
,
962 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
963 if (!expand_subword_shift (op1_mode
, binoptab
,
964 outof_input
, into_input
, subword_op1
,
965 outof_target
, into_target
,
966 unsignedp
, methods
, shift_mask
))
969 /* Select between them. Do the INTO half first because INTO_SUPERWORD
970 might be the current value of OUTOF_TARGET. */
971 if (!emit_conditional_move (into_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
972 into_target
, into_superword
, word_mode
, false))
975 if (outof_target
!= 0)
976 if (!emit_conditional_move (outof_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
977 outof_target
, outof_superword
,
985 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
986 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
987 input operand; the shift moves bits in the direction OUTOF_INPUT->
988 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
989 of the target. OP1 is the shift count and OP1_MODE is its mode.
990 If OP1 is constant, it will have been truncated as appropriate
991 and is known to be nonzero.
993 If SHIFT_MASK is zero, the result of word shifts is undefined when the
994 shift count is outside the range [0, BITS_PER_WORD). This routine must
995 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
997 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
998 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
999 fill with zeros or sign bits as appropriate.
1001 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
1002 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
1003 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
1004 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
1007 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
1008 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
1009 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
1010 function wants to calculate it itself.
1012 Return true if the shift could be successfully synthesized. */
1015 expand_doubleword_shift (machine_mode op1_mode
, optab binoptab
,
1016 rtx outof_input
, rtx into_input
, rtx op1
,
1017 rtx outof_target
, rtx into_target
,
1018 int unsignedp
, enum optab_methods methods
,
1019 unsigned HOST_WIDE_INT shift_mask
)
1021 rtx superword_op1
, tmp
, cmp1
, cmp2
;
1022 enum rtx_code cmp_code
;
1024 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
1025 fill the result with sign or zero bits as appropriate. If so, the value
1026 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
1027 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
1028 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
1030 This isn't worthwhile for constant shifts since the optimizers will
1031 cope better with in-range shift counts. */
1032 if (shift_mask
>= BITS_PER_WORD
1033 && outof_target
!= 0
1034 && !CONSTANT_P (op1
))
1036 if (!expand_doubleword_shift (op1_mode
, binoptab
,
1037 outof_input
, into_input
, op1
,
1039 unsignedp
, methods
, shift_mask
))
1041 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
1042 outof_target
, unsignedp
, methods
))
1047 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
1048 is true when the effective shift value is less than BITS_PER_WORD.
1049 Set SUPERWORD_OP1 to the shift count that should be used to shift
1050 OUTOF_INPUT into INTO_TARGET when the condition is false. */
1051 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
, op1_mode
), op1_mode
);
1052 if (!CONSTANT_P (op1
) && shift_mask
== BITS_PER_WORD
- 1)
1054 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
1055 is a subword shift count. */
1056 cmp1
= simplify_expand_binop (op1_mode
, and_optab
, op1
, tmp
,
1058 cmp2
= CONST0_RTX (op1_mode
);
1060 superword_op1
= op1
;
1064 /* Set CMP1 to OP1 - BITS_PER_WORD. */
1065 cmp1
= simplify_expand_binop (op1_mode
, sub_optab
, op1
, tmp
,
1067 cmp2
= CONST0_RTX (op1_mode
);
1069 superword_op1
= cmp1
;
1074 /* If we can compute the condition at compile time, pick the
1075 appropriate subroutine. */
1076 tmp
= simplify_relational_operation (cmp_code
, SImode
, op1_mode
, cmp1
, cmp2
);
1077 if (tmp
!= 0 && CONST_INT_P (tmp
))
1079 if (tmp
== const0_rtx
)
1080 return expand_superword_shift (binoptab
, outof_input
, superword_op1
,
1081 outof_target
, into_target
,
1082 unsignedp
, methods
);
1084 return expand_subword_shift (op1_mode
, binoptab
,
1085 outof_input
, into_input
, op1
,
1086 outof_target
, into_target
,
1087 unsignedp
, methods
, shift_mask
);
1090 #ifdef HAVE_conditional_move
1091 /* Try using conditional moves to generate straight-line code. */
1093 rtx_insn
*start
= get_last_insn ();
1094 if (expand_doubleword_shift_condmove (op1_mode
, binoptab
,
1095 cmp_code
, cmp1
, cmp2
,
1096 outof_input
, into_input
,
1098 outof_target
, into_target
,
1099 unsignedp
, methods
, shift_mask
))
1101 delete_insns_since (start
);
1105 /* As a last resort, use branches to select the correct alternative. */
1106 rtx_code_label
*subword_label
= gen_label_rtx ();
1107 rtx_code_label
*done_label
= gen_label_rtx ();
1110 do_compare_rtx_and_jump (cmp1
, cmp2
, cmp_code
, false, op1_mode
,
1111 0, 0, subword_label
, -1);
1114 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
1115 outof_target
, into_target
,
1116 unsignedp
, methods
))
1119 emit_jump_insn (gen_jump (done_label
));
1121 emit_label (subword_label
);
1123 if (!expand_subword_shift (op1_mode
, binoptab
,
1124 outof_input
, into_input
, op1
,
1125 outof_target
, into_target
,
1126 unsignedp
, methods
, shift_mask
))
1129 emit_label (done_label
);
1133 /* Subroutine of expand_binop. Perform a double word multiplication of
1134 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1135 as the target's word_mode. This function return NULL_RTX if anything
1136 goes wrong, in which case it may have already emitted instructions
1137 which need to be deleted.
1139 If we want to multiply two two-word values and have normal and widening
1140 multiplies of single-word values, we can do this with three smaller
1143 The multiplication proceeds as follows:
1144 _______________________
1145 [__op0_high_|__op0_low__]
1146 _______________________
1147 * [__op1_high_|__op1_low__]
1148 _______________________________________________
1149 _______________________
1150 (1) [__op0_low__*__op1_low__]
1151 _______________________
1152 (2a) [__op0_low__*__op1_high_]
1153 _______________________
1154 (2b) [__op0_high_*__op1_low__]
1155 _______________________
1156 (3) [__op0_high_*__op1_high_]
1159 This gives a 4-word result. Since we are only interested in the
1160 lower 2 words, partial result (3) and the upper words of (2a) and
1161 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1162 calculated using non-widening multiplication.
1164 (1), however, needs to be calculated with an unsigned widening
1165 multiplication. If this operation is not directly supported we
1166 try using a signed widening multiplication and adjust the result.
1167 This adjustment works as follows:
1169 If both operands are positive then no adjustment is needed.
1171 If the operands have different signs, for example op0_low < 0 and
1172 op1_low >= 0, the instruction treats the most significant bit of
1173 op0_low as a sign bit instead of a bit with significance
1174 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1175 with 2**BITS_PER_WORD - op0_low, and two's complements the
1176 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1179 Similarly, if both operands are negative, we need to add
1180 (op0_low + op1_low) * 2**BITS_PER_WORD.
1182 We use a trick to adjust quickly. We logically shift op0_low right
1183 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1184 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1185 logical shift exists, we do an arithmetic right shift and subtract
1189 expand_doubleword_mult (machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
1190 bool umulp
, enum optab_methods methods
)
1192 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1193 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1194 rtx wordm1
= umulp
? NULL_RTX
: GEN_INT (BITS_PER_WORD
- 1);
1195 rtx product
, adjust
, product_high
, temp
;
1197 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1198 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1199 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1200 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1202 /* If we're using an unsigned multiply to directly compute the product
1203 of the low-order words of the operands and perform any required
1204 adjustments of the operands, we begin by trying two more multiplications
1205 and then computing the appropriate sum.
1207 We have checked above that the required addition is provided.
1208 Full-word addition will normally always succeed, especially if
1209 it is provided at all, so we don't worry about its failure. The
1210 multiplication may well fail, however, so we do handle that. */
1214 /* ??? This could be done with emit_store_flag where available. */
1215 temp
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1216 NULL_RTX
, 1, methods
);
1218 op0_high
= expand_binop (word_mode
, add_optab
, op0_high
, temp
,
1219 NULL_RTX
, 0, OPTAB_DIRECT
);
1222 temp
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1223 NULL_RTX
, 0, methods
);
1226 op0_high
= expand_binop (word_mode
, sub_optab
, op0_high
, temp
,
1227 NULL_RTX
, 0, OPTAB_DIRECT
);
1234 adjust
= expand_binop (word_mode
, smul_optab
, op0_high
, op1_low
,
1235 NULL_RTX
, 0, OPTAB_DIRECT
);
1239 /* OP0_HIGH should now be dead. */
1243 /* ??? This could be done with emit_store_flag where available. */
1244 temp
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1245 NULL_RTX
, 1, methods
);
1247 op1_high
= expand_binop (word_mode
, add_optab
, op1_high
, temp
,
1248 NULL_RTX
, 0, OPTAB_DIRECT
);
1251 temp
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1252 NULL_RTX
, 0, methods
);
1255 op1_high
= expand_binop (word_mode
, sub_optab
, op1_high
, temp
,
1256 NULL_RTX
, 0, OPTAB_DIRECT
);
1263 temp
= expand_binop (word_mode
, smul_optab
, op1_high
, op0_low
,
1264 NULL_RTX
, 0, OPTAB_DIRECT
);
1268 /* OP1_HIGH should now be dead. */
1270 adjust
= expand_binop (word_mode
, add_optab
, adjust
, temp
,
1271 NULL_RTX
, 0, OPTAB_DIRECT
);
1273 if (target
&& !REG_P (target
))
1277 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1278 target
, 1, OPTAB_DIRECT
);
1280 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1281 target
, 1, OPTAB_DIRECT
);
1286 product_high
= operand_subword (product
, high
, 1, mode
);
1287 adjust
= expand_binop (word_mode
, add_optab
, product_high
, adjust
,
1288 NULL_RTX
, 0, OPTAB_DIRECT
);
1289 emit_move_insn (product_high
, adjust
);
1293 /* Wrapper around expand_binop which takes an rtx code to specify
1294 the operation to perform, not an optab pointer. All other
1295 arguments are the same. */
1297 expand_simple_binop (machine_mode mode
, enum rtx_code code
, rtx op0
,
1298 rtx op1
, rtx target
, int unsignedp
,
1299 enum optab_methods methods
)
1301 optab binop
= code_to_optab (code
);
1304 return expand_binop (mode
, binop
, op0
, op1
, target
, unsignedp
, methods
);
1307 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1308 binop. Order them according to commutative_operand_precedence and, if
1309 possible, try to put TARGET or a pseudo first. */
1311 swap_commutative_operands_with_target (rtx target
, rtx op0
, rtx op1
)
1313 int op0_prec
= commutative_operand_precedence (op0
);
1314 int op1_prec
= commutative_operand_precedence (op1
);
1316 if (op0_prec
< op1_prec
)
1319 if (op0_prec
> op1_prec
)
1322 /* With equal precedence, both orders are ok, but it is better if the
1323 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1324 if (target
== 0 || REG_P (target
))
1325 return (REG_P (op1
) && !REG_P (op0
)) || target
== op1
;
1327 return rtx_equal_p (op1
, target
);
1330 /* Return true if BINOPTAB implements a shift operation. */
1333 shift_optab_p (optab binoptab
)
1335 switch (optab_to_code (binoptab
))
1351 /* Return true if BINOPTAB implements a commutative binary operation. */
1354 commutative_optab_p (optab binoptab
)
1356 return (GET_RTX_CLASS (optab_to_code (binoptab
)) == RTX_COMM_ARITH
1357 || binoptab
== smul_widen_optab
1358 || binoptab
== umul_widen_optab
1359 || binoptab
== smul_highpart_optab
1360 || binoptab
== umul_highpart_optab
);
1363 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
1364 optimizing, and if the operand is a constant that costs more than
1365 1 instruction, force the constant into a register and return that
1366 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1369 avoid_expensive_constant (machine_mode mode
, optab binoptab
,
1370 int opn
, rtx x
, bool unsignedp
)
1372 bool speed
= optimize_insn_for_speed_p ();
1374 if (mode
!= VOIDmode
1377 && (rtx_cost (x
, optab_to_code (binoptab
), opn
, speed
)
1378 > set_src_cost (x
, speed
)))
1380 if (CONST_INT_P (x
))
1382 HOST_WIDE_INT intval
= trunc_int_for_mode (INTVAL (x
), mode
);
1383 if (intval
!= INTVAL (x
))
1384 x
= GEN_INT (intval
);
1387 x
= convert_modes (mode
, VOIDmode
, x
, unsignedp
);
1388 x
= force_reg (mode
, x
);
1393 /* Helper function for expand_binop: handle the case where there
1394 is an insn that directly implements the indicated operation.
1395 Returns null if this is not possible. */
1397 expand_binop_directly (machine_mode mode
, optab binoptab
,
1399 rtx target
, int unsignedp
, enum optab_methods methods
,
1402 machine_mode from_mode
= widened_mode (mode
, op0
, op1
);
1403 enum insn_code icode
= find_widening_optab_handler (binoptab
, mode
,
1405 machine_mode xmode0
= insn_data
[(int) icode
].operand
[1].mode
;
1406 machine_mode xmode1
= insn_data
[(int) icode
].operand
[2].mode
;
1407 machine_mode mode0
, mode1
, tmp_mode
;
1408 struct expand_operand ops
[3];
1411 rtx xop0
= op0
, xop1
= op1
;
1414 /* If it is a commutative operator and the modes would match
1415 if we would swap the operands, we can save the conversions. */
1416 commutative_p
= commutative_optab_p (binoptab
);
1418 && GET_MODE (xop0
) != xmode0
&& GET_MODE (xop1
) != xmode1
1419 && GET_MODE (xop0
) == xmode1
&& GET_MODE (xop1
) == xmode1
)
1426 /* If we are optimizing, force expensive constants into a register. */
1427 xop0
= avoid_expensive_constant (xmode0
, binoptab
, 0, xop0
, unsignedp
);
1428 if (!shift_optab_p (binoptab
))
1429 xop1
= avoid_expensive_constant (xmode1
, binoptab
, 1, xop1
, unsignedp
);
1431 /* In case the insn wants input operands in modes different from
1432 those of the actual operands, convert the operands. It would
1433 seem that we don't need to convert CONST_INTs, but we do, so
1434 that they're properly zero-extended, sign-extended or truncated
1437 mode0
= GET_MODE (xop0
) != VOIDmode
? GET_MODE (xop0
) : mode
;
1438 if (xmode0
!= VOIDmode
&& xmode0
!= mode0
)
1440 xop0
= convert_modes (xmode0
, mode0
, xop0
, unsignedp
);
1444 mode1
= GET_MODE (xop1
) != VOIDmode
? GET_MODE (xop1
) : mode
;
1445 if (xmode1
!= VOIDmode
&& xmode1
!= mode1
)
1447 xop1
= convert_modes (xmode1
, mode1
, xop1
, unsignedp
);
1451 /* If operation is commutative,
1452 try to make the first operand a register.
1453 Even better, try to make it the same as the target.
1454 Also try to make the last operand a constant. */
1456 && swap_commutative_operands_with_target (target
, xop0
, xop1
))
1463 /* Now, if insn's predicates don't allow our operands, put them into
1466 if (binoptab
== vec_pack_trunc_optab
1467 || binoptab
== vec_pack_usat_optab
1468 || binoptab
== vec_pack_ssat_optab
1469 || binoptab
== vec_pack_ufix_trunc_optab
1470 || binoptab
== vec_pack_sfix_trunc_optab
)
1472 /* The mode of the result is different then the mode of the
1474 tmp_mode
= insn_data
[(int) icode
].operand
[0].mode
;
1475 if (GET_MODE_NUNITS (tmp_mode
) != 2 * GET_MODE_NUNITS (mode
))
1477 delete_insns_since (last
);
1484 create_output_operand (&ops
[0], target
, tmp_mode
);
1485 create_input_operand (&ops
[1], xop0
, mode0
);
1486 create_input_operand (&ops
[2], xop1
, mode1
);
1487 pat
= maybe_gen_insn (icode
, 3, ops
);
1490 /* If PAT is composed of more than one insn, try to add an appropriate
1491 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1492 operand, call expand_binop again, this time without a target. */
1493 if (INSN_P (pat
) && NEXT_INSN (as_a
<rtx_insn
*> (pat
)) != NULL_RTX
1494 && ! add_equal_note (as_a
<rtx_insn
*> (pat
), ops
[0].value
,
1495 optab_to_code (binoptab
),
1496 ops
[1].value
, ops
[2].value
))
1498 delete_insns_since (last
);
1499 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
1500 unsignedp
, methods
);
1504 return ops
[0].value
;
1506 delete_insns_since (last
);
1510 /* Generate code to perform an operation specified by BINOPTAB
1511 on operands OP0 and OP1, with result having machine-mode MODE.
1513 UNSIGNEDP is for the case where we have to widen the operands
1514 to perform the operation. It says to use zero-extension.
1516 If TARGET is nonzero, the value
1517 is generated there, if it is convenient to do so.
1518 In all cases an rtx is returned for the locus of the value;
1519 this may or may not be TARGET. */
1522 expand_binop (machine_mode mode
, optab binoptab
, rtx op0
, rtx op1
,
1523 rtx target
, int unsignedp
, enum optab_methods methods
)
1525 enum optab_methods next_methods
1526 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
1527 ? OPTAB_WIDEN
: methods
);
1528 enum mode_class mclass
;
1529 machine_mode wider_mode
;
1532 rtx_insn
*entry_last
= get_last_insn ();
1535 mclass
= GET_MODE_CLASS (mode
);
1537 /* If subtracting an integer constant, convert this into an addition of
1538 the negated constant. */
1540 if (binoptab
== sub_optab
&& CONST_INT_P (op1
))
1542 op1
= negate_rtx (mode
, op1
);
1543 binoptab
= add_optab
;
1546 /* Record where to delete back to if we backtrack. */
1547 last
= get_last_insn ();
1549 /* If we can do it with a three-operand insn, do so. */
1551 if (methods
!= OPTAB_MUST_WIDEN
1552 && find_widening_optab_handler (binoptab
, mode
,
1553 widened_mode (mode
, op0
, op1
), 1)
1554 != CODE_FOR_nothing
)
1556 temp
= expand_binop_directly (mode
, binoptab
, op0
, op1
, target
,
1557 unsignedp
, methods
, last
);
1562 /* If we were trying to rotate, and that didn't work, try rotating
1563 the other direction before falling back to shifts and bitwise-or. */
1564 if (((binoptab
== rotl_optab
1565 && optab_handler (rotr_optab
, mode
) != CODE_FOR_nothing
)
1566 || (binoptab
== rotr_optab
1567 && optab_handler (rotl_optab
, mode
) != CODE_FOR_nothing
))
1568 && mclass
== MODE_INT
)
1570 optab otheroptab
= (binoptab
== rotl_optab
? rotr_optab
: rotl_optab
);
1572 unsigned int bits
= GET_MODE_PRECISION (mode
);
1574 if (CONST_INT_P (op1
))
1575 newop1
= GEN_INT (bits
- INTVAL (op1
));
1576 else if (targetm
.shift_truncation_mask (mode
) == bits
- 1)
1577 newop1
= negate_rtx (GET_MODE (op1
), op1
);
1579 newop1
= expand_binop (GET_MODE (op1
), sub_optab
,
1580 gen_int_mode (bits
, GET_MODE (op1
)), op1
,
1581 NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1583 temp
= expand_binop_directly (mode
, otheroptab
, op0
, newop1
,
1584 target
, unsignedp
, methods
, last
);
1589 /* If this is a multiply, see if we can do a widening operation that
1590 takes operands of this mode and makes a wider mode. */
1592 if (binoptab
== smul_optab
1593 && GET_MODE_2XWIDER_MODE (mode
) != VOIDmode
1594 && (widening_optab_handler ((unsignedp
? umul_widen_optab
1595 : smul_widen_optab
),
1596 GET_MODE_2XWIDER_MODE (mode
), mode
)
1597 != CODE_FOR_nothing
))
1599 temp
= expand_binop (GET_MODE_2XWIDER_MODE (mode
),
1600 unsignedp
? umul_widen_optab
: smul_widen_optab
,
1601 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1605 if (GET_MODE_CLASS (mode
) == MODE_INT
1606 && TRULY_NOOP_TRUNCATION_MODES_P (mode
, GET_MODE (temp
)))
1607 return gen_lowpart (mode
, temp
);
1609 return convert_to_mode (mode
, temp
, unsignedp
);
1613 /* If this is a vector shift by a scalar, see if we can do a vector
1614 shift by a vector. If so, broadcast the scalar into a vector. */
1615 if (mclass
== MODE_VECTOR_INT
)
1617 optab otheroptab
= unknown_optab
;
1619 if (binoptab
== ashl_optab
)
1620 otheroptab
= vashl_optab
;
1621 else if (binoptab
== ashr_optab
)
1622 otheroptab
= vashr_optab
;
1623 else if (binoptab
== lshr_optab
)
1624 otheroptab
= vlshr_optab
;
1625 else if (binoptab
== rotl_optab
)
1626 otheroptab
= vrotl_optab
;
1627 else if (binoptab
== rotr_optab
)
1628 otheroptab
= vrotr_optab
;
1630 if (otheroptab
&& optab_handler (otheroptab
, mode
) != CODE_FOR_nothing
)
1632 rtx vop1
= expand_vector_broadcast (mode
, op1
);
1635 temp
= expand_binop_directly (mode
, otheroptab
, op0
, vop1
,
1636 target
, unsignedp
, methods
, last
);
1643 /* Look for a wider mode of the same class for which we think we
1644 can open-code the operation. Check for a widening multiply at the
1645 wider mode as well. */
1647 if (CLASS_HAS_WIDER_MODES_P (mclass
)
1648 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
1649 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
1650 wider_mode
!= VOIDmode
;
1651 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1653 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
1654 || (binoptab
== smul_optab
1655 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
1656 && (find_widening_optab_handler ((unsignedp
1658 : smul_widen_optab
),
1659 GET_MODE_WIDER_MODE (wider_mode
),
1661 != CODE_FOR_nothing
)))
1663 rtx xop0
= op0
, xop1
= op1
;
1666 /* For certain integer operations, we need not actually extend
1667 the narrow operands, as long as we will truncate
1668 the results to the same narrowness. */
1670 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1671 || binoptab
== xor_optab
1672 || binoptab
== add_optab
|| binoptab
== sub_optab
1673 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1674 && mclass
== MODE_INT
)
1677 xop0
= avoid_expensive_constant (mode
, binoptab
, 0,
1679 if (binoptab
!= ashl_optab
)
1680 xop1
= avoid_expensive_constant (mode
, binoptab
, 1,
1684 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
1686 /* The second operand of a shift must always be extended. */
1687 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1688 no_extend
&& binoptab
!= ashl_optab
);
1690 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1691 unsignedp
, OPTAB_DIRECT
);
1694 if (mclass
!= MODE_INT
1695 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
1698 target
= gen_reg_rtx (mode
);
1699 convert_move (target
, temp
, 0);
1703 return gen_lowpart (mode
, temp
);
1706 delete_insns_since (last
);
1710 /* If operation is commutative,
1711 try to make the first operand a register.
1712 Even better, try to make it the same as the target.
1713 Also try to make the last operand a constant. */
1714 if (commutative_optab_p (binoptab
)
1715 && swap_commutative_operands_with_target (target
, op0
, op1
))
1722 /* These can be done a word at a time. */
1723 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
1724 && mclass
== MODE_INT
1725 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1726 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1731 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1732 won't be accurate, so use a new target. */
1736 || !valid_multiword_target_p (target
))
1737 target
= gen_reg_rtx (mode
);
1741 /* Do the actual arithmetic. */
1742 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1744 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1745 rtx x
= expand_binop (word_mode
, binoptab
,
1746 operand_subword_force (op0
, i
, mode
),
1747 operand_subword_force (op1
, i
, mode
),
1748 target_piece
, unsignedp
, next_methods
);
1753 if (target_piece
!= x
)
1754 emit_move_insn (target_piece
, x
);
1757 insns
= get_insns ();
1760 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
1767 /* Synthesize double word shifts from single word shifts. */
1768 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
1769 || binoptab
== ashr_optab
)
1770 && mclass
== MODE_INT
1771 && (CONST_INT_P (op1
) || optimize_insn_for_speed_p ())
1772 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1773 && GET_MODE_PRECISION (mode
) == GET_MODE_BITSIZE (mode
)
1774 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
1775 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1776 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1778 unsigned HOST_WIDE_INT shift_mask
, double_shift_mask
;
1779 machine_mode op1_mode
;
1781 double_shift_mask
= targetm
.shift_truncation_mask (mode
);
1782 shift_mask
= targetm
.shift_truncation_mask (word_mode
);
1783 op1_mode
= GET_MODE (op1
) != VOIDmode
? GET_MODE (op1
) : word_mode
;
1785 /* Apply the truncation to constant shifts. */
1786 if (double_shift_mask
> 0 && CONST_INT_P (op1
))
1787 op1
= GEN_INT (INTVAL (op1
) & double_shift_mask
);
1789 if (op1
== CONST0_RTX (op1_mode
))
1792 /* Make sure that this is a combination that expand_doubleword_shift
1793 can handle. See the comments there for details. */
1794 if (double_shift_mask
== 0
1795 || (shift_mask
== BITS_PER_WORD
- 1
1796 && double_shift_mask
== BITS_PER_WORD
* 2 - 1))
1799 rtx into_target
, outof_target
;
1800 rtx into_input
, outof_input
;
1801 int left_shift
, outof_word
;
1803 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1804 won't be accurate, so use a new target. */
1808 || !valid_multiword_target_p (target
))
1809 target
= gen_reg_rtx (mode
);
1813 /* OUTOF_* is the word we are shifting bits away from, and
1814 INTO_* is the word that we are shifting bits towards, thus
1815 they differ depending on the direction of the shift and
1816 WORDS_BIG_ENDIAN. */
1818 left_shift
= binoptab
== ashl_optab
;
1819 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1821 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1822 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1824 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1825 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1827 if (expand_doubleword_shift (op1_mode
, binoptab
,
1828 outof_input
, into_input
, op1
,
1829 outof_target
, into_target
,
1830 unsignedp
, next_methods
, shift_mask
))
1832 insns
= get_insns ();
1842 /* Synthesize double word rotates from single word shifts. */
1843 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
1844 && mclass
== MODE_INT
1845 && CONST_INT_P (op1
)
1846 && GET_MODE_PRECISION (mode
) == 2 * BITS_PER_WORD
1847 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1848 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1851 rtx into_target
, outof_target
;
1852 rtx into_input
, outof_input
;
1854 int shift_count
, left_shift
, outof_word
;
1856 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1857 won't be accurate, so use a new target. Do this also if target is not
1858 a REG, first because having a register instead may open optimization
1859 opportunities, and second because if target and op0 happen to be MEMs
1860 designating the same location, we would risk clobbering it too early
1861 in the code sequence we generate below. */
1866 || !valid_multiword_target_p (target
))
1867 target
= gen_reg_rtx (mode
);
1871 shift_count
= INTVAL (op1
);
1873 /* OUTOF_* is the word we are shifting bits away from, and
1874 INTO_* is the word that we are shifting bits towards, thus
1875 they differ depending on the direction of the shift and
1876 WORDS_BIG_ENDIAN. */
1878 left_shift
= (binoptab
== rotl_optab
);
1879 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1881 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1882 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1884 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1885 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1887 if (shift_count
== BITS_PER_WORD
)
1889 /* This is just a word swap. */
1890 emit_move_insn (outof_target
, into_input
);
1891 emit_move_insn (into_target
, outof_input
);
1896 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1897 rtx first_shift_count
, second_shift_count
;
1898 optab reverse_unsigned_shift
, unsigned_shift
;
1900 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1901 ? lshr_optab
: ashl_optab
);
1903 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1904 ? ashl_optab
: lshr_optab
);
1906 if (shift_count
> BITS_PER_WORD
)
1908 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
1909 second_shift_count
= GEN_INT (2 * BITS_PER_WORD
- shift_count
);
1913 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
1914 second_shift_count
= GEN_INT (shift_count
);
1917 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1918 outof_input
, first_shift_count
,
1919 NULL_RTX
, unsignedp
, next_methods
);
1920 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1921 into_input
, second_shift_count
,
1922 NULL_RTX
, unsignedp
, next_methods
);
1924 if (into_temp1
!= 0 && into_temp2
!= 0)
1925 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1926 into_target
, unsignedp
, next_methods
);
1930 if (inter
!= 0 && inter
!= into_target
)
1931 emit_move_insn (into_target
, inter
);
1933 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1934 into_input
, first_shift_count
,
1935 NULL_RTX
, unsignedp
, next_methods
);
1936 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1937 outof_input
, second_shift_count
,
1938 NULL_RTX
, unsignedp
, next_methods
);
1940 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1941 inter
= expand_binop (word_mode
, ior_optab
,
1942 outof_temp1
, outof_temp2
,
1943 outof_target
, unsignedp
, next_methods
);
1945 if (inter
!= 0 && inter
!= outof_target
)
1946 emit_move_insn (outof_target
, inter
);
1949 insns
= get_insns ();
1959 /* These can be done a word at a time by propagating carries. */
1960 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1961 && mclass
== MODE_INT
1962 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
1963 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1966 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1967 const unsigned int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
1968 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1969 rtx xop0
, xop1
, xtarget
;
1971 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1972 value is one of those, use it. Otherwise, use 1 since it is the
1973 one easiest to get. */
1974 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1975 int normalizep
= STORE_FLAG_VALUE
;
1980 /* Prepare the operands. */
1981 xop0
= force_reg (mode
, op0
);
1982 xop1
= force_reg (mode
, op1
);
1984 xtarget
= gen_reg_rtx (mode
);
1986 if (target
== 0 || !REG_P (target
) || !valid_multiword_target_p (target
))
1989 /* Indicate for flow that the entire target reg is being set. */
1991 emit_clobber (xtarget
);
1993 /* Do the actual arithmetic. */
1994 for (i
= 0; i
< nwords
; i
++)
1996 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
1997 rtx target_piece
= operand_subword (xtarget
, index
, 1, mode
);
1998 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
1999 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
2002 /* Main add/subtract of the input operands. */
2003 x
= expand_binop (word_mode
, binoptab
,
2004 op0_piece
, op1_piece
,
2005 target_piece
, unsignedp
, next_methods
);
2011 /* Store carry from main add/subtract. */
2012 carry_out
= gen_reg_rtx (word_mode
);
2013 carry_out
= emit_store_flag_force (carry_out
,
2014 (binoptab
== add_optab
2017 word_mode
, 1, normalizep
);
2024 /* Add/subtract previous carry to main result. */
2025 newx
= expand_binop (word_mode
,
2026 normalizep
== 1 ? binoptab
: otheroptab
,
2028 NULL_RTX
, 1, next_methods
);
2032 /* Get out carry from adding/subtracting carry in. */
2033 rtx carry_tmp
= gen_reg_rtx (word_mode
);
2034 carry_tmp
= emit_store_flag_force (carry_tmp
,
2035 (binoptab
== add_optab
2038 word_mode
, 1, normalizep
);
2040 /* Logical-ior the two poss. carry together. */
2041 carry_out
= expand_binop (word_mode
, ior_optab
,
2042 carry_out
, carry_tmp
,
2043 carry_out
, 0, next_methods
);
2047 emit_move_insn (target_piece
, newx
);
2051 if (x
!= target_piece
)
2052 emit_move_insn (target_piece
, x
);
2055 carry_in
= carry_out
;
2058 if (i
== GET_MODE_BITSIZE (mode
) / (unsigned) BITS_PER_WORD
)
2060 if (optab_handler (mov_optab
, mode
) != CODE_FOR_nothing
2061 || ! rtx_equal_p (target
, xtarget
))
2063 rtx temp
= emit_move_insn (target
, xtarget
);
2065 set_dst_reg_note (temp
, REG_EQUAL
,
2066 gen_rtx_fmt_ee (optab_to_code (binoptab
),
2067 mode
, copy_rtx (xop0
),
2078 delete_insns_since (last
);
2081 /* Attempt to synthesize double word multiplies using a sequence of word
2082 mode multiplications. We first attempt to generate a sequence using a
2083 more efficient unsigned widening multiply, and if that fails we then
2084 try using a signed widening multiply. */
2086 if (binoptab
== smul_optab
2087 && mclass
== MODE_INT
2088 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
2089 && optab_handler (smul_optab
, word_mode
) != CODE_FOR_nothing
2090 && optab_handler (add_optab
, word_mode
) != CODE_FOR_nothing
)
2092 rtx product
= NULL_RTX
;
2093 if (widening_optab_handler (umul_widen_optab
, mode
, word_mode
)
2094 != CODE_FOR_nothing
)
2096 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
2099 delete_insns_since (last
);
2102 if (product
== NULL_RTX
2103 && widening_optab_handler (smul_widen_optab
, mode
, word_mode
)
2104 != CODE_FOR_nothing
)
2106 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
2109 delete_insns_since (last
);
2112 if (product
!= NULL_RTX
)
2114 if (optab_handler (mov_optab
, mode
) != CODE_FOR_nothing
)
2116 temp
= emit_move_insn (target
? target
: product
, product
);
2117 set_dst_reg_note (temp
,
2119 gen_rtx_fmt_ee (MULT
, mode
,
2122 target
? target
: product
);
2128 /* It can't be open-coded in this mode.
2129 Use a library call if one is available and caller says that's ok. */
2131 libfunc
= optab_libfunc (binoptab
, mode
);
2133 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
2137 machine_mode op1_mode
= mode
;
2142 if (shift_optab_p (binoptab
))
2144 op1_mode
= targetm
.libgcc_shift_count_mode ();
2145 /* Specify unsigned here,
2146 since negative shift counts are meaningless. */
2147 op1x
= convert_to_mode (op1_mode
, op1
, 1);
2150 if (GET_MODE (op0
) != VOIDmode
2151 && GET_MODE (op0
) != mode
)
2152 op0
= convert_to_mode (mode
, op0
, unsignedp
);
2154 /* Pass 1 for NO_QUEUE so we don't lose any increments
2155 if the libcall is cse'd or moved. */
2156 value
= emit_library_call_value (libfunc
,
2157 NULL_RTX
, LCT_CONST
, mode
, 2,
2158 op0
, mode
, op1x
, op1_mode
);
2160 insns
= get_insns ();
2163 target
= gen_reg_rtx (mode
);
2164 emit_libcall_block_1 (insns
, target
, value
,
2165 gen_rtx_fmt_ee (optab_to_code (binoptab
),
2167 trapv_binoptab_p (binoptab
));
2172 delete_insns_since (last
);
2174 /* It can't be done in this mode. Can we do it in a wider mode? */
2176 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
2177 || methods
== OPTAB_MUST_WIDEN
))
2179 /* Caller says, don't even try. */
2180 delete_insns_since (entry_last
);
2184 /* Compute the value of METHODS to pass to recursive calls.
2185 Don't allow widening to be tried recursively. */
2187 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
2189 /* Look for a wider mode of the same class for which it appears we can do
2192 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2194 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2195 wider_mode
!= VOIDmode
;
2196 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2198 if (find_widening_optab_handler (binoptab
, wider_mode
, mode
, 1)
2200 || (methods
== OPTAB_LIB
2201 && optab_libfunc (binoptab
, wider_mode
)))
2203 rtx xop0
= op0
, xop1
= op1
;
2206 /* For certain integer operations, we need not actually extend
2207 the narrow operands, as long as we will truncate
2208 the results to the same narrowness. */
2210 if ((binoptab
== ior_optab
|| binoptab
== and_optab
2211 || binoptab
== xor_optab
2212 || binoptab
== add_optab
|| binoptab
== sub_optab
2213 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
2214 && mclass
== MODE_INT
)
2217 xop0
= widen_operand (xop0
, wider_mode
, mode
,
2218 unsignedp
, no_extend
);
2220 /* The second operand of a shift must always be extended. */
2221 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
2222 no_extend
&& binoptab
!= ashl_optab
);
2224 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
2225 unsignedp
, methods
);
2228 if (mclass
!= MODE_INT
2229 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
2232 target
= gen_reg_rtx (mode
);
2233 convert_move (target
, temp
, 0);
2237 return gen_lowpart (mode
, temp
);
2240 delete_insns_since (last
);
2245 delete_insns_since (entry_last
);
2249 /* Expand a binary operator which has both signed and unsigned forms.
2250 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2253 If we widen unsigned operands, we may use a signed wider operation instead
2254 of an unsigned wider operation, since the result would be the same. */
2257 sign_expand_binop (machine_mode mode
, optab uoptab
, optab soptab
,
2258 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
2259 enum optab_methods methods
)
2262 optab direct_optab
= unsignedp
? uoptab
: soptab
;
2265 /* Do it without widening, if possible. */
2266 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
2267 unsignedp
, OPTAB_DIRECT
);
2268 if (temp
|| methods
== OPTAB_DIRECT
)
2271 /* Try widening to a signed int. Disable any direct use of any
2272 signed insn in the current mode. */
2273 save_enable
= swap_optab_enable (soptab
, mode
, false);
2275 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
2276 unsignedp
, OPTAB_WIDEN
);
2278 /* For unsigned operands, try widening to an unsigned int. */
2279 if (!temp
&& unsignedp
)
2280 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
2281 unsignedp
, OPTAB_WIDEN
);
2282 if (temp
|| methods
== OPTAB_WIDEN
)
2285 /* Use the right width libcall if that exists. */
2286 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
2287 unsignedp
, OPTAB_LIB
);
2288 if (temp
|| methods
== OPTAB_LIB
)
2291 /* Must widen and use a libcall, use either signed or unsigned. */
2292 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
2293 unsignedp
, methods
);
2294 if (!temp
&& unsignedp
)
2295 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
2296 unsignedp
, methods
);
2299 /* Undo the fiddling above. */
2301 swap_optab_enable (soptab
, mode
, true);
2305 /* Generate code to perform an operation specified by UNOPPTAB
2306 on operand OP0, with two results to TARG0 and TARG1.
2307 We assume that the order of the operands for the instruction
2308 is TARG0, TARG1, OP0.
2310 Either TARG0 or TARG1 may be zero, but what that means is that
2311 the result is not actually wanted. We will generate it into
2312 a dummy pseudo-reg and discard it. They may not both be zero.
2314 Returns 1 if this operation can be performed; 0 if not. */
2317 expand_twoval_unop (optab unoptab
, rtx op0
, rtx targ0
, rtx targ1
,
2320 machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2321 enum mode_class mclass
;
2322 machine_mode wider_mode
;
2323 rtx_insn
*entry_last
= get_last_insn ();
2326 mclass
= GET_MODE_CLASS (mode
);
2329 targ0
= gen_reg_rtx (mode
);
2331 targ1
= gen_reg_rtx (mode
);
2333 /* Record where to go back to if we fail. */
2334 last
= get_last_insn ();
2336 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
2338 struct expand_operand ops
[3];
2339 enum insn_code icode
= optab_handler (unoptab
, mode
);
2341 create_fixed_operand (&ops
[0], targ0
);
2342 create_fixed_operand (&ops
[1], targ1
);
2343 create_convert_operand_from (&ops
[2], op0
, mode
, unsignedp
);
2344 if (maybe_expand_insn (icode
, 3, ops
))
2348 /* It can't be done in this mode. Can we do it in a wider mode? */
2350 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2352 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2353 wider_mode
!= VOIDmode
;
2354 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2356 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2358 rtx t0
= gen_reg_rtx (wider_mode
);
2359 rtx t1
= gen_reg_rtx (wider_mode
);
2360 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2362 if (expand_twoval_unop (unoptab
, cop0
, t0
, t1
, unsignedp
))
2364 convert_move (targ0
, t0
, unsignedp
);
2365 convert_move (targ1
, t1
, unsignedp
);
2369 delete_insns_since (last
);
2374 delete_insns_since (entry_last
);
2378 /* Generate code to perform an operation specified by BINOPTAB
2379 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2380 We assume that the order of the operands for the instruction
2381 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2382 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2384 Either TARG0 or TARG1 may be zero, but what that means is that
2385 the result is not actually wanted. We will generate it into
2386 a dummy pseudo-reg and discard it. They may not both be zero.
2388 Returns 1 if this operation can be performed; 0 if not. */
2391 expand_twoval_binop (optab binoptab
, rtx op0
, rtx op1
, rtx targ0
, rtx targ1
,
2394 machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2395 enum mode_class mclass
;
2396 machine_mode wider_mode
;
2397 rtx_insn
*entry_last
= get_last_insn ();
2400 mclass
= GET_MODE_CLASS (mode
);
2403 targ0
= gen_reg_rtx (mode
);
2405 targ1
= gen_reg_rtx (mode
);
2407 /* Record where to go back to if we fail. */
2408 last
= get_last_insn ();
2410 if (optab_handler (binoptab
, mode
) != CODE_FOR_nothing
)
2412 struct expand_operand ops
[4];
2413 enum insn_code icode
= optab_handler (binoptab
, mode
);
2414 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2415 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2416 rtx xop0
= op0
, xop1
= op1
;
2418 /* If we are optimizing, force expensive constants into a register. */
2419 xop0
= avoid_expensive_constant (mode0
, binoptab
, 0, xop0
, unsignedp
);
2420 xop1
= avoid_expensive_constant (mode1
, binoptab
, 1, xop1
, unsignedp
);
2422 create_fixed_operand (&ops
[0], targ0
);
2423 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
2424 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
2425 create_fixed_operand (&ops
[3], targ1
);
2426 if (maybe_expand_insn (icode
, 4, ops
))
2428 delete_insns_since (last
);
2431 /* It can't be done in this mode. Can we do it in a wider mode? */
2433 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2435 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2436 wider_mode
!= VOIDmode
;
2437 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2439 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
)
2441 rtx t0
= gen_reg_rtx (wider_mode
);
2442 rtx t1
= gen_reg_rtx (wider_mode
);
2443 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2444 rtx cop1
= convert_modes (wider_mode
, mode
, op1
, unsignedp
);
2446 if (expand_twoval_binop (binoptab
, cop0
, cop1
,
2449 convert_move (targ0
, t0
, unsignedp
);
2450 convert_move (targ1
, t1
, unsignedp
);
2454 delete_insns_since (last
);
2459 delete_insns_since (entry_last
);
2463 /* Expand the two-valued library call indicated by BINOPTAB, but
2464 preserve only one of the values. If TARG0 is non-NULL, the first
2465 value is placed into TARG0; otherwise the second value is placed
2466 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2467 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2468 This routine assumes that the value returned by the library call is
2469 as if the return value was of an integral mode twice as wide as the
2470 mode of OP0. Returns 1 if the call was successful. */
2473 expand_twoval_binop_libfunc (optab binoptab
, rtx op0
, rtx op1
,
2474 rtx targ0
, rtx targ1
, enum rtx_code code
)
2477 machine_mode libval_mode
;
2482 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2483 gcc_assert (!targ0
!= !targ1
);
2485 mode
= GET_MODE (op0
);
2486 libfunc
= optab_libfunc (binoptab
, mode
);
2490 /* The value returned by the library function will have twice as
2491 many bits as the nominal MODE. */
2492 libval_mode
= smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode
),
2495 libval
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
2499 /* Get the part of VAL containing the value that we want. */
2500 libval
= simplify_gen_subreg (mode
, libval
, libval_mode
,
2501 targ0
? 0 : GET_MODE_SIZE (mode
));
2502 insns
= get_insns ();
2504 /* Move the into the desired location. */
2505 emit_libcall_block (insns
, targ0
? targ0
: targ1
, libval
,
2506 gen_rtx_fmt_ee (code
, mode
, op0
, op1
));
2512 /* Wrapper around expand_unop which takes an rtx code to specify
2513 the operation to perform, not an optab pointer. All other
2514 arguments are the same. */
2516 expand_simple_unop (machine_mode mode
, enum rtx_code code
, rtx op0
,
2517 rtx target
, int unsignedp
)
2519 optab unop
= code_to_optab (code
);
2522 return expand_unop (mode
, unop
, op0
, target
, unsignedp
);
2528 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2530 A similar operation can be used for clrsb. UNOPTAB says which operation
2531 we are trying to expand. */
2533 widen_leading (machine_mode mode
, rtx op0
, rtx target
, optab unoptab
)
2535 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2536 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2538 machine_mode wider_mode
;
2539 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2540 wider_mode
!= VOIDmode
;
2541 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2543 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2548 last
= get_last_insn ();
2551 target
= gen_reg_rtx (mode
);
2552 xop0
= widen_operand (op0
, wider_mode
, mode
,
2553 unoptab
!= clrsb_optab
, false);
2554 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2555 unoptab
!= clrsb_optab
);
2558 (wider_mode
, sub_optab
, temp
,
2559 gen_int_mode (GET_MODE_PRECISION (wider_mode
)
2560 - GET_MODE_PRECISION (mode
),
2562 target
, true, OPTAB_DIRECT
);
2564 delete_insns_since (last
);
2573 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2574 quantities, choosing which based on whether the high word is nonzero. */
2576 expand_doubleword_clz (machine_mode mode
, rtx op0
, rtx target
)
2578 rtx xop0
= force_reg (mode
, op0
);
2579 rtx subhi
= gen_highpart (word_mode
, xop0
);
2580 rtx sublo
= gen_lowpart (word_mode
, xop0
);
2581 rtx_code_label
*hi0_label
= gen_label_rtx ();
2582 rtx_code_label
*after_label
= gen_label_rtx ();
2586 /* If we were not given a target, use a word_mode register, not a
2587 'mode' register. The result will fit, and nobody is expecting
2588 anything bigger (the return type of __builtin_clz* is int). */
2590 target
= gen_reg_rtx (word_mode
);
2592 /* In any case, write to a word_mode scratch in both branches of the
2593 conditional, so we can ensure there is a single move insn setting
2594 'target' to tag a REG_EQUAL note on. */
2595 result
= gen_reg_rtx (word_mode
);
2599 /* If the high word is not equal to zero,
2600 then clz of the full value is clz of the high word. */
2601 emit_cmp_and_jump_insns (subhi
, CONST0_RTX (word_mode
), EQ
, 0,
2602 word_mode
, true, hi0_label
);
2604 temp
= expand_unop_direct (word_mode
, clz_optab
, subhi
, result
, true);
2609 convert_move (result
, temp
, true);
2611 emit_jump_insn (gen_jump (after_label
));
2614 /* Else clz of the full value is clz of the low word plus the number
2615 of bits in the high word. */
2616 emit_label (hi0_label
);
2618 temp
= expand_unop_direct (word_mode
, clz_optab
, sublo
, 0, true);
2621 temp
= expand_binop (word_mode
, add_optab
, temp
,
2622 gen_int_mode (GET_MODE_BITSIZE (word_mode
), word_mode
),
2623 result
, true, OPTAB_DIRECT
);
2627 convert_move (result
, temp
, true);
2629 emit_label (after_label
);
2630 convert_move (target
, result
, true);
2635 add_equal_note (seq
, target
, CLZ
, xop0
, 0);
2647 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2649 widen_bswap (machine_mode mode
, rtx op0
, rtx target
)
2651 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2652 machine_mode wider_mode
;
2656 if (!CLASS_HAS_WIDER_MODES_P (mclass
))
2659 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2660 wider_mode
!= VOIDmode
;
2661 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2662 if (optab_handler (bswap_optab
, wider_mode
) != CODE_FOR_nothing
)
2667 last
= get_last_insn ();
2669 x
= widen_operand (op0
, wider_mode
, mode
, true, true);
2670 x
= expand_unop (wider_mode
, bswap_optab
, x
, NULL_RTX
, true);
2672 gcc_assert (GET_MODE_PRECISION (wider_mode
) == GET_MODE_BITSIZE (wider_mode
)
2673 && GET_MODE_PRECISION (mode
) == GET_MODE_BITSIZE (mode
));
2675 x
= expand_shift (RSHIFT_EXPR
, wider_mode
, x
,
2676 GET_MODE_BITSIZE (wider_mode
)
2677 - GET_MODE_BITSIZE (mode
),
2683 target
= gen_reg_rtx (mode
);
2684 emit_move_insn (target
, gen_lowpart (mode
, x
));
2687 delete_insns_since (last
);
2692 /* Try calculating bswap as two bswaps of two word-sized operands. */
2695 expand_doubleword_bswap (machine_mode mode
, rtx op
, rtx target
)
2699 t1
= expand_unop (word_mode
, bswap_optab
,
2700 operand_subword_force (op
, 0, mode
), NULL_RTX
, true);
2701 t0
= expand_unop (word_mode
, bswap_optab
,
2702 operand_subword_force (op
, 1, mode
), NULL_RTX
, true);
2704 if (target
== 0 || !valid_multiword_target_p (target
))
2705 target
= gen_reg_rtx (mode
);
2707 emit_clobber (target
);
2708 emit_move_insn (operand_subword (target
, 0, 1, mode
), t0
);
2709 emit_move_insn (operand_subword (target
, 1, 1, mode
), t1
);
2714 /* Try calculating (parity x) as (and (popcount x) 1), where
2715 popcount can also be done in a wider mode. */
2717 expand_parity (machine_mode mode
, rtx op0
, rtx target
)
2719 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2720 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2722 machine_mode wider_mode
;
2723 for (wider_mode
= mode
; wider_mode
!= VOIDmode
;
2724 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2726 if (optab_handler (popcount_optab
, wider_mode
) != CODE_FOR_nothing
)
2731 last
= get_last_insn ();
2734 target
= gen_reg_rtx (mode
);
2735 xop0
= widen_operand (op0
, wider_mode
, mode
, true, false);
2736 temp
= expand_unop (wider_mode
, popcount_optab
, xop0
, NULL_RTX
,
2739 temp
= expand_binop (wider_mode
, and_optab
, temp
, const1_rtx
,
2740 target
, true, OPTAB_DIRECT
);
2742 delete_insns_since (last
);
2751 /* Try calculating ctz(x) as K - clz(x & -x) ,
2752 where K is GET_MODE_PRECISION(mode) - 1.
2754 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2755 don't have to worry about what the hardware does in that case. (If
2756 the clz instruction produces the usual value at 0, which is K, the
2757 result of this code sequence will be -1; expand_ffs, below, relies
2758 on this. It might be nice to have it be K instead, for consistency
2759 with the (very few) processors that provide a ctz with a defined
2760 value, but that would take one more instruction, and it would be
2761 less convenient for expand_ffs anyway. */
2764 expand_ctz (machine_mode mode
, rtx op0
, rtx target
)
2769 if (optab_handler (clz_optab
, mode
) == CODE_FOR_nothing
)
2774 temp
= expand_unop_direct (mode
, neg_optab
, op0
, NULL_RTX
, true);
2776 temp
= expand_binop (mode
, and_optab
, op0
, temp
, NULL_RTX
,
2777 true, OPTAB_DIRECT
);
2779 temp
= expand_unop_direct (mode
, clz_optab
, temp
, NULL_RTX
, true);
2781 temp
= expand_binop (mode
, sub_optab
,
2782 gen_int_mode (GET_MODE_PRECISION (mode
) - 1, mode
),
2784 true, OPTAB_DIRECT
);
2794 add_equal_note (seq
, temp
, CTZ
, op0
, 0);
2800 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2801 else with the sequence used by expand_clz.
2803 The ffs builtin promises to return zero for a zero value and ctz/clz
2804 may have an undefined value in that case. If they do not give us a
2805 convenient value, we have to generate a test and branch. */
2807 expand_ffs (machine_mode mode
, rtx op0
, rtx target
)
2809 HOST_WIDE_INT val
= 0;
2810 bool defined_at_zero
= false;
2814 if (optab_handler (ctz_optab
, mode
) != CODE_FOR_nothing
)
2818 temp
= expand_unop_direct (mode
, ctz_optab
, op0
, 0, true);
2822 defined_at_zero
= (CTZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2);
2824 else if (optab_handler (clz_optab
, mode
) != CODE_FOR_nothing
)
2827 temp
= expand_ctz (mode
, op0
, 0);
2831 if (CLZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2)
2833 defined_at_zero
= true;
2834 val
= (GET_MODE_PRECISION (mode
) - 1) - val
;
2840 if (defined_at_zero
&& val
== -1)
2841 /* No correction needed at zero. */;
2844 /* We don't try to do anything clever with the situation found
2845 on some processors (eg Alpha) where ctz(0:mode) ==
2846 bitsize(mode). If someone can think of a way to send N to -1
2847 and leave alone all values in the range 0..N-1 (where N is a
2848 power of two), cheaper than this test-and-branch, please add it.
2850 The test-and-branch is done after the operation itself, in case
2851 the operation sets condition codes that can be recycled for this.
2852 (This is true on i386, for instance.) */
2854 rtx_code_label
*nonzero_label
= gen_label_rtx ();
2855 emit_cmp_and_jump_insns (op0
, CONST0_RTX (mode
), NE
, 0,
2856 mode
, true, nonzero_label
);
2858 convert_move (temp
, GEN_INT (-1), false);
2859 emit_label (nonzero_label
);
2862 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2863 to produce a value in the range 0..bitsize. */
2864 temp
= expand_binop (mode
, add_optab
, temp
, gen_int_mode (1, mode
),
2865 target
, false, OPTAB_DIRECT
);
2872 add_equal_note (seq
, temp
, FFS
, op0
, 0);
2881 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2882 conditions, VAL may already be a SUBREG against which we cannot generate
2883 a further SUBREG. In this case, we expect forcing the value into a
2884 register will work around the situation. */
2887 lowpart_subreg_maybe_copy (machine_mode omode
, rtx val
,
2891 ret
= lowpart_subreg (omode
, val
, imode
);
2894 val
= force_reg (imode
, val
);
2895 ret
= lowpart_subreg (omode
, val
, imode
);
2896 gcc_assert (ret
!= NULL
);
2901 /* Expand a floating point absolute value or negation operation via a
2902 logical operation on the sign bit. */
2905 expand_absneg_bit (enum rtx_code code
, machine_mode mode
,
2906 rtx op0
, rtx target
)
2908 const struct real_format
*fmt
;
2909 int bitpos
, word
, nwords
, i
;
2914 /* The format has to have a simple sign bit. */
2915 fmt
= REAL_MODE_FORMAT (mode
);
2919 bitpos
= fmt
->signbit_rw
;
2923 /* Don't create negative zeros if the format doesn't support them. */
2924 if (code
== NEG
&& !fmt
->has_signed_zero
)
2927 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
2929 imode
= int_mode_for_mode (mode
);
2930 if (imode
== BLKmode
)
2939 if (FLOAT_WORDS_BIG_ENDIAN
)
2940 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
2942 word
= bitpos
/ BITS_PER_WORD
;
2943 bitpos
= bitpos
% BITS_PER_WORD
;
2944 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
2947 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
2953 || (nwords
> 1 && !valid_multiword_target_p (target
)))
2954 target
= gen_reg_rtx (mode
);
2960 for (i
= 0; i
< nwords
; ++i
)
2962 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
2963 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
2967 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2969 immed_wide_int_const (mask
, imode
),
2970 targ_piece
, 1, OPTAB_LIB_WIDEN
);
2971 if (temp
!= targ_piece
)
2972 emit_move_insn (targ_piece
, temp
);
2975 emit_move_insn (targ_piece
, op0_piece
);
2978 insns
= get_insns ();
2985 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2986 gen_lowpart (imode
, op0
),
2987 immed_wide_int_const (mask
, imode
),
2988 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
2989 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
2991 set_dst_reg_note (get_last_insn (), REG_EQUAL
,
2992 gen_rtx_fmt_e (code
, mode
, copy_rtx (op0
)),
2999 /* As expand_unop, but will fail rather than attempt the operation in a
3000 different mode or with a libcall. */
3002 expand_unop_direct (machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
3005 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
3007 struct expand_operand ops
[2];
3008 enum insn_code icode
= optab_handler (unoptab
, mode
);
3009 rtx_insn
*last
= get_last_insn ();
3012 create_output_operand (&ops
[0], target
, mode
);
3013 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
3014 pat
= maybe_gen_insn (icode
, 2, ops
);
3017 if (INSN_P (pat
) && NEXT_INSN (as_a
<rtx_insn
*> (pat
)) != NULL_RTX
3018 && ! add_equal_note (as_a
<rtx_insn
*> (pat
), ops
[0].value
,
3019 optab_to_code (unoptab
),
3020 ops
[1].value
, NULL_RTX
))
3022 delete_insns_since (last
);
3023 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
3028 return ops
[0].value
;
3034 /* Generate code to perform an operation specified by UNOPTAB
3035 on operand OP0, with result having machine-mode MODE.
3037 UNSIGNEDP is for the case where we have to widen the operands
3038 to perform the operation. It says to use zero-extension.
3040 If TARGET is nonzero, the value
3041 is generated there, if it is convenient to do so.
3042 In all cases an rtx is returned for the locus of the value;
3043 this may or may not be TARGET. */
3046 expand_unop (machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
3049 enum mode_class mclass
= GET_MODE_CLASS (mode
);
3050 machine_mode wider_mode
;
3054 temp
= expand_unop_direct (mode
, unoptab
, op0
, target
, unsignedp
);
3058 /* It can't be done in this mode. Can we open-code it in a wider mode? */
3060 /* Widening (or narrowing) clz needs special treatment. */
3061 if (unoptab
== clz_optab
)
3063 temp
= widen_leading (mode
, op0
, target
, unoptab
);
3067 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
3068 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
3070 temp
= expand_doubleword_clz (mode
, op0
, target
);
3078 if (unoptab
== clrsb_optab
)
3080 temp
= widen_leading (mode
, op0
, target
, unoptab
);
3086 /* Widening (or narrowing) bswap needs special treatment. */
3087 if (unoptab
== bswap_optab
)
3089 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
3090 or ROTATERT. First try these directly; if this fails, then try the
3091 obvious pair of shifts with allowed widening, as this will probably
3092 be always more efficient than the other fallback methods. */
3098 if (optab_handler (rotl_optab
, mode
) != CODE_FOR_nothing
)
3100 temp
= expand_binop (mode
, rotl_optab
, op0
, GEN_INT (8), target
,
3101 unsignedp
, OPTAB_DIRECT
);
3106 if (optab_handler (rotr_optab
, mode
) != CODE_FOR_nothing
)
3108 temp
= expand_binop (mode
, rotr_optab
, op0
, GEN_INT (8), target
,
3109 unsignedp
, OPTAB_DIRECT
);
3114 last
= get_last_insn ();
3116 temp1
= expand_binop (mode
, ashl_optab
, op0
, GEN_INT (8), NULL_RTX
,
3117 unsignedp
, OPTAB_WIDEN
);
3118 temp2
= expand_binop (mode
, lshr_optab
, op0
, GEN_INT (8), NULL_RTX
,
3119 unsignedp
, OPTAB_WIDEN
);
3122 temp
= expand_binop (mode
, ior_optab
, temp1
, temp2
, target
,
3123 unsignedp
, OPTAB_WIDEN
);
3128 delete_insns_since (last
);
3131 temp
= widen_bswap (mode
, op0
, target
);
3135 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
3136 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
3138 temp
= expand_doubleword_bswap (mode
, op0
, target
);
3146 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3147 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
3148 wider_mode
!= VOIDmode
;
3149 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3151 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
3154 rtx_insn
*last
= get_last_insn ();
3156 /* For certain operations, we need not actually extend
3157 the narrow operand, as long as we will truncate the
3158 results to the same narrowness. */
3160 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3161 (unoptab
== neg_optab
3162 || unoptab
== one_cmpl_optab
)
3163 && mclass
== MODE_INT
);
3165 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3170 if (mclass
!= MODE_INT
3171 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
3174 target
= gen_reg_rtx (mode
);
3175 convert_move (target
, temp
, 0);
3179 return gen_lowpart (mode
, temp
);
3182 delete_insns_since (last
);
3186 /* These can be done a word at a time. */
3187 if (unoptab
== one_cmpl_optab
3188 && mclass
== MODE_INT
3189 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
3190 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
3195 if (target
== 0 || target
== op0
|| !valid_multiword_target_p (target
))
3196 target
= gen_reg_rtx (mode
);
3200 /* Do the actual arithmetic. */
3201 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
3203 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
3204 rtx x
= expand_unop (word_mode
, unoptab
,
3205 operand_subword_force (op0
, i
, mode
),
3206 target_piece
, unsignedp
);
3208 if (target_piece
!= x
)
3209 emit_move_insn (target_piece
, x
);
3212 insns
= get_insns ();
3219 if (optab_to_code (unoptab
) == NEG
)
3221 /* Try negating floating point values by flipping the sign bit. */
3222 if (SCALAR_FLOAT_MODE_P (mode
))
3224 temp
= expand_absneg_bit (NEG
, mode
, op0
, target
);
3229 /* If there is no negation pattern, and we have no negative zero,
3230 try subtracting from zero. */
3231 if (!HONOR_SIGNED_ZEROS (mode
))
3233 temp
= expand_binop (mode
, (unoptab
== negv_optab
3234 ? subv_optab
: sub_optab
),
3235 CONST0_RTX (mode
), op0
, target
,
3236 unsignedp
, OPTAB_DIRECT
);
3242 /* Try calculating parity (x) as popcount (x) % 2. */
3243 if (unoptab
== parity_optab
)
3245 temp
= expand_parity (mode
, op0
, target
);
3250 /* Try implementing ffs (x) in terms of clz (x). */
3251 if (unoptab
== ffs_optab
)
3253 temp
= expand_ffs (mode
, op0
, target
);
3258 /* Try implementing ctz (x) in terms of clz (x). */
3259 if (unoptab
== ctz_optab
)
3261 temp
= expand_ctz (mode
, op0
, target
);
3267 /* Now try a library call in this mode. */
3268 libfunc
= optab_libfunc (unoptab
, mode
);
3274 machine_mode outmode
= mode
;
3276 /* All of these functions return small values. Thus we choose to
3277 have them return something that isn't a double-word. */
3278 if (unoptab
== ffs_optab
|| unoptab
== clz_optab
|| unoptab
== ctz_optab
3279 || unoptab
== clrsb_optab
|| unoptab
== popcount_optab
3280 || unoptab
== parity_optab
)
3282 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node
),
3283 optab_libfunc (unoptab
, mode
)));
3287 /* Pass 1 for NO_QUEUE so we don't lose any increments
3288 if the libcall is cse'd or moved. */
3289 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, outmode
,
3291 insns
= get_insns ();
3294 target
= gen_reg_rtx (outmode
);
3295 eq_value
= gen_rtx_fmt_e (optab_to_code (unoptab
), mode
, op0
);
3296 if (GET_MODE_SIZE (outmode
) < GET_MODE_SIZE (mode
))
3297 eq_value
= simplify_gen_unary (TRUNCATE
, outmode
, eq_value
, mode
);
3298 else if (GET_MODE_SIZE (outmode
) > GET_MODE_SIZE (mode
))
3299 eq_value
= simplify_gen_unary (ZERO_EXTEND
, outmode
, eq_value
, mode
);
3300 emit_libcall_block_1 (insns
, target
, value
, eq_value
,
3301 trapv_unoptab_p (unoptab
));
3306 /* It can't be done in this mode. Can we do it in a wider mode? */
3308 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3310 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
3311 wider_mode
!= VOIDmode
;
3312 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3314 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
3315 || optab_libfunc (unoptab
, wider_mode
))
3318 rtx_insn
*last
= get_last_insn ();
3320 /* For certain operations, we need not actually extend
3321 the narrow operand, as long as we will truncate the
3322 results to the same narrowness. */
3323 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3324 (unoptab
== neg_optab
3325 || unoptab
== one_cmpl_optab
3326 || unoptab
== bswap_optab
)
3327 && mclass
== MODE_INT
);
3329 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3332 /* If we are generating clz using wider mode, adjust the
3333 result. Similarly for clrsb. */
3334 if ((unoptab
== clz_optab
|| unoptab
== clrsb_optab
)
3337 (wider_mode
, sub_optab
, temp
,
3338 gen_int_mode (GET_MODE_PRECISION (wider_mode
)
3339 - GET_MODE_PRECISION (mode
),
3341 target
, true, OPTAB_DIRECT
);
3343 /* Likewise for bswap. */
3344 if (unoptab
== bswap_optab
&& temp
!= 0)
3346 gcc_assert (GET_MODE_PRECISION (wider_mode
)
3347 == GET_MODE_BITSIZE (wider_mode
)
3348 && GET_MODE_PRECISION (mode
)
3349 == GET_MODE_BITSIZE (mode
));
3351 temp
= expand_shift (RSHIFT_EXPR
, wider_mode
, temp
,
3352 GET_MODE_BITSIZE (wider_mode
)
3353 - GET_MODE_BITSIZE (mode
),
3359 if (mclass
!= MODE_INT
)
3362 target
= gen_reg_rtx (mode
);
3363 convert_move (target
, temp
, 0);
3367 return gen_lowpart (mode
, temp
);
3370 delete_insns_since (last
);
3375 /* One final attempt at implementing negation via subtraction,
3376 this time allowing widening of the operand. */
3377 if (optab_to_code (unoptab
) == NEG
&& !HONOR_SIGNED_ZEROS (mode
))
3380 temp
= expand_binop (mode
,
3381 unoptab
== negv_optab
? subv_optab
: sub_optab
,
3382 CONST0_RTX (mode
), op0
,
3383 target
, unsignedp
, OPTAB_LIB_WIDEN
);
3391 /* Emit code to compute the absolute value of OP0, with result to
3392 TARGET if convenient. (TARGET may be 0.) The return value says
3393 where the result actually is to be found.
3395 MODE is the mode of the operand; the mode of the result is
3396 different but can be deduced from MODE.
3401 expand_abs_nojump (machine_mode mode
, rtx op0
, rtx target
,
3402 int result_unsignedp
)
3406 if (GET_MODE_CLASS (mode
) != MODE_INT
3408 result_unsignedp
= 1;
3410 /* First try to do it with a special abs instruction. */
3411 temp
= expand_unop (mode
, result_unsignedp
? abs_optab
: absv_optab
,
3416 /* For floating point modes, try clearing the sign bit. */
3417 if (SCALAR_FLOAT_MODE_P (mode
))
3419 temp
= expand_absneg_bit (ABS
, mode
, op0
, target
);
3424 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3425 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
3426 && !HONOR_SIGNED_ZEROS (mode
))
3428 rtx_insn
*last
= get_last_insn ();
3430 temp
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3433 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3439 delete_insns_since (last
);
3442 /* If this machine has expensive jumps, we can do integer absolute
3443 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3444 where W is the width of MODE. */
3446 if (GET_MODE_CLASS (mode
) == MODE_INT
3447 && BRANCH_COST (optimize_insn_for_speed_p (),
3450 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
3451 GET_MODE_PRECISION (mode
) - 1,
3454 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
3457 temp
= expand_binop (mode
, result_unsignedp
? sub_optab
: subv_optab
,
3458 temp
, extended
, target
, 0, OPTAB_LIB_WIDEN
);
3468 expand_abs (machine_mode mode
, rtx op0
, rtx target
,
3469 int result_unsignedp
, int safe
)
3472 rtx_code_label
*op1
;
3474 if (GET_MODE_CLASS (mode
) != MODE_INT
3476 result_unsignedp
= 1;
3478 temp
= expand_abs_nojump (mode
, op0
, target
, result_unsignedp
);
3482 /* If that does not win, use conditional jump and negate. */
3484 /* It is safe to use the target if it is the same
3485 as the source if this is also a pseudo register */
3486 if (op0
== target
&& REG_P (op0
)
3487 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
3490 op1
= gen_label_rtx ();
3491 if (target
== 0 || ! safe
3492 || GET_MODE (target
) != mode
3493 || (MEM_P (target
) && MEM_VOLATILE_P (target
))
3495 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
3496 target
= gen_reg_rtx (mode
);
3498 emit_move_insn (target
, op0
);
3501 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
3502 NULL_RTX
, NULL_RTX
, op1
, -1);
3504 op0
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3507 emit_move_insn (target
, op0
);
3513 /* Emit code to compute the one's complement absolute value of OP0
3514 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3515 (TARGET may be NULL_RTX.) The return value says where the result
3516 actually is to be found.
3518 MODE is the mode of the operand; the mode of the result is
3519 different but can be deduced from MODE. */
3522 expand_one_cmpl_abs_nojump (machine_mode mode
, rtx op0
, rtx target
)
3526 /* Not applicable for floating point modes. */
3527 if (FLOAT_MODE_P (mode
))
3530 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3531 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
)
3533 rtx_insn
*last
= get_last_insn ();
3535 temp
= expand_unop (mode
, one_cmpl_optab
, op0
, NULL_RTX
, 0);
3537 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3543 delete_insns_since (last
);
3546 /* If this machine has expensive jumps, we can do one's complement
3547 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3549 if (GET_MODE_CLASS (mode
) == MODE_INT
3550 && BRANCH_COST (optimize_insn_for_speed_p (),
3553 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
3554 GET_MODE_PRECISION (mode
) - 1,
3557 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
3567 /* A subroutine of expand_copysign, perform the copysign operation using the
3568 abs and neg primitives advertised to exist on the target. The assumption
3569 is that we have a split register file, and leaving op0 in fp registers,
3570 and not playing with subregs so much, will help the register allocator. */
3573 expand_copysign_absneg (machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3574 int bitpos
, bool op0_is_abs
)
3577 enum insn_code icode
;
3579 rtx_code_label
*label
;
3584 /* Check if the back end provides an insn that handles signbit for the
3586 icode
= optab_handler (signbit_optab
, mode
);
3587 if (icode
!= CODE_FOR_nothing
)
3589 imode
= insn_data
[(int) icode
].operand
[0].mode
;
3590 sign
= gen_reg_rtx (imode
);
3591 emit_unop_insn (icode
, sign
, op1
, UNKNOWN
);
3595 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3597 imode
= int_mode_for_mode (mode
);
3598 if (imode
== BLKmode
)
3600 op1
= gen_lowpart (imode
, op1
);
3607 if (FLOAT_WORDS_BIG_ENDIAN
)
3608 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3610 word
= bitpos
/ BITS_PER_WORD
;
3611 bitpos
= bitpos
% BITS_PER_WORD
;
3612 op1
= operand_subword_force (op1
, word
, mode
);
3615 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3616 sign
= expand_binop (imode
, and_optab
, op1
,
3617 immed_wide_int_const (mask
, imode
),
3618 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3623 op0
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
3630 if (target
== NULL_RTX
)
3631 target
= copy_to_reg (op0
);
3633 emit_move_insn (target
, op0
);
3636 label
= gen_label_rtx ();
3637 emit_cmp_and_jump_insns (sign
, const0_rtx
, EQ
, NULL_RTX
, imode
, 1, label
);
3639 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3640 op0
= simplify_unary_operation (NEG
, mode
, op0
, mode
);
3642 op0
= expand_unop (mode
, neg_optab
, op0
, target
, 0);
3644 emit_move_insn (target
, op0
);
3652 /* A subroutine of expand_copysign, perform the entire copysign operation
3653 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3654 is true if op0 is known to have its sign bit clear. */
3657 expand_copysign_bit (machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3658 int bitpos
, bool op0_is_abs
)
3661 int word
, nwords
, i
;
3665 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3667 imode
= int_mode_for_mode (mode
);
3668 if (imode
== BLKmode
)
3677 if (FLOAT_WORDS_BIG_ENDIAN
)
3678 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3680 word
= bitpos
/ BITS_PER_WORD
;
3681 bitpos
= bitpos
% BITS_PER_WORD
;
3682 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
3685 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3690 || (nwords
> 1 && !valid_multiword_target_p (target
)))
3691 target
= gen_reg_rtx (mode
);
3697 for (i
= 0; i
< nwords
; ++i
)
3699 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
3700 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
3706 = expand_binop (imode
, and_optab
, op0_piece
,
3707 immed_wide_int_const (~mask
, imode
),
3708 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3709 op1
= expand_binop (imode
, and_optab
,
3710 operand_subword_force (op1
, i
, mode
),
3711 immed_wide_int_const (mask
, imode
),
3712 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3714 temp
= expand_binop (imode
, ior_optab
, op0_piece
, op1
,
3715 targ_piece
, 1, OPTAB_LIB_WIDEN
);
3716 if (temp
!= targ_piece
)
3717 emit_move_insn (targ_piece
, temp
);
3720 emit_move_insn (targ_piece
, op0_piece
);
3723 insns
= get_insns ();
3730 op1
= expand_binop (imode
, and_optab
, gen_lowpart (imode
, op1
),
3731 immed_wide_int_const (mask
, imode
),
3732 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3734 op0
= gen_lowpart (imode
, op0
);
3736 op0
= expand_binop (imode
, and_optab
, op0
,
3737 immed_wide_int_const (~mask
, imode
),
3738 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3740 temp
= expand_binop (imode
, ior_optab
, op0
, op1
,
3741 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3742 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3748 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3749 scalar floating point mode. Return NULL if we do not know how to
3750 expand the operation inline. */
3753 expand_copysign (rtx op0
, rtx op1
, rtx target
)
3755 machine_mode mode
= GET_MODE (op0
);
3756 const struct real_format
*fmt
;
3760 gcc_assert (SCALAR_FLOAT_MODE_P (mode
));
3761 gcc_assert (GET_MODE (op1
) == mode
);
3763 /* First try to do it with a special instruction. */
3764 temp
= expand_binop (mode
, copysign_optab
, op0
, op1
,
3765 target
, 0, OPTAB_DIRECT
);
3769 fmt
= REAL_MODE_FORMAT (mode
);
3770 if (fmt
== NULL
|| !fmt
->has_signed_zero
)
3774 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3776 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0
)))
3777 op0
= simplify_unary_operation (ABS
, mode
, op0
, mode
);
3781 if (fmt
->signbit_ro
>= 0
3782 && (CONST_DOUBLE_AS_FLOAT_P (op0
)
3783 || (optab_handler (neg_optab
, mode
) != CODE_FOR_nothing
3784 && optab_handler (abs_optab
, mode
) != CODE_FOR_nothing
)))
3786 temp
= expand_copysign_absneg (mode
, op0
, op1
, target
,
3787 fmt
->signbit_ro
, op0_is_abs
);
3792 if (fmt
->signbit_rw
< 0)
3794 return expand_copysign_bit (mode
, op0
, op1
, target
,
3795 fmt
->signbit_rw
, op0_is_abs
);
3798 /* Generate an instruction whose insn-code is INSN_CODE,
3799 with two operands: an output TARGET and an input OP0.
3800 TARGET *must* be nonzero, and the output is always stored there.
3801 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3802 the value that is stored into TARGET.
3804 Return false if expansion failed. */
3807 maybe_emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
,
3810 struct expand_operand ops
[2];
3813 create_output_operand (&ops
[0], target
, GET_MODE (target
));
3814 create_input_operand (&ops
[1], op0
, GET_MODE (op0
));
3815 pat
= maybe_gen_insn (icode
, 2, ops
);
3819 if (INSN_P (pat
) && NEXT_INSN (as_a
<rtx_insn
*> (pat
)) != NULL_RTX
3821 add_equal_note (as_a
<rtx_insn
*> (pat
), ops
[0].value
, code
, ops
[1].value
,
3826 if (ops
[0].value
!= target
)
3827 emit_move_insn (target
, ops
[0].value
);
3830 /* Generate an instruction whose insn-code is INSN_CODE,
3831 with two operands: an output TARGET and an input OP0.
3832 TARGET *must* be nonzero, and the output is always stored there.
3833 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3834 the value that is stored into TARGET. */
3837 emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
, enum rtx_code code
)
3839 bool ok
= maybe_emit_unop_insn (icode
, target
, op0
, code
);
3843 struct no_conflict_data
3846 rtx_insn
*first
, *insn
;
3850 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3851 the currently examined clobber / store has to stay in the list of
3852 insns that constitute the actual libcall block. */
3854 no_conflict_move_test (rtx dest
, const_rtx set
, void *p0
)
3856 struct no_conflict_data
*p
= (struct no_conflict_data
*) p0
;
3858 /* If this inns directly contributes to setting the target, it must stay. */
3859 if (reg_overlap_mentioned_p (p
->target
, dest
))
3860 p
->must_stay
= true;
3861 /* If we haven't committed to keeping any other insns in the list yet,
3862 there is nothing more to check. */
3863 else if (p
->insn
== p
->first
)
3865 /* If this insn sets / clobbers a register that feeds one of the insns
3866 already in the list, this insn has to stay too. */
3867 else if (reg_overlap_mentioned_p (dest
, PATTERN (p
->first
))
3868 || (CALL_P (p
->first
) && (find_reg_fusage (p
->first
, USE
, dest
)))
3869 || reg_used_between_p (dest
, p
->first
, p
->insn
)
3870 /* Likewise if this insn depends on a register set by a previous
3871 insn in the list, or if it sets a result (presumably a hard
3872 register) that is set or clobbered by a previous insn.
3873 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3874 SET_DEST perform the former check on the address, and the latter
3875 check on the MEM. */
3876 || (GET_CODE (set
) == SET
3877 && (modified_in_p (SET_SRC (set
), p
->first
)
3878 || modified_in_p (SET_DEST (set
), p
->first
)
3879 || modified_between_p (SET_SRC (set
), p
->first
, p
->insn
)
3880 || modified_between_p (SET_DEST (set
), p
->first
, p
->insn
))))
3881 p
->must_stay
= true;
3885 /* Emit code to make a call to a constant function or a library call.
3887 INSNS is a list containing all insns emitted in the call.
3888 These insns leave the result in RESULT. Our block is to copy RESULT
3889 to TARGET, which is logically equivalent to EQUIV.
3891 We first emit any insns that set a pseudo on the assumption that these are
3892 loading constants into registers; doing so allows them to be safely cse'ed
3893 between blocks. Then we emit all the other insns in the block, followed by
3894 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3895 note with an operand of EQUIV. */
3898 emit_libcall_block_1 (rtx_insn
*insns
, rtx target
, rtx result
, rtx equiv
,
3899 bool equiv_may_trap
)
3901 rtx final_dest
= target
;
3902 rtx_insn
*next
, *last
, *insn
;
3904 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3905 into a MEM later. Protect the libcall block from this change. */
3906 if (! REG_P (target
) || REG_USERVAR_P (target
))
3907 target
= gen_reg_rtx (GET_MODE (target
));
3909 /* If we're using non-call exceptions, a libcall corresponding to an
3910 operation that may trap may also trap. */
3911 /* ??? See the comment in front of make_reg_eh_region_note. */
3912 if (cfun
->can_throw_non_call_exceptions
3913 && (equiv_may_trap
|| may_trap_p (equiv
)))
3915 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3918 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
3921 int lp_nr
= INTVAL (XEXP (note
, 0));
3922 if (lp_nr
== 0 || lp_nr
== INT_MIN
)
3923 remove_note (insn
, note
);
3929 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3930 reg note to indicate that this call cannot throw or execute a nonlocal
3931 goto (unless there is already a REG_EH_REGION note, in which case
3933 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3935 make_reg_eh_region_note_nothrow_nononlocal (insn
);
3938 /* First emit all insns that set pseudos. Remove them from the list as
3939 we go. Avoid insns that set pseudos which were referenced in previous
3940 insns. These can be generated by move_by_pieces, for example,
3941 to update an address. Similarly, avoid insns that reference things
3942 set in previous insns. */
3944 for (insn
= insns
; insn
; insn
= next
)
3946 rtx set
= single_set (insn
);
3948 next
= NEXT_INSN (insn
);
3950 if (set
!= 0 && REG_P (SET_DEST (set
))
3951 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
)
3953 struct no_conflict_data data
;
3955 data
.target
= const0_rtx
;
3959 note_stores (PATTERN (insn
), no_conflict_move_test
, &data
);
3960 if (! data
.must_stay
)
3962 if (PREV_INSN (insn
))
3963 SET_NEXT_INSN (PREV_INSN (insn
)) = next
;
3968 SET_PREV_INSN (next
) = PREV_INSN (insn
);
3974 /* Some ports use a loop to copy large arguments onto the stack.
3975 Don't move anything outside such a loop. */
3980 /* Write the remaining insns followed by the final copy. */
3981 for (insn
= insns
; insn
; insn
= next
)
3983 next
= NEXT_INSN (insn
);
3988 last
= emit_move_insn (target
, result
);
3989 set_dst_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
), target
);
3991 if (final_dest
!= target
)
3992 emit_move_insn (final_dest
, target
);
3996 emit_libcall_block (rtx insns
, rtx target
, rtx result
, rtx equiv
)
3998 emit_libcall_block_1 (safe_as_a
<rtx_insn
*> (insns
),
3999 target
, result
, equiv
, false);
4002 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
4003 PURPOSE describes how this comparison will be used. CODE is the rtx
4004 comparison code we will be using.
4006 ??? Actually, CODE is slightly weaker than that. A target is still
4007 required to implement all of the normal bcc operations, but not
4008 required to implement all (or any) of the unordered bcc operations. */
4011 can_compare_p (enum rtx_code code
, machine_mode mode
,
4012 enum can_compare_purpose purpose
)
4015 test
= gen_rtx_fmt_ee (code
, mode
, const0_rtx
, const0_rtx
);
4018 enum insn_code icode
;
4020 if (purpose
== ccp_jump
4021 && (icode
= optab_handler (cbranch_optab
, mode
)) != CODE_FOR_nothing
4022 && insn_operand_matches (icode
, 0, test
))
4024 if (purpose
== ccp_store_flag
4025 && (icode
= optab_handler (cstore_optab
, mode
)) != CODE_FOR_nothing
4026 && insn_operand_matches (icode
, 1, test
))
4028 if (purpose
== ccp_cmov
4029 && optab_handler (cmov_optab
, mode
) != CODE_FOR_nothing
)
4032 mode
= GET_MODE_WIDER_MODE (mode
);
4033 PUT_MODE (test
, mode
);
4035 while (mode
!= VOIDmode
);
4040 /* This function is called when we are going to emit a compare instruction that
4041 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
4043 *PMODE is the mode of the inputs (in case they are const_int).
4044 *PUNSIGNEDP nonzero says that the operands are unsigned;
4045 this matters if they need to be widened (as given by METHODS).
4047 If they have mode BLKmode, then SIZE specifies the size of both operands.
4049 This function performs all the setup necessary so that the caller only has
4050 to emit a single comparison insn. This setup can involve doing a BLKmode
4051 comparison or emitting a library call to perform the comparison if no insn
4052 is available to handle it.
4053 The values which are passed in through pointers can be modified; the caller
4054 should perform the comparison on the modified values. Constant
4055 comparisons must have already been folded. */
4058 prepare_cmp_insn (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4059 int unsignedp
, enum optab_methods methods
,
4060 rtx
*ptest
, machine_mode
*pmode
)
4062 machine_mode mode
= *pmode
;
4064 machine_mode cmp_mode
;
4065 enum mode_class mclass
;
4067 /* The other methods are not needed. */
4068 gcc_assert (methods
== OPTAB_DIRECT
|| methods
== OPTAB_WIDEN
4069 || methods
== OPTAB_LIB_WIDEN
);
4071 /* If we are optimizing, force expensive constants into a register. */
4072 if (CONSTANT_P (x
) && optimize
4073 && (rtx_cost (x
, COMPARE
, 0, optimize_insn_for_speed_p ())
4074 > COSTS_N_INSNS (1)))
4075 x
= force_reg (mode
, x
);
4077 if (CONSTANT_P (y
) && optimize
4078 && (rtx_cost (y
, COMPARE
, 1, optimize_insn_for_speed_p ())
4079 > COSTS_N_INSNS (1)))
4080 y
= force_reg (mode
, y
);
4083 /* Make sure if we have a canonical comparison. The RTL
4084 documentation states that canonical comparisons are required only
4085 for targets which have cc0. */
4086 gcc_assert (!CONSTANT_P (x
) || CONSTANT_P (y
));
4089 /* Don't let both operands fail to indicate the mode. */
4090 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
4091 x
= force_reg (mode
, x
);
4092 if (mode
== VOIDmode
)
4093 mode
= GET_MODE (x
) != VOIDmode
? GET_MODE (x
) : GET_MODE (y
);
4095 /* Handle all BLKmode compares. */
4097 if (mode
== BLKmode
)
4099 machine_mode result_mode
;
4100 enum insn_code cmp_code
;
4105 = GEN_INT (MIN (MEM_ALIGN (x
), MEM_ALIGN (y
)) / BITS_PER_UNIT
);
4109 /* Try to use a memory block compare insn - either cmpstr
4110 or cmpmem will do. */
4111 for (cmp_mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
4112 cmp_mode
!= VOIDmode
;
4113 cmp_mode
= GET_MODE_WIDER_MODE (cmp_mode
))
4115 cmp_code
= direct_optab_handler (cmpmem_optab
, cmp_mode
);
4116 if (cmp_code
== CODE_FOR_nothing
)
4117 cmp_code
= direct_optab_handler (cmpstr_optab
, cmp_mode
);
4118 if (cmp_code
== CODE_FOR_nothing
)
4119 cmp_code
= direct_optab_handler (cmpstrn_optab
, cmp_mode
);
4120 if (cmp_code
== CODE_FOR_nothing
)
4123 /* Must make sure the size fits the insn's mode. */
4124 if ((CONST_INT_P (size
)
4125 && INTVAL (size
) >= (1 << GET_MODE_BITSIZE (cmp_mode
)))
4126 || (GET_MODE_BITSIZE (GET_MODE (size
))
4127 > GET_MODE_BITSIZE (cmp_mode
)))
4130 result_mode
= insn_data
[cmp_code
].operand
[0].mode
;
4131 result
= gen_reg_rtx (result_mode
);
4132 size
= convert_to_mode (cmp_mode
, size
, 1);
4133 emit_insn (GEN_FCN (cmp_code
) (result
, x
, y
, size
, opalign
));
4135 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, result
, const0_rtx
);
4136 *pmode
= result_mode
;
4140 if (methods
!= OPTAB_LIB
&& methods
!= OPTAB_LIB_WIDEN
)
4143 /* Otherwise call a library function, memcmp. */
4144 libfunc
= memcmp_libfunc
;
4145 length_type
= sizetype
;
4146 result_mode
= TYPE_MODE (integer_type_node
);
4147 cmp_mode
= TYPE_MODE (length_type
);
4148 size
= convert_to_mode (TYPE_MODE (length_type
), size
,
4149 TYPE_UNSIGNED (length_type
));
4151 result
= emit_library_call_value (libfunc
, 0, LCT_PURE
,
4159 methods
= OPTAB_LIB_WIDEN
;
4163 /* Don't allow operands to the compare to trap, as that can put the
4164 compare and branch in different basic blocks. */
4165 if (cfun
->can_throw_non_call_exceptions
)
4168 x
= force_reg (mode
, x
);
4170 y
= force_reg (mode
, y
);
4173 if (GET_MODE_CLASS (mode
) == MODE_CC
)
4175 enum insn_code icode
= optab_handler (cbranch_optab
, CCmode
);
4176 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
4177 gcc_assert (icode
!= CODE_FOR_nothing
4178 && insn_operand_matches (icode
, 0, test
));
4183 mclass
= GET_MODE_CLASS (mode
);
4184 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
4188 enum insn_code icode
;
4189 icode
= optab_handler (cbranch_optab
, cmp_mode
);
4190 if (icode
!= CODE_FOR_nothing
4191 && insn_operand_matches (icode
, 0, test
))
4193 rtx_insn
*last
= get_last_insn ();
4194 rtx op0
= prepare_operand (icode
, x
, 1, mode
, cmp_mode
, unsignedp
);
4195 rtx op1
= prepare_operand (icode
, y
, 2, mode
, cmp_mode
, unsignedp
);
4197 && insn_operand_matches (icode
, 1, op0
)
4198 && insn_operand_matches (icode
, 2, op1
))
4200 XEXP (test
, 0) = op0
;
4201 XEXP (test
, 1) = op1
;
4206 delete_insns_since (last
);
4209 if (methods
== OPTAB_DIRECT
|| !CLASS_HAS_WIDER_MODES_P (mclass
))
4211 cmp_mode
= GET_MODE_WIDER_MODE (cmp_mode
);
4213 while (cmp_mode
!= VOIDmode
);
4215 if (methods
!= OPTAB_LIB_WIDEN
)
4218 if (!SCALAR_FLOAT_MODE_P (mode
))
4221 machine_mode ret_mode
;
4223 /* Handle a libcall just for the mode we are using. */
4224 libfunc
= optab_libfunc (cmp_optab
, mode
);
4225 gcc_assert (libfunc
);
4227 /* If we want unsigned, and this mode has a distinct unsigned
4228 comparison routine, use that. */
4231 rtx ulibfunc
= optab_libfunc (ucmp_optab
, mode
);
4236 ret_mode
= targetm
.libgcc_cmp_return_mode ();
4237 result
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4238 ret_mode
, 2, x
, mode
, y
, mode
);
4240 /* There are two kinds of comparison routines. Biased routines
4241 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4242 of gcc expect that the comparison operation is equivalent
4243 to the modified comparison. For signed comparisons compare the
4244 result against 1 in the biased case, and zero in the unbiased
4245 case. For unsigned comparisons always compare against 1 after
4246 biasing the unbiased result by adding 1. This gives us a way to
4248 The comparisons in the fixed-point helper library are always
4253 if (!TARGET_LIB_INT_CMP_BIASED
&& !ALL_FIXED_POINT_MODE_P (mode
))
4256 x
= plus_constant (ret_mode
, result
, 1);
4262 prepare_cmp_insn (x
, y
, comparison
, NULL_RTX
, unsignedp
, methods
,
4266 prepare_float_lib_cmp (x
, y
, comparison
, ptest
, pmode
);
4274 /* Before emitting an insn with code ICODE, make sure that X, which is going
4275 to be used for operand OPNUM of the insn, is converted from mode MODE to
4276 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4277 that it is accepted by the operand predicate. Return the new value. */
4280 prepare_operand (enum insn_code icode
, rtx x
, int opnum
, machine_mode mode
,
4281 machine_mode wider_mode
, int unsignedp
)
4283 if (mode
!= wider_mode
)
4284 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
4286 if (!insn_operand_matches (icode
, opnum
, x
))
4288 machine_mode op_mode
= insn_data
[(int) icode
].operand
[opnum
].mode
;
4289 if (reload_completed
)
4291 if (GET_MODE (x
) != op_mode
&& GET_MODE (x
) != VOIDmode
)
4293 x
= copy_to_mode_reg (op_mode
, x
);
4299 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4300 we can do the branch. */
4303 emit_cmp_and_jump_insn_1 (rtx test
, machine_mode mode
, rtx label
, int prob
)
4305 machine_mode optab_mode
;
4306 enum mode_class mclass
;
4307 enum insn_code icode
;
4310 mclass
= GET_MODE_CLASS (mode
);
4311 optab_mode
= (mclass
== MODE_CC
) ? CCmode
: mode
;
4312 icode
= optab_handler (cbranch_optab
, optab_mode
);
4314 gcc_assert (icode
!= CODE_FOR_nothing
);
4315 gcc_assert (insn_operand_matches (icode
, 0, test
));
4316 insn
= emit_jump_insn (GEN_FCN (icode
) (test
, XEXP (test
, 0),
4317 XEXP (test
, 1), label
));
4319 && profile_status_for_fn (cfun
) != PROFILE_ABSENT
4322 && any_condjump_p (insn
)
4323 && !find_reg_note (insn
, REG_BR_PROB
, 0))
4324 add_int_reg_note (insn
, REG_BR_PROB
, prob
);
4327 /* Generate code to compare X with Y so that the condition codes are
4328 set and to jump to LABEL if the condition is true. If X is a
4329 constant and Y is not a constant, then the comparison is swapped to
4330 ensure that the comparison RTL has the canonical form.
4332 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4333 need to be widened. UNSIGNEDP is also used to select the proper
4334 branch condition code.
4336 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4338 MODE is the mode of the inputs (in case they are const_int).
4340 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4341 It will be potentially converted into an unsigned variant based on
4342 UNSIGNEDP to select a proper jump instruction.
4344 PROB is the probability of jumping to LABEL. */
4347 emit_cmp_and_jump_insns (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4348 machine_mode mode
, int unsignedp
, rtx label
,
4351 rtx op0
= x
, op1
= y
;
4354 /* Swap operands and condition to ensure canonical RTL. */
4355 if (swap_commutative_operands_p (x
, y
)
4356 && can_compare_p (swap_condition (comparison
), mode
, ccp_jump
))
4359 comparison
= swap_condition (comparison
);
4362 /* If OP0 is still a constant, then both X and Y must be constants
4363 or the opposite comparison is not supported. Force X into a register
4364 to create canonical RTL. */
4365 if (CONSTANT_P (op0
))
4366 op0
= force_reg (mode
, op0
);
4369 comparison
= unsigned_condition (comparison
);
4371 prepare_cmp_insn (op0
, op1
, comparison
, size
, unsignedp
, OPTAB_LIB_WIDEN
,
4373 emit_cmp_and_jump_insn_1 (test
, mode
, label
, prob
);
4377 /* Emit a library call comparison between floating point X and Y.
4378 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4381 prepare_float_lib_cmp (rtx x
, rtx y
, enum rtx_code comparison
,
4382 rtx
*ptest
, machine_mode
*pmode
)
4384 enum rtx_code swapped
= swap_condition (comparison
);
4385 enum rtx_code reversed
= reverse_condition_maybe_unordered (comparison
);
4386 machine_mode orig_mode
= GET_MODE (x
);
4387 machine_mode mode
, cmp_mode
;
4388 rtx true_rtx
, false_rtx
;
4389 rtx value
, target
, equiv
;
4392 bool reversed_p
= false;
4393 cmp_mode
= targetm
.libgcc_cmp_return_mode ();
4395 for (mode
= orig_mode
;
4397 mode
= GET_MODE_WIDER_MODE (mode
))
4399 if (code_to_optab (comparison
)
4400 && (libfunc
= optab_libfunc (code_to_optab (comparison
), mode
)))
4403 if (code_to_optab (swapped
)
4404 && (libfunc
= optab_libfunc (code_to_optab (swapped
), mode
)))
4407 tmp
= x
; x
= y
; y
= tmp
;
4408 comparison
= swapped
;
4412 if (code_to_optab (reversed
)
4413 && (libfunc
= optab_libfunc (code_to_optab (reversed
), mode
)))
4415 comparison
= reversed
;
4421 gcc_assert (mode
!= VOIDmode
);
4423 if (mode
!= orig_mode
)
4425 x
= convert_to_mode (mode
, x
, 0);
4426 y
= convert_to_mode (mode
, y
, 0);
4429 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4430 the RTL. The allows the RTL optimizers to delete the libcall if the
4431 condition can be determined at compile-time. */
4432 if (comparison
== UNORDERED
4433 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4435 true_rtx
= const_true_rtx
;
4436 false_rtx
= const0_rtx
;
4443 true_rtx
= const0_rtx
;
4444 false_rtx
= const_true_rtx
;
4448 true_rtx
= const_true_rtx
;
4449 false_rtx
= const0_rtx
;
4453 true_rtx
= const1_rtx
;
4454 false_rtx
= const0_rtx
;
4458 true_rtx
= const0_rtx
;
4459 false_rtx
= constm1_rtx
;
4463 true_rtx
= constm1_rtx
;
4464 false_rtx
= const0_rtx
;
4468 true_rtx
= const0_rtx
;
4469 false_rtx
= const1_rtx
;
4477 if (comparison
== UNORDERED
)
4479 rtx temp
= simplify_gen_relational (NE
, cmp_mode
, mode
, x
, x
);
4480 equiv
= simplify_gen_relational (NE
, cmp_mode
, mode
, y
, y
);
4481 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4482 temp
, const_true_rtx
, equiv
);
4486 equiv
= simplify_gen_relational (comparison
, cmp_mode
, mode
, x
, y
);
4487 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4488 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4489 equiv
, true_rtx
, false_rtx
);
4493 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4494 cmp_mode
, 2, x
, mode
, y
, mode
);
4495 insns
= get_insns ();
4498 target
= gen_reg_rtx (cmp_mode
);
4499 emit_libcall_block (insns
, target
, value
, equiv
);
4501 if (comparison
== UNORDERED
4502 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
)
4504 *ptest
= gen_rtx_fmt_ee (reversed_p
? EQ
: NE
, VOIDmode
, target
, false_rtx
);
4506 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, target
, const0_rtx
);
4511 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4514 emit_indirect_jump (rtx loc ATTRIBUTE_UNUSED
)
4516 #ifndef HAVE_indirect_jump
4517 sorry ("indirect jumps are not available on this target");
4519 struct expand_operand ops
[1];
4520 create_address_operand (&ops
[0], loc
);
4521 expand_jump_insn (CODE_FOR_indirect_jump
, 1, ops
);
4526 #ifdef HAVE_conditional_move
4528 /* Emit a conditional move instruction if the machine supports one for that
4529 condition and machine mode.
4531 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4532 the mode to use should they be constants. If it is VOIDmode, they cannot
4535 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4536 should be stored there. MODE is the mode to use should they be constants.
4537 If it is VOIDmode, they cannot both be constants.
4539 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4540 is not supported. */
4543 emit_conditional_move (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4544 machine_mode cmode
, rtx op2
, rtx op3
,
4545 machine_mode mode
, int unsignedp
)
4547 rtx tem
, comparison
;
4549 enum insn_code icode
;
4550 enum rtx_code reversed
;
4552 /* If one operand is constant, make it the second one. Only do this
4553 if the other operand is not constant as well. */
4555 if (swap_commutative_operands_p (op0
, op1
))
4560 code
= swap_condition (code
);
4563 /* get_condition will prefer to generate LT and GT even if the old
4564 comparison was against zero, so undo that canonicalization here since
4565 comparisons against zero are cheaper. */
4566 if (code
== LT
&& op1
== const1_rtx
)
4567 code
= LE
, op1
= const0_rtx
;
4568 else if (code
== GT
&& op1
== constm1_rtx
)
4569 code
= GE
, op1
= const0_rtx
;
4571 if (cmode
== VOIDmode
)
4572 cmode
= GET_MODE (op0
);
4574 if (swap_commutative_operands_p (op2
, op3
)
4575 && ((reversed
= reversed_comparison_code_parts (code
, op0
, op1
, NULL
))
4584 if (mode
== VOIDmode
)
4585 mode
= GET_MODE (op2
);
4587 icode
= direct_optab_handler (movcc_optab
, mode
);
4589 if (icode
== CODE_FOR_nothing
)
4593 target
= gen_reg_rtx (mode
);
4595 code
= unsignedp
? unsigned_condition (code
) : code
;
4596 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4598 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4599 return NULL and let the caller figure out how best to deal with this
4601 if (!COMPARISON_P (comparison
))
4604 saved_pending_stack_adjust save
;
4605 save_pending_stack_adjust (&save
);
4606 last
= get_last_insn ();
4607 do_pending_stack_adjust ();
4608 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4609 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4610 &comparison
, &cmode
);
4613 struct expand_operand ops
[4];
4615 create_output_operand (&ops
[0], target
, mode
);
4616 create_fixed_operand (&ops
[1], comparison
);
4617 create_input_operand (&ops
[2], op2
, mode
);
4618 create_input_operand (&ops
[3], op3
, mode
);
4619 if (maybe_expand_insn (icode
, 4, ops
))
4621 if (ops
[0].value
!= target
)
4622 convert_move (target
, ops
[0].value
, false);
4626 delete_insns_since (last
);
4627 restore_pending_stack_adjust (&save
);
4631 /* Return nonzero if a conditional move of mode MODE is supported.
4633 This function is for combine so it can tell whether an insn that looks
4634 like a conditional move is actually supported by the hardware. If we
4635 guess wrong we lose a bit on optimization, but that's it. */
4636 /* ??? sparc64 supports conditionally moving integers values based on fp
4637 comparisons, and vice versa. How do we handle them? */
4640 can_conditionally_move_p (machine_mode mode
)
4642 if (direct_optab_handler (movcc_optab
, mode
) != CODE_FOR_nothing
)
4648 #endif /* HAVE_conditional_move */
4650 /* Emit a conditional addition instruction if the machine supports one for that
4651 condition and machine mode.
4653 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4654 the mode to use should they be constants. If it is VOIDmode, they cannot
4657 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4658 should be stored there. MODE is the mode to use should they be constants.
4659 If it is VOIDmode, they cannot both be constants.
4661 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4662 is not supported. */
4665 emit_conditional_add (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4666 machine_mode cmode
, rtx op2
, rtx op3
,
4667 machine_mode mode
, int unsignedp
)
4669 rtx tem
, comparison
;
4671 enum insn_code icode
;
4673 /* If one operand is constant, make it the second one. Only do this
4674 if the other operand is not constant as well. */
4676 if (swap_commutative_operands_p (op0
, op1
))
4681 code
= swap_condition (code
);
4684 /* get_condition will prefer to generate LT and GT even if the old
4685 comparison was against zero, so undo that canonicalization here since
4686 comparisons against zero are cheaper. */
4687 if (code
== LT
&& op1
== const1_rtx
)
4688 code
= LE
, op1
= const0_rtx
;
4689 else if (code
== GT
&& op1
== constm1_rtx
)
4690 code
= GE
, op1
= const0_rtx
;
4692 if (cmode
== VOIDmode
)
4693 cmode
= GET_MODE (op0
);
4695 if (mode
== VOIDmode
)
4696 mode
= GET_MODE (op2
);
4698 icode
= optab_handler (addcc_optab
, mode
);
4700 if (icode
== CODE_FOR_nothing
)
4704 target
= gen_reg_rtx (mode
);
4706 code
= unsignedp
? unsigned_condition (code
) : code
;
4707 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4709 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4710 return NULL and let the caller figure out how best to deal with this
4712 if (!COMPARISON_P (comparison
))
4715 do_pending_stack_adjust ();
4716 last
= get_last_insn ();
4717 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4718 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4719 &comparison
, &cmode
);
4722 struct expand_operand ops
[4];
4724 create_output_operand (&ops
[0], target
, mode
);
4725 create_fixed_operand (&ops
[1], comparison
);
4726 create_input_operand (&ops
[2], op2
, mode
);
4727 create_input_operand (&ops
[3], op3
, mode
);
4728 if (maybe_expand_insn (icode
, 4, ops
))
4730 if (ops
[0].value
!= target
)
4731 convert_move (target
, ops
[0].value
, false);
4735 delete_insns_since (last
);
4739 /* These functions attempt to generate an insn body, rather than
4740 emitting the insn, but if the gen function already emits them, we
4741 make no attempt to turn them back into naked patterns. */
4743 /* Generate and return an insn body to add Y to X. */
4746 gen_add2_insn (rtx x
, rtx y
)
4748 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (x
));
4750 gcc_assert (insn_operand_matches (icode
, 0, x
));
4751 gcc_assert (insn_operand_matches (icode
, 1, x
));
4752 gcc_assert (insn_operand_matches (icode
, 2, y
));
4754 return GEN_FCN (icode
) (x
, x
, y
);
4757 /* Generate and return an insn body to add r1 and c,
4758 storing the result in r0. */
4761 gen_add3_insn (rtx r0
, rtx r1
, rtx c
)
4763 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (r0
));
4765 if (icode
== CODE_FOR_nothing
4766 || !insn_operand_matches (icode
, 0, r0
)
4767 || !insn_operand_matches (icode
, 1, r1
)
4768 || !insn_operand_matches (icode
, 2, c
))
4771 return GEN_FCN (icode
) (r0
, r1
, c
);
4775 have_add2_insn (rtx x
, rtx y
)
4777 enum insn_code icode
;
4779 gcc_assert (GET_MODE (x
) != VOIDmode
);
4781 icode
= optab_handler (add_optab
, GET_MODE (x
));
4783 if (icode
== CODE_FOR_nothing
)
4786 if (!insn_operand_matches (icode
, 0, x
)
4787 || !insn_operand_matches (icode
, 1, x
)
4788 || !insn_operand_matches (icode
, 2, y
))
4794 /* Generate and return an insn body to add Y to X. */
4797 gen_addptr3_insn (rtx x
, rtx y
, rtx z
)
4799 enum insn_code icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
4801 gcc_assert (insn_operand_matches (icode
, 0, x
));
4802 gcc_assert (insn_operand_matches (icode
, 1, y
));
4803 gcc_assert (insn_operand_matches (icode
, 2, z
));
4805 return GEN_FCN (icode
) (x
, y
, z
);
4808 /* Return true if the target implements an addptr pattern and X, Y,
4809 and Z are valid for the pattern predicates. */
4812 have_addptr3_insn (rtx x
, rtx y
, rtx z
)
4814 enum insn_code icode
;
4816 gcc_assert (GET_MODE (x
) != VOIDmode
);
4818 icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
4820 if (icode
== CODE_FOR_nothing
)
4823 if (!insn_operand_matches (icode
, 0, x
)
4824 || !insn_operand_matches (icode
, 1, y
)
4825 || !insn_operand_matches (icode
, 2, z
))
4831 /* Generate and return an insn body to subtract Y from X. */
4834 gen_sub2_insn (rtx x
, rtx y
)
4836 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (x
));
4838 gcc_assert (insn_operand_matches (icode
, 0, x
));
4839 gcc_assert (insn_operand_matches (icode
, 1, x
));
4840 gcc_assert (insn_operand_matches (icode
, 2, y
));
4842 return GEN_FCN (icode
) (x
, x
, y
);
4845 /* Generate and return an insn body to subtract r1 and c,
4846 storing the result in r0. */
4849 gen_sub3_insn (rtx r0
, rtx r1
, rtx c
)
4851 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (r0
));
4853 if (icode
== CODE_FOR_nothing
4854 || !insn_operand_matches (icode
, 0, r0
)
4855 || !insn_operand_matches (icode
, 1, r1
)
4856 || !insn_operand_matches (icode
, 2, c
))
4859 return GEN_FCN (icode
) (r0
, r1
, c
);
4863 have_sub2_insn (rtx x
, rtx y
)
4865 enum insn_code icode
;
4867 gcc_assert (GET_MODE (x
) != VOIDmode
);
4869 icode
= optab_handler (sub_optab
, GET_MODE (x
));
4871 if (icode
== CODE_FOR_nothing
)
4874 if (!insn_operand_matches (icode
, 0, x
)
4875 || !insn_operand_matches (icode
, 1, x
)
4876 || !insn_operand_matches (icode
, 2, y
))
4882 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4883 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4884 no such operation exists, CODE_FOR_nothing will be returned. */
4887 can_extend_p (machine_mode to_mode
, machine_mode from_mode
,
4891 #ifdef HAVE_ptr_extend
4893 return CODE_FOR_ptr_extend
;
4896 tab
= unsignedp
? zext_optab
: sext_optab
;
4897 return convert_optab_handler (tab
, to_mode
, from_mode
);
4900 /* Generate the body of an insn to extend Y (with mode MFROM)
4901 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4904 gen_extend_insn (rtx x
, rtx y
, machine_mode mto
,
4905 machine_mode mfrom
, int unsignedp
)
4907 enum insn_code icode
= can_extend_p (mto
, mfrom
, unsignedp
);
4908 return GEN_FCN (icode
) (x
, y
);
4911 /* can_fix_p and can_float_p say whether the target machine
4912 can directly convert a given fixed point type to
4913 a given floating point type, or vice versa.
4914 The returned value is the CODE_FOR_... value to use,
4915 or CODE_FOR_nothing if these modes cannot be directly converted.
4917 *TRUNCP_PTR is set to 1 if it is necessary to output
4918 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4920 static enum insn_code
4921 can_fix_p (machine_mode fixmode
, machine_mode fltmode
,
4922 int unsignedp
, int *truncp_ptr
)
4925 enum insn_code icode
;
4927 tab
= unsignedp
? ufixtrunc_optab
: sfixtrunc_optab
;
4928 icode
= convert_optab_handler (tab
, fixmode
, fltmode
);
4929 if (icode
!= CODE_FOR_nothing
)
4935 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4936 for this to work. We need to rework the fix* and ftrunc* patterns
4937 and documentation. */
4938 tab
= unsignedp
? ufix_optab
: sfix_optab
;
4939 icode
= convert_optab_handler (tab
, fixmode
, fltmode
);
4940 if (icode
!= CODE_FOR_nothing
4941 && optab_handler (ftrunc_optab
, fltmode
) != CODE_FOR_nothing
)
4948 return CODE_FOR_nothing
;
4952 can_float_p (machine_mode fltmode
, machine_mode fixmode
,
4957 tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
4958 return convert_optab_handler (tab
, fltmode
, fixmode
);
4961 /* Function supportable_convert_operation
4963 Check whether an operation represented by the code CODE is a
4964 convert operation that is supported by the target platform in
4965 vector form (i.e., when operating on arguments of type VECTYPE_IN
4966 producing a result of type VECTYPE_OUT).
4968 Convert operations we currently support directly are FIX_TRUNC and FLOAT.
4969 This function checks if these operations are supported
4970 by the target platform either directly (via vector tree-codes), or via
4974 - CODE1 is code of vector operation to be used when
4975 vectorizing the operation, if available.
4976 - DECL is decl of target builtin functions to be used
4977 when vectorizing the operation, if available. In this case,
4978 CODE1 is CALL_EXPR. */
4981 supportable_convert_operation (enum tree_code code
,
4982 tree vectype_out
, tree vectype_in
,
4983 tree
*decl
, enum tree_code
*code1
)
4988 m1
= TYPE_MODE (vectype_out
);
4989 m2
= TYPE_MODE (vectype_in
);
4991 /* First check if we can done conversion directly. */
4992 if ((code
== FIX_TRUNC_EXPR
4993 && can_fix_p (m1
,m2
,TYPE_UNSIGNED (vectype_out
), &truncp
)
4994 != CODE_FOR_nothing
)
4995 || (code
== FLOAT_EXPR
4996 && can_float_p (m1
,m2
,TYPE_UNSIGNED (vectype_in
))
4997 != CODE_FOR_nothing
))
5003 /* Now check for builtin. */
5004 if (targetm
.vectorize
.builtin_conversion
5005 && targetm
.vectorize
.builtin_conversion (code
, vectype_out
, vectype_in
))
5008 *decl
= targetm
.vectorize
.builtin_conversion (code
, vectype_out
, vectype_in
);
5015 /* Generate code to convert FROM to floating point
5016 and store in TO. FROM must be fixed point and not VOIDmode.
5017 UNSIGNEDP nonzero means regard FROM as unsigned.
5018 Normally this is done by correcting the final value
5019 if it is negative. */
5022 expand_float (rtx to
, rtx from
, int unsignedp
)
5024 enum insn_code icode
;
5026 machine_mode fmode
, imode
;
5027 bool can_do_signed
= false;
5029 /* Crash now, because we won't be able to decide which mode to use. */
5030 gcc_assert (GET_MODE (from
) != VOIDmode
);
5032 /* Look for an insn to do the conversion. Do it in the specified
5033 modes if possible; otherwise convert either input, output or both to
5034 wider mode. If the integer mode is wider than the mode of FROM,
5035 we can do the conversion signed even if the input is unsigned. */
5037 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
5038 fmode
= GET_MODE_WIDER_MODE (fmode
))
5039 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
5040 imode
= GET_MODE_WIDER_MODE (imode
))
5042 int doing_unsigned
= unsignedp
;
5044 if (fmode
!= GET_MODE (to
)
5045 && significand_size (fmode
) < GET_MODE_PRECISION (GET_MODE (from
)))
5048 icode
= can_float_p (fmode
, imode
, unsignedp
);
5049 if (icode
== CODE_FOR_nothing
&& unsignedp
)
5051 enum insn_code scode
= can_float_p (fmode
, imode
, 0);
5052 if (scode
!= CODE_FOR_nothing
)
5053 can_do_signed
= true;
5054 if (imode
!= GET_MODE (from
))
5055 icode
= scode
, doing_unsigned
= 0;
5058 if (icode
!= CODE_FOR_nothing
)
5060 if (imode
!= GET_MODE (from
))
5061 from
= convert_to_mode (imode
, from
, unsignedp
);
5063 if (fmode
!= GET_MODE (to
))
5064 target
= gen_reg_rtx (fmode
);
5066 emit_unop_insn (icode
, target
, from
,
5067 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
5070 convert_move (to
, target
, 0);
5075 /* Unsigned integer, and no way to convert directly. Convert as signed,
5076 then unconditionally adjust the result. */
5077 if (unsignedp
&& can_do_signed
)
5079 rtx_code_label
*label
= gen_label_rtx ();
5081 REAL_VALUE_TYPE offset
;
5083 /* Look for a usable floating mode FMODE wider than the source and at
5084 least as wide as the target. Using FMODE will avoid rounding woes
5085 with unsigned values greater than the signed maximum value. */
5087 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
5088 fmode
= GET_MODE_WIDER_MODE (fmode
))
5089 if (GET_MODE_PRECISION (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
5090 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
5093 if (fmode
== VOIDmode
)
5095 /* There is no such mode. Pretend the target is wide enough. */
5096 fmode
= GET_MODE (to
);
5098 /* Avoid double-rounding when TO is narrower than FROM. */
5099 if ((significand_size (fmode
) + 1)
5100 < GET_MODE_PRECISION (GET_MODE (from
)))
5103 rtx_code_label
*neglabel
= gen_label_rtx ();
5105 /* Don't use TARGET if it isn't a register, is a hard register,
5106 or is the wrong mode. */
5108 || REGNO (target
) < FIRST_PSEUDO_REGISTER
5109 || GET_MODE (target
) != fmode
)
5110 target
= gen_reg_rtx (fmode
);
5112 imode
= GET_MODE (from
);
5113 do_pending_stack_adjust ();
5115 /* Test whether the sign bit is set. */
5116 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
5119 /* The sign bit is not set. Convert as signed. */
5120 expand_float (target
, from
, 0);
5121 emit_jump_insn (gen_jump (label
));
5124 /* The sign bit is set.
5125 Convert to a usable (positive signed) value by shifting right
5126 one bit, while remembering if a nonzero bit was shifted
5127 out; i.e., compute (from & 1) | (from >> 1). */
5129 emit_label (neglabel
);
5130 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
5131 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5132 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, 1, NULL_RTX
, 1);
5133 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
5135 expand_float (target
, temp
, 0);
5137 /* Multiply by 2 to undo the shift above. */
5138 temp
= expand_binop (fmode
, add_optab
, target
, target
,
5139 target
, 0, OPTAB_LIB_WIDEN
);
5141 emit_move_insn (target
, temp
);
5143 do_pending_stack_adjust ();
5149 /* If we are about to do some arithmetic to correct for an
5150 unsigned operand, do it in a pseudo-register. */
5152 if (GET_MODE (to
) != fmode
5153 || !REG_P (to
) || REGNO (to
) < FIRST_PSEUDO_REGISTER
)
5154 target
= gen_reg_rtx (fmode
);
5156 /* Convert as signed integer to floating. */
5157 expand_float (target
, from
, 0);
5159 /* If FROM is negative (and therefore TO is negative),
5160 correct its value by 2**bitwidth. */
5162 do_pending_stack_adjust ();
5163 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
),
5167 real_2expN (&offset
, GET_MODE_PRECISION (GET_MODE (from
)), fmode
);
5168 temp
= expand_binop (fmode
, add_optab
, target
,
5169 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
5170 target
, 0, OPTAB_LIB_WIDEN
);
5172 emit_move_insn (target
, temp
);
5174 do_pending_stack_adjust ();
5179 /* No hardware instruction available; call a library routine. */
5184 convert_optab tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
5186 if (GET_MODE_PRECISION (GET_MODE (from
)) < GET_MODE_PRECISION (SImode
))
5187 from
= convert_to_mode (SImode
, from
, unsignedp
);
5189 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5190 gcc_assert (libfunc
);
5194 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5195 GET_MODE (to
), 1, from
,
5197 insns
= get_insns ();
5200 emit_libcall_block (insns
, target
, value
,
5201 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FLOAT
: FLOAT
,
5202 GET_MODE (to
), from
));
5207 /* Copy result to requested destination
5208 if we have been computing in a temp location. */
5212 if (GET_MODE (target
) == GET_MODE (to
))
5213 emit_move_insn (to
, target
);
5215 convert_move (to
, target
, 0);
5219 /* Generate code to convert FROM to fixed point and store in TO. FROM
5220 must be floating point. */
5223 expand_fix (rtx to
, rtx from
, int unsignedp
)
5225 enum insn_code icode
;
5227 machine_mode fmode
, imode
;
5230 /* We first try to find a pair of modes, one real and one integer, at
5231 least as wide as FROM and TO, respectively, in which we can open-code
5232 this conversion. If the integer mode is wider than the mode of TO,
5233 we can do the conversion either signed or unsigned. */
5235 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5236 fmode
= GET_MODE_WIDER_MODE (fmode
))
5237 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
5238 imode
= GET_MODE_WIDER_MODE (imode
))
5240 int doing_unsigned
= unsignedp
;
5242 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
5243 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
5244 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
5246 if (icode
!= CODE_FOR_nothing
)
5248 rtx_insn
*last
= get_last_insn ();
5249 if (fmode
!= GET_MODE (from
))
5250 from
= convert_to_mode (fmode
, from
, 0);
5254 rtx temp
= gen_reg_rtx (GET_MODE (from
));
5255 from
= expand_unop (GET_MODE (from
), ftrunc_optab
, from
,
5259 if (imode
!= GET_MODE (to
))
5260 target
= gen_reg_rtx (imode
);
5262 if (maybe_emit_unop_insn (icode
, target
, from
,
5263 doing_unsigned
? UNSIGNED_FIX
: FIX
))
5266 convert_move (to
, target
, unsignedp
);
5269 delete_insns_since (last
);
5273 /* For an unsigned conversion, there is one more way to do it.
5274 If we have a signed conversion, we generate code that compares
5275 the real value to the largest representable positive number. If if
5276 is smaller, the conversion is done normally. Otherwise, subtract
5277 one plus the highest signed number, convert, and add it back.
5279 We only need to check all real modes, since we know we didn't find
5280 anything with a wider integer mode.
5282 This code used to extend FP value into mode wider than the destination.
5283 This is needed for decimal float modes which cannot accurately
5284 represent one plus the highest signed number of the same size, but
5285 not for binary modes. Consider, for instance conversion from SFmode
5288 The hot path through the code is dealing with inputs smaller than 2^63
5289 and doing just the conversion, so there is no bits to lose.
5291 In the other path we know the value is positive in the range 2^63..2^64-1
5292 inclusive. (as for other input overflow happens and result is undefined)
5293 So we know that the most important bit set in mantissa corresponds to
5294 2^63. The subtraction of 2^63 should not generate any rounding as it
5295 simply clears out that bit. The rest is trivial. */
5297 if (unsignedp
&& GET_MODE_PRECISION (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
5298 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5299 fmode
= GET_MODE_WIDER_MODE (fmode
))
5300 if (CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0, &must_trunc
)
5301 && (!DECIMAL_FLOAT_MODE_P (fmode
)
5302 || GET_MODE_BITSIZE (fmode
) > GET_MODE_PRECISION (GET_MODE (to
))))
5305 REAL_VALUE_TYPE offset
;
5307 rtx_code_label
*lab1
, *lab2
;
5310 bitsize
= GET_MODE_PRECISION (GET_MODE (to
));
5311 real_2expN (&offset
, bitsize
- 1, fmode
);
5312 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
5313 lab1
= gen_label_rtx ();
5314 lab2
= gen_label_rtx ();
5316 if (fmode
!= GET_MODE (from
))
5317 from
= convert_to_mode (fmode
, from
, 0);
5319 /* See if we need to do the subtraction. */
5320 do_pending_stack_adjust ();
5321 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
),
5324 /* If not, do the signed "fix" and branch around fixup code. */
5325 expand_fix (to
, from
, 0);
5326 emit_jump_insn (gen_jump (lab2
));
5329 /* Otherwise, subtract 2**(N-1), convert to signed number,
5330 then add 2**(N-1). Do the addition using XOR since this
5331 will often generate better code. */
5333 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
5334 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
5335 expand_fix (to
, target
, 0);
5336 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
5338 ((HOST_WIDE_INT
) 1 << (bitsize
- 1),
5340 to
, 1, OPTAB_LIB_WIDEN
);
5343 emit_move_insn (to
, target
);
5347 if (optab_handler (mov_optab
, GET_MODE (to
)) != CODE_FOR_nothing
)
5349 /* Make a place for a REG_NOTE and add it. */
5350 insn
= emit_move_insn (to
, to
);
5351 set_dst_reg_note (insn
, REG_EQUAL
,
5352 gen_rtx_fmt_e (UNSIGNED_FIX
, GET_MODE (to
),
5360 /* We can't do it with an insn, so use a library call. But first ensure
5361 that the mode of TO is at least as wide as SImode, since those are the
5362 only library calls we know about. */
5364 if (GET_MODE_PRECISION (GET_MODE (to
)) < GET_MODE_PRECISION (SImode
))
5366 target
= gen_reg_rtx (SImode
);
5368 expand_fix (target
, from
, unsignedp
);
5376 convert_optab tab
= unsignedp
? ufix_optab
: sfix_optab
;
5377 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5378 gcc_assert (libfunc
);
5382 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5383 GET_MODE (to
), 1, from
,
5385 insns
= get_insns ();
5388 emit_libcall_block (insns
, target
, value
,
5389 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
5390 GET_MODE (to
), from
));
5395 if (GET_MODE (to
) == GET_MODE (target
))
5396 emit_move_insn (to
, target
);
5398 convert_move (to
, target
, 0);
5402 /* Generate code to convert FROM or TO a fixed-point.
5403 If UINTP is true, either TO or FROM is an unsigned integer.
5404 If SATP is true, we need to saturate the result. */
5407 expand_fixed_convert (rtx to
, rtx from
, int uintp
, int satp
)
5409 machine_mode to_mode
= GET_MODE (to
);
5410 machine_mode from_mode
= GET_MODE (from
);
5412 enum rtx_code this_code
;
5413 enum insn_code code
;
5418 if (to_mode
== from_mode
)
5420 emit_move_insn (to
, from
);
5426 tab
= satp
? satfractuns_optab
: fractuns_optab
;
5427 this_code
= satp
? UNSIGNED_SAT_FRACT
: UNSIGNED_FRACT_CONVERT
;
5431 tab
= satp
? satfract_optab
: fract_optab
;
5432 this_code
= satp
? SAT_FRACT
: FRACT_CONVERT
;
5434 code
= convert_optab_handler (tab
, to_mode
, from_mode
);
5435 if (code
!= CODE_FOR_nothing
)
5437 emit_unop_insn (code
, to
, from
, this_code
);
5441 libfunc
= convert_optab_libfunc (tab
, to_mode
, from_mode
);
5442 gcc_assert (libfunc
);
5445 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, to_mode
,
5446 1, from
, from_mode
);
5447 insns
= get_insns ();
5450 emit_libcall_block (insns
, to
, value
,
5451 gen_rtx_fmt_e (optab_to_code (tab
), to_mode
, from
));
5454 /* Generate code to convert FROM to fixed point and store in TO. FROM
5455 must be floating point, TO must be signed. Use the conversion optab
5456 TAB to do the conversion. */
5459 expand_sfix_optab (rtx to
, rtx from
, convert_optab tab
)
5461 enum insn_code icode
;
5463 machine_mode fmode
, imode
;
5465 /* We first try to find a pair of modes, one real and one integer, at
5466 least as wide as FROM and TO, respectively, in which we can open-code
5467 this conversion. If the integer mode is wider than the mode of TO,
5468 we can do the conversion either signed or unsigned. */
5470 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5471 fmode
= GET_MODE_WIDER_MODE (fmode
))
5472 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
5473 imode
= GET_MODE_WIDER_MODE (imode
))
5475 icode
= convert_optab_handler (tab
, imode
, fmode
);
5476 if (icode
!= CODE_FOR_nothing
)
5478 rtx_insn
*last
= get_last_insn ();
5479 if (fmode
!= GET_MODE (from
))
5480 from
= convert_to_mode (fmode
, from
, 0);
5482 if (imode
!= GET_MODE (to
))
5483 target
= gen_reg_rtx (imode
);
5485 if (!maybe_emit_unop_insn (icode
, target
, from
, UNKNOWN
))
5487 delete_insns_since (last
);
5491 convert_move (to
, target
, 0);
5499 /* Report whether we have an instruction to perform the operation
5500 specified by CODE on operands of mode MODE. */
5502 have_insn_for (enum rtx_code code
, machine_mode mode
)
5504 return (code_to_optab (code
)
5505 && (optab_handler (code_to_optab (code
), mode
)
5506 != CODE_FOR_nothing
));
5509 /* Initialize the libfunc fields of an entire group of entries in some
5510 optab. Each entry is set equal to a string consisting of a leading
5511 pair of underscores followed by a generic operation name followed by
5512 a mode name (downshifted to lowercase) followed by a single character
5513 representing the number of operands for the given operation (which is
5514 usually one of the characters '2', '3', or '4').
5516 OPTABLE is the table in which libfunc fields are to be initialized.
5517 OPNAME is the generic (string) name of the operation.
5518 SUFFIX is the character which specifies the number of operands for
5519 the given generic operation.
5520 MODE is the mode to generate for.
5524 gen_libfunc (optab optable
, const char *opname
, int suffix
,
5527 unsigned opname_len
= strlen (opname
);
5528 const char *mname
= GET_MODE_NAME (mode
);
5529 unsigned mname_len
= strlen (mname
);
5530 int prefix_len
= targetm
.libfunc_gnu_prefix
? 6 : 2;
5531 int len
= prefix_len
+ opname_len
+ mname_len
+ 1 + 1;
5532 char *libfunc_name
= XALLOCAVEC (char, len
);
5539 if (targetm
.libfunc_gnu_prefix
)
5546 for (q
= opname
; *q
; )
5548 for (q
= mname
; *q
; q
++)
5549 *p
++ = TOLOWER (*q
);
5553 set_optab_libfunc (optable
, mode
,
5554 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5557 /* Like gen_libfunc, but verify that integer operation is involved. */
5560 gen_int_libfunc (optab optable
, const char *opname
, char suffix
,
5563 int maxsize
= 2 * BITS_PER_WORD
;
5564 int minsize
= BITS_PER_WORD
;
5566 if (GET_MODE_CLASS (mode
) != MODE_INT
)
5568 if (maxsize
< LONG_LONG_TYPE_SIZE
)
5569 maxsize
= LONG_LONG_TYPE_SIZE
;
5570 if (minsize
> INT_TYPE_SIZE
5571 && (trapv_binoptab_p (optable
)
5572 || trapv_unoptab_p (optable
)))
5573 minsize
= INT_TYPE_SIZE
;
5574 if (GET_MODE_BITSIZE (mode
) < minsize
5575 || GET_MODE_BITSIZE (mode
) > maxsize
)
5577 gen_libfunc (optable
, opname
, suffix
, mode
);
5580 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */
5583 gen_fp_libfunc (optab optable
, const char *opname
, char suffix
,
5588 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5589 gen_libfunc (optable
, opname
, suffix
, mode
);
5590 if (DECIMAL_FLOAT_MODE_P (mode
))
5592 dec_opname
= XALLOCAVEC (char, sizeof (DECIMAL_PREFIX
) + strlen (opname
));
5593 /* For BID support, change the name to have either a bid_ or dpd_ prefix
5594 depending on the low level floating format used. */
5595 memcpy (dec_opname
, DECIMAL_PREFIX
, sizeof (DECIMAL_PREFIX
) - 1);
5596 strcpy (dec_opname
+ sizeof (DECIMAL_PREFIX
) - 1, opname
);
5597 gen_libfunc (optable
, dec_opname
, suffix
, mode
);
5601 /* Like gen_libfunc, but verify that fixed-point operation is involved. */
5604 gen_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5607 if (!ALL_FIXED_POINT_MODE_P (mode
))
5609 gen_libfunc (optable
, opname
, suffix
, mode
);
5612 /* Like gen_libfunc, but verify that signed fixed-point operation is
5616 gen_signed_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5619 if (!SIGNED_FIXED_POINT_MODE_P (mode
))
5621 gen_libfunc (optable
, opname
, suffix
, mode
);
5624 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
5628 gen_unsigned_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
5631 if (!UNSIGNED_FIXED_POINT_MODE_P (mode
))
5633 gen_libfunc (optable
, opname
, suffix
, mode
);
5636 /* Like gen_libfunc, but verify that FP or INT operation is involved. */
5639 gen_int_fp_libfunc (optab optable
, const char *name
, char suffix
,
5642 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5643 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5644 if (INTEGRAL_MODE_P (mode
))
5645 gen_int_libfunc (optable
, name
, suffix
, mode
);
5648 /* Like gen_libfunc, but verify that FP or INT operation is involved
5649 and add 'v' suffix for integer operation. */
5652 gen_intv_fp_libfunc (optab optable
, const char *name
, char suffix
,
5655 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5656 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5657 if (GET_MODE_CLASS (mode
) == MODE_INT
)
5659 int len
= strlen (name
);
5660 char *v_name
= XALLOCAVEC (char, len
+ 2);
5661 strcpy (v_name
, name
);
5663 v_name
[len
+ 1] = 0;
5664 gen_int_libfunc (optable
, v_name
, suffix
, mode
);
5668 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
5672 gen_int_fp_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5675 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5676 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5677 if (INTEGRAL_MODE_P (mode
))
5678 gen_int_libfunc (optable
, name
, suffix
, mode
);
5679 if (ALL_FIXED_POINT_MODE_P (mode
))
5680 gen_fixed_libfunc (optable
, name
, suffix
, mode
);
5683 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
5687 gen_int_fp_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5690 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5691 gen_fp_libfunc (optable
, name
, suffix
, mode
);
5692 if (INTEGRAL_MODE_P (mode
))
5693 gen_int_libfunc (optable
, name
, suffix
, mode
);
5694 if (SIGNED_FIXED_POINT_MODE_P (mode
))
5695 gen_signed_fixed_libfunc (optable
, name
, suffix
, mode
);
5698 /* Like gen_libfunc, but verify that INT or FIXED operation is
5702 gen_int_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5705 if (INTEGRAL_MODE_P (mode
))
5706 gen_int_libfunc (optable
, name
, suffix
, mode
);
5707 if (ALL_FIXED_POINT_MODE_P (mode
))
5708 gen_fixed_libfunc (optable
, name
, suffix
, mode
);
5711 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
5715 gen_int_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5718 if (INTEGRAL_MODE_P (mode
))
5719 gen_int_libfunc (optable
, name
, suffix
, mode
);
5720 if (SIGNED_FIXED_POINT_MODE_P (mode
))
5721 gen_signed_fixed_libfunc (optable
, name
, suffix
, mode
);
5724 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
5728 gen_int_unsigned_fixed_libfunc (optab optable
, const char *name
, char suffix
,
5731 if (INTEGRAL_MODE_P (mode
))
5732 gen_int_libfunc (optable
, name
, suffix
, mode
);
5733 if (UNSIGNED_FIXED_POINT_MODE_P (mode
))
5734 gen_unsigned_fixed_libfunc (optable
, name
, suffix
, mode
);
5737 /* Initialize the libfunc fields of an entire group of entries of an
5738 inter-mode-class conversion optab. The string formation rules are
5739 similar to the ones for init_libfuncs, above, but instead of having
5740 a mode name and an operand count these functions have two mode names
5741 and no operand count. */
5744 gen_interclass_conv_libfunc (convert_optab tab
,
5749 size_t opname_len
= strlen (opname
);
5750 size_t mname_len
= 0;
5752 const char *fname
, *tname
;
5754 int prefix_len
= targetm
.libfunc_gnu_prefix
? 6 : 2;
5755 char *libfunc_name
, *suffix
;
5756 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
5759 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5760 depends on which underlying decimal floating point format is used. */
5761 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
5763 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
5765 nondec_name
= XALLOCAVEC (char, prefix_len
+ opname_len
+ mname_len
+ 1 + 1);
5766 nondec_name
[0] = '_';
5767 nondec_name
[1] = '_';
5768 if (targetm
.libfunc_gnu_prefix
)
5770 nondec_name
[2] = 'g';
5771 nondec_name
[3] = 'n';
5772 nondec_name
[4] = 'u';
5773 nondec_name
[5] = '_';
5776 memcpy (&nondec_name
[prefix_len
], opname
, opname_len
);
5777 nondec_suffix
= nondec_name
+ opname_len
+ prefix_len
;
5779 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 1);
5782 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
5783 memcpy (&dec_name
[2+dec_len
], opname
, opname_len
);
5784 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
5786 fname
= GET_MODE_NAME (fmode
);
5787 tname
= GET_MODE_NAME (tmode
);
5789 if (DECIMAL_FLOAT_MODE_P (fmode
) || DECIMAL_FLOAT_MODE_P (tmode
))
5791 libfunc_name
= dec_name
;
5792 suffix
= dec_suffix
;
5796 libfunc_name
= nondec_name
;
5797 suffix
= nondec_suffix
;
5801 for (q
= fname
; *q
; p
++, q
++)
5803 for (q
= tname
; *q
; p
++, q
++)
5808 set_conv_libfunc (tab
, tmode
, fmode
,
5809 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5812 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5813 int->fp conversion. */
5816 gen_int_to_fp_conv_libfunc (convert_optab tab
,
5821 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
5823 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
5825 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5828 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
5832 gen_ufloat_conv_libfunc (convert_optab tab
,
5833 const char *opname ATTRIBUTE_UNUSED
,
5837 if (DECIMAL_FLOAT_MODE_P (tmode
))
5838 gen_int_to_fp_conv_libfunc (tab
, "floatuns", tmode
, fmode
);
5840 gen_int_to_fp_conv_libfunc (tab
, "floatun", tmode
, fmode
);
5843 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5844 fp->int conversion. */
5847 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab
,
5852 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
5854 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
)
5856 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5859 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5860 fp->int conversion with no decimal floating point involved. */
5863 gen_fp_to_int_conv_libfunc (convert_optab tab
,
5868 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
5870 if (GET_MODE_CLASS (tmode
) != MODE_INT
)
5872 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5875 /* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
5876 The string formation rules are
5877 similar to the ones for init_libfunc, above. */
5880 gen_intraclass_conv_libfunc (convert_optab tab
, const char *opname
,
5881 machine_mode tmode
, machine_mode fmode
)
5883 size_t opname_len
= strlen (opname
);
5884 size_t mname_len
= 0;
5886 const char *fname
, *tname
;
5888 int prefix_len
= targetm
.libfunc_gnu_prefix
? 6 : 2;
5889 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
5890 char *libfunc_name
, *suffix
;
5893 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5894 depends on which underlying decimal floating point format is used. */
5895 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
5897 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
5899 nondec_name
= XALLOCAVEC (char, 2 + opname_len
+ mname_len
+ 1 + 1);
5900 nondec_name
[0] = '_';
5901 nondec_name
[1] = '_';
5902 if (targetm
.libfunc_gnu_prefix
)
5904 nondec_name
[2] = 'g';
5905 nondec_name
[3] = 'n';
5906 nondec_name
[4] = 'u';
5907 nondec_name
[5] = '_';
5909 memcpy (&nondec_name
[prefix_len
], opname
, opname_len
);
5910 nondec_suffix
= nondec_name
+ opname_len
+ prefix_len
;
5912 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 1);
5915 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
5916 memcpy (&dec_name
[2 + dec_len
], opname
, opname_len
);
5917 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
5919 fname
= GET_MODE_NAME (fmode
);
5920 tname
= GET_MODE_NAME (tmode
);
5922 if (DECIMAL_FLOAT_MODE_P (fmode
) || DECIMAL_FLOAT_MODE_P (tmode
))
5924 libfunc_name
= dec_name
;
5925 suffix
= dec_suffix
;
5929 libfunc_name
= nondec_name
;
5930 suffix
= nondec_suffix
;
5934 for (q
= fname
; *q
; p
++, q
++)
5936 for (q
= tname
; *q
; p
++, q
++)
5942 set_conv_libfunc (tab
, tmode
, fmode
,
5943 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5946 /* Pick proper libcall for trunc_optab. We need to chose if we do
5947 truncation or extension and interclass or intraclass. */
5950 gen_trunc_conv_libfunc (convert_optab tab
,
5955 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
5957 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
5962 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (fmode
))
5963 || (GET_MODE_CLASS (fmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (tmode
)))
5964 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5966 if (GET_MODE_PRECISION (fmode
) <= GET_MODE_PRECISION (tmode
))
5969 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
5970 && GET_MODE_CLASS (fmode
) == MODE_FLOAT
)
5971 || (DECIMAL_FLOAT_MODE_P (fmode
) && DECIMAL_FLOAT_MODE_P (tmode
)))
5972 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5975 /* Pick proper libcall for extend_optab. We need to chose if we do
5976 truncation or extension and interclass or intraclass. */
5979 gen_extend_conv_libfunc (convert_optab tab
,
5980 const char *opname ATTRIBUTE_UNUSED
,
5984 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
5986 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
5991 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (fmode
))
5992 || (GET_MODE_CLASS (fmode
) == MODE_FLOAT
&& DECIMAL_FLOAT_MODE_P (tmode
)))
5993 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
5995 if (GET_MODE_PRECISION (fmode
) > GET_MODE_PRECISION (tmode
))
5998 if ((GET_MODE_CLASS (tmode
) == MODE_FLOAT
5999 && GET_MODE_CLASS (fmode
) == MODE_FLOAT
)
6000 || (DECIMAL_FLOAT_MODE_P (fmode
) && DECIMAL_FLOAT_MODE_P (tmode
)))
6001 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6004 /* Pick proper libcall for fract_optab. We need to chose if we do
6005 interclass or intraclass. */
6008 gen_fract_conv_libfunc (convert_optab tab
,
6015 if (!(ALL_FIXED_POINT_MODE_P (tmode
) || ALL_FIXED_POINT_MODE_P (fmode
)))
6018 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
6019 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6021 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6024 /* Pick proper libcall for fractuns_optab. */
6027 gen_fractuns_conv_libfunc (convert_optab tab
,
6034 /* One mode must be a fixed-point mode, and the other must be an integer
6036 if (!((ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
)
6037 || (ALL_FIXED_POINT_MODE_P (fmode
)
6038 && GET_MODE_CLASS (tmode
) == MODE_INT
)))
6041 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6044 /* Pick proper libcall for satfract_optab. We need to chose if we do
6045 interclass or intraclass. */
6048 gen_satfract_conv_libfunc (convert_optab tab
,
6055 /* TMODE must be a fixed-point mode. */
6056 if (!ALL_FIXED_POINT_MODE_P (tmode
))
6059 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
6060 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6062 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6065 /* Pick proper libcall for satfractuns_optab. */
6068 gen_satfractuns_conv_libfunc (convert_optab tab
,
6075 /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
6076 if (!(ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
))
6079 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
6082 /* Hashtable callbacks for libfunc_decls. */
6084 struct libfunc_decl_hasher
: ggc_hasher
<tree
>
6089 return IDENTIFIER_HASH_VALUE (DECL_NAME (entry
));
6093 equal (tree decl
, tree name
)
6095 return DECL_NAME (decl
) == name
;
6099 /* A table of previously-created libfuncs, hashed by name. */
6100 static GTY (()) hash_table
<libfunc_decl_hasher
> *libfunc_decls
;
6102 /* Build a decl for a libfunc named NAME. */
6105 build_libfunc_function (const char *name
)
6107 tree decl
= build_decl (UNKNOWN_LOCATION
, FUNCTION_DECL
,
6108 get_identifier (name
),
6109 build_function_type (integer_type_node
, NULL_TREE
));
6110 /* ??? We don't have any type information except for this is
6111 a function. Pretend this is "int foo()". */
6112 DECL_ARTIFICIAL (decl
) = 1;
6113 DECL_EXTERNAL (decl
) = 1;
6114 TREE_PUBLIC (decl
) = 1;
6115 gcc_assert (DECL_ASSEMBLER_NAME (decl
));
6117 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
6118 are the flags assigned by targetm.encode_section_info. */
6119 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl
), 0), NULL
);
6125 init_one_libfunc (const char *name
)
6130 if (libfunc_decls
== NULL
)
6131 libfunc_decls
= hash_table
<libfunc_decl_hasher
>::create_ggc (37);
6133 /* See if we have already created a libfunc decl for this function. */
6134 id
= get_identifier (name
);
6135 hash
= IDENTIFIER_HASH_VALUE (id
);
6136 tree
*slot
= libfunc_decls
->find_slot_with_hash (id
, hash
, INSERT
);
6140 /* Create a new decl, so that it can be passed to
6141 targetm.encode_section_info. */
6142 decl
= build_libfunc_function (name
);
6145 return XEXP (DECL_RTL (decl
), 0);
6148 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */
6151 set_user_assembler_libfunc (const char *name
, const char *asmspec
)
6156 id
= get_identifier (name
);
6157 hash
= IDENTIFIER_HASH_VALUE (id
);
6158 tree
*slot
= libfunc_decls
->find_slot_with_hash (id
, hash
, NO_INSERT
);
6160 decl
= (tree
) *slot
;
6161 set_user_assembler_name (decl
, asmspec
);
6162 return XEXP (DECL_RTL (decl
), 0);
6165 /* Call this to reset the function entry for one optab (OPTABLE) in mode
6166 MODE to NAME, which should be either 0 or a string constant. */
6168 set_optab_libfunc (optab op
, machine_mode mode
, const char *name
)
6171 struct libfunc_entry e
;
6172 struct libfunc_entry
**slot
;
6179 val
= init_one_libfunc (name
);
6182 slot
= libfunc_hash
->find_slot (&e
, INSERT
);
6184 *slot
= ggc_alloc
<libfunc_entry
> ();
6186 (*slot
)->mode1
= mode
;
6187 (*slot
)->mode2
= VOIDmode
;
6188 (*slot
)->libfunc
= val
;
6191 /* Call this to reset the function entry for one conversion optab
6192 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
6193 either 0 or a string constant. */
6195 set_conv_libfunc (convert_optab optab
, machine_mode tmode
,
6196 machine_mode fmode
, const char *name
)
6199 struct libfunc_entry e
;
6200 struct libfunc_entry
**slot
;
6207 val
= init_one_libfunc (name
);
6210 slot
= libfunc_hash
->find_slot (&e
, INSERT
);
6212 *slot
= ggc_alloc
<libfunc_entry
> ();
6213 (*slot
)->op
= optab
;
6214 (*slot
)->mode1
= tmode
;
6215 (*slot
)->mode2
= fmode
;
6216 (*slot
)->libfunc
= val
;
6219 /* Call this to initialize the contents of the optabs
6220 appropriately for the current target machine. */
6226 libfunc_hash
->empty ();
6228 libfunc_hash
= hash_table
<libfunc_hasher
>::create_ggc (10);
6230 /* Fill in the optabs with the insns we support. */
6231 init_all_optabs (this_fn_optabs
);
6233 /* The ffs function operates on `int'. Fall back on it if we do not
6234 have a libgcc2 function for that width. */
6235 if (INT_TYPE_SIZE
< BITS_PER_WORD
)
6236 set_optab_libfunc (ffs_optab
, mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0),
6239 /* Explicitly initialize the bswap libfuncs since we need them to be
6240 valid for things other than word_mode. */
6241 if (targetm
.libfunc_gnu_prefix
)
6243 set_optab_libfunc (bswap_optab
, SImode
, "__gnu_bswapsi2");
6244 set_optab_libfunc (bswap_optab
, DImode
, "__gnu_bswapdi2");
6248 set_optab_libfunc (bswap_optab
, SImode
, "__bswapsi2");
6249 set_optab_libfunc (bswap_optab
, DImode
, "__bswapdi2");
6252 /* Use cabs for double complex abs, since systems generally have cabs.
6253 Don't define any libcall for float complex, so that cabs will be used. */
6254 if (complex_double_type_node
)
6255 set_optab_libfunc (abs_optab
, TYPE_MODE (complex_double_type_node
),
6258 abort_libfunc
= init_one_libfunc ("abort");
6259 memcpy_libfunc
= init_one_libfunc ("memcpy");
6260 memmove_libfunc
= init_one_libfunc ("memmove");
6261 memcmp_libfunc
= init_one_libfunc ("memcmp");
6262 memset_libfunc
= init_one_libfunc ("memset");
6263 setbits_libfunc
= init_one_libfunc ("__setbits");
6265 #ifndef DONT_USE_BUILTIN_SETJMP
6266 setjmp_libfunc
= init_one_libfunc ("__builtin_setjmp");
6267 longjmp_libfunc
= init_one_libfunc ("__builtin_longjmp");
6269 setjmp_libfunc
= init_one_libfunc ("setjmp");
6270 longjmp_libfunc
= init_one_libfunc ("longjmp");
6272 unwind_sjlj_register_libfunc
= init_one_libfunc ("_Unwind_SjLj_Register");
6273 unwind_sjlj_unregister_libfunc
6274 = init_one_libfunc ("_Unwind_SjLj_Unregister");
6276 /* For function entry/exit instrumentation. */
6277 profile_function_entry_libfunc
6278 = init_one_libfunc ("__cyg_profile_func_enter");
6279 profile_function_exit_libfunc
6280 = init_one_libfunc ("__cyg_profile_func_exit");
6282 gcov_flush_libfunc
= init_one_libfunc ("__gcov_flush");
6284 /* Allow the target to add more libcalls or rename some, etc. */
6285 targetm
.init_libfuncs ();
6288 /* Use the current target and options to initialize
6289 TREE_OPTIMIZATION_OPTABS (OPTNODE). */
6292 init_tree_optimization_optabs (tree optnode
)
6294 /* Quick exit if we have already computed optabs for this target. */
6295 if (TREE_OPTIMIZATION_BASE_OPTABS (optnode
) == this_target_optabs
)
6298 /* Forget any previous information and set up for the current target. */
6299 TREE_OPTIMIZATION_BASE_OPTABS (optnode
) = this_target_optabs
;
6300 struct target_optabs
*tmp_optabs
= (struct target_optabs
*)
6301 TREE_OPTIMIZATION_OPTABS (optnode
);
6303 memset (tmp_optabs
, 0, sizeof (struct target_optabs
));
6305 tmp_optabs
= ggc_alloc
<target_optabs
> ();
6307 /* Generate a new set of optabs into tmp_optabs. */
6308 init_all_optabs (tmp_optabs
);
6310 /* If the optabs changed, record it. */
6311 if (memcmp (tmp_optabs
, this_target_optabs
, sizeof (struct target_optabs
)))
6312 TREE_OPTIMIZATION_OPTABS (optnode
) = tmp_optabs
;
6315 TREE_OPTIMIZATION_OPTABS (optnode
) = NULL
;
6316 ggc_free (tmp_optabs
);
6320 /* A helper function for init_sync_libfuncs. Using the basename BASE,
6321 install libfuncs into TAB for BASE_N for 1 <= N <= MAX. */
6324 init_sync_libfuncs_1 (optab tab
, const char *base
, int max
)
6328 size_t len
= strlen (base
);
6331 gcc_assert (max
<= 8);
6332 gcc_assert (len
+ 3 < sizeof (buf
));
6334 memcpy (buf
, base
, len
);
6337 buf
[len
+ 2] = '\0';
6340 for (i
= 1; i
<= max
; i
*= 2)
6342 buf
[len
+ 1] = '0' + i
;
6343 set_optab_libfunc (tab
, mode
, buf
);
6344 mode
= GET_MODE_2XWIDER_MODE (mode
);
6349 init_sync_libfuncs (int max
)
6351 if (!flag_sync_libcalls
)
6354 init_sync_libfuncs_1 (sync_compare_and_swap_optab
,
6355 "__sync_val_compare_and_swap", max
);
6356 init_sync_libfuncs_1 (sync_lock_test_and_set_optab
,
6357 "__sync_lock_test_and_set", max
);
6359 init_sync_libfuncs_1 (sync_old_add_optab
, "__sync_fetch_and_add", max
);
6360 init_sync_libfuncs_1 (sync_old_sub_optab
, "__sync_fetch_and_sub", max
);
6361 init_sync_libfuncs_1 (sync_old_ior_optab
, "__sync_fetch_and_or", max
);
6362 init_sync_libfuncs_1 (sync_old_and_optab
, "__sync_fetch_and_and", max
);
6363 init_sync_libfuncs_1 (sync_old_xor_optab
, "__sync_fetch_and_xor", max
);
6364 init_sync_libfuncs_1 (sync_old_nand_optab
, "__sync_fetch_and_nand", max
);
6366 init_sync_libfuncs_1 (sync_new_add_optab
, "__sync_add_and_fetch", max
);
6367 init_sync_libfuncs_1 (sync_new_sub_optab
, "__sync_sub_and_fetch", max
);
6368 init_sync_libfuncs_1 (sync_new_ior_optab
, "__sync_or_and_fetch", max
);
6369 init_sync_libfuncs_1 (sync_new_and_optab
, "__sync_and_and_fetch", max
);
6370 init_sync_libfuncs_1 (sync_new_xor_optab
, "__sync_xor_and_fetch", max
);
6371 init_sync_libfuncs_1 (sync_new_nand_optab
, "__sync_nand_and_fetch", max
);
6374 /* Print information about the current contents of the optabs on
6378 debug_optab_libfuncs (void)
6382 /* Dump the arithmetic optabs. */
6383 for (i
= FIRST_NORM_OPTAB
; i
<= LAST_NORMLIB_OPTAB
; ++i
)
6384 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
6386 rtx l
= optab_libfunc ((optab
) i
, (machine_mode
) j
);
6389 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
6390 fprintf (stderr
, "%s\t%s:\t%s\n",
6391 GET_RTX_NAME (optab_to_code ((optab
) i
)),
6397 /* Dump the conversion optabs. */
6398 for (i
= FIRST_CONV_OPTAB
; i
<= LAST_CONVLIB_OPTAB
; ++i
)
6399 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
6400 for (k
= 0; k
< NUM_MACHINE_MODES
; ++k
)
6402 rtx l
= convert_optab_libfunc ((optab
) i
, (machine_mode
) j
,
6406 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
6407 fprintf (stderr
, "%s\t%s\t%s:\t%s\n",
6408 GET_RTX_NAME (optab_to_code ((optab
) i
)),
6417 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6418 CODE. Return 0 on failure. */
6421 gen_cond_trap (enum rtx_code code
, rtx op1
, rtx op2
, rtx tcode
)
6423 machine_mode mode
= GET_MODE (op1
);
6424 enum insn_code icode
;
6428 if (mode
== VOIDmode
)
6431 icode
= optab_handler (ctrap_optab
, mode
);
6432 if (icode
== CODE_FOR_nothing
)
6435 /* Some targets only accept a zero trap code. */
6436 if (!insn_operand_matches (icode
, 3, tcode
))
6439 do_pending_stack_adjust ();
6441 prepare_cmp_insn (op1
, op2
, code
, NULL_RTX
, false, OPTAB_DIRECT
,
6446 insn
= GEN_FCN (icode
) (trap_rtx
, XEXP (trap_rtx
, 0), XEXP (trap_rtx
, 1),
6449 /* If that failed, then give up. */
6457 insn
= get_insns ();
6462 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6463 or unsigned operation code. */
6466 get_rtx_code (enum tree_code tcode
, bool unsignedp
)
6478 code
= unsignedp
? LTU
: LT
;
6481 code
= unsignedp
? LEU
: LE
;
6484 code
= unsignedp
? GTU
: GT
;
6487 code
= unsignedp
? GEU
: GE
;
6490 case UNORDERED_EXPR
:
6529 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6530 unsigned operators. Do not generate compare instruction. */
6533 vector_compare_rtx (enum tree_code tcode
, tree t_op0
, tree t_op1
,
6534 bool unsignedp
, enum insn_code icode
)
6536 struct expand_operand ops
[2];
6537 rtx rtx_op0
, rtx_op1
;
6538 enum rtx_code rcode
= get_rtx_code (tcode
, unsignedp
);
6540 gcc_assert (TREE_CODE_CLASS (tcode
) == tcc_comparison
);
6542 /* Expand operands. */
6543 rtx_op0
= expand_expr (t_op0
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op0
)),
6545 rtx_op1
= expand_expr (t_op1
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op1
)),
6548 create_input_operand (&ops
[0], rtx_op0
, GET_MODE (rtx_op0
));
6549 create_input_operand (&ops
[1], rtx_op1
, GET_MODE (rtx_op1
));
6550 if (!maybe_legitimize_operands (icode
, 4, 2, ops
))
6552 return gen_rtx_fmt_ee (rcode
, VOIDmode
, ops
[0].value
, ops
[1].value
);
6555 /* Return true if VEC_PERM_EXPR of arbitrary input vectors can be expanded using
6556 SIMD extensions of the CPU. SEL may be NULL, which stands for an unknown
6557 constant. Note that additional permutations representing whole-vector shifts
6558 may also be handled via the vec_shr optab, but only where the second input
6559 vector is entirely constant zeroes; this case is not dealt with here. */
6562 can_vec_perm_p (machine_mode mode
, bool variable
,
6563 const unsigned char *sel
)
6565 machine_mode qimode
;
6567 /* If the target doesn't implement a vector mode for the vector type,
6568 then no operations are supported. */
6569 if (!VECTOR_MODE_P (mode
))
6574 if (direct_optab_handler (vec_perm_const_optab
, mode
) != CODE_FOR_nothing
6576 || targetm
.vectorize
.vec_perm_const_ok
== NULL
6577 || targetm
.vectorize
.vec_perm_const_ok (mode
, sel
)))
6581 if (direct_optab_handler (vec_perm_optab
, mode
) != CODE_FOR_nothing
)
6584 /* We allow fallback to a QI vector mode, and adjust the mask. */
6585 if (GET_MODE_INNER (mode
) == QImode
)
6587 qimode
= mode_for_vector (QImode
, GET_MODE_SIZE (mode
));
6588 if (!VECTOR_MODE_P (qimode
))
6591 /* ??? For completeness, we ought to check the QImode version of
6592 vec_perm_const_optab. But all users of this implicit lowering
6593 feature implement the variable vec_perm_optab. */
6594 if (direct_optab_handler (vec_perm_optab
, qimode
) == CODE_FOR_nothing
)
6597 /* In order to support the lowering of variable permutations,
6598 we need to support shifts and adds. */
6601 if (GET_MODE_UNIT_SIZE (mode
) > 2
6602 && optab_handler (ashl_optab
, mode
) == CODE_FOR_nothing
6603 && optab_handler (vashl_optab
, mode
) == CODE_FOR_nothing
)
6605 if (optab_handler (add_optab
, qimode
) == CODE_FOR_nothing
)
6612 /* Checks if vec_perm mask SEL is a constant equivalent to a shift of the first
6613 vec_perm operand, assuming the second operand is a constant vector of zeroes.
6614 Return the shift distance in bits if so, or NULL_RTX if the vec_perm is not a
6617 shift_amt_for_vec_perm_mask (rtx sel
)
6619 unsigned int i
, first
, nelt
= GET_MODE_NUNITS (GET_MODE (sel
));
6620 unsigned int bitsize
= GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (sel
)));
6622 if (GET_CODE (sel
) != CONST_VECTOR
)
6625 first
= INTVAL (CONST_VECTOR_ELT (sel
, 0));
6626 if (first
>= 2*nelt
)
6628 for (i
= 1; i
< nelt
; i
++)
6630 int idx
= INTVAL (CONST_VECTOR_ELT (sel
, i
));
6631 unsigned int expected
= (i
+ first
) & (2 * nelt
- 1);
6632 /* Indices into the second vector are all equivalent. */
6633 if (idx
< 0 || (MIN (nelt
, (unsigned) idx
) != MIN (nelt
, expected
)))
6637 return GEN_INT (first
* bitsize
);
6640 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
6643 expand_vec_perm_1 (enum insn_code icode
, rtx target
,
6644 rtx v0
, rtx v1
, rtx sel
)
6646 machine_mode tmode
= GET_MODE (target
);
6647 machine_mode smode
= GET_MODE (sel
);
6648 struct expand_operand ops
[4];
6650 create_output_operand (&ops
[0], target
, tmode
);
6651 create_input_operand (&ops
[3], sel
, smode
);
6653 /* Make an effort to preserve v0 == v1. The target expander is able to
6654 rely on this to determine if we're permuting a single input operand. */
6655 if (rtx_equal_p (v0
, v1
))
6657 if (!insn_operand_matches (icode
, 1, v0
))
6658 v0
= force_reg (tmode
, v0
);
6659 gcc_checking_assert (insn_operand_matches (icode
, 1, v0
));
6660 gcc_checking_assert (insn_operand_matches (icode
, 2, v0
));
6662 create_fixed_operand (&ops
[1], v0
);
6663 create_fixed_operand (&ops
[2], v0
);
6667 create_input_operand (&ops
[1], v0
, tmode
);
6668 /* See if this can be handled with a vec_shr. We only do this if the
6669 second vector is all zeroes. */
6670 enum insn_code shift_code
= optab_handler (vec_shr_optab
, GET_MODE (v0
));
6671 if (v1
== CONST0_RTX (GET_MODE (v1
)) && shift_code
)
6672 if (rtx shift_amt
= shift_amt_for_vec_perm_mask (sel
))
6674 create_convert_operand_from_type (&ops
[2], shift_amt
,
6675 sizetype_tab
[(int) stk_sizetype
]);
6676 if (maybe_expand_insn (shift_code
, 3, ops
))
6677 return ops
[0].value
;
6679 create_input_operand (&ops
[2], v1
, tmode
);
6682 if (maybe_expand_insn (icode
, 4, ops
))
6683 return ops
[0].value
;
6687 /* Generate instructions for vec_perm optab given its mode
6688 and three operands. */
6691 expand_vec_perm (machine_mode mode
, rtx v0
, rtx v1
, rtx sel
, rtx target
)
6693 enum insn_code icode
;
6694 machine_mode qimode
;
6695 unsigned int i
, w
, e
, u
;
6696 rtx tmp
, sel_qi
= NULL
;
6699 if (!target
|| GET_MODE (target
) != mode
)
6700 target
= gen_reg_rtx (mode
);
6702 w
= GET_MODE_SIZE (mode
);
6703 e
= GET_MODE_NUNITS (mode
);
6704 u
= GET_MODE_UNIT_SIZE (mode
);
6706 /* Set QIMODE to a different vector mode with byte elements.
6707 If no such mode, or if MODE already has byte elements, use VOIDmode. */
6709 if (GET_MODE_INNER (mode
) != QImode
)
6711 qimode
= mode_for_vector (QImode
, w
);
6712 if (!VECTOR_MODE_P (qimode
))
6716 /* If the input is a constant, expand it specially. */
6717 gcc_assert (GET_MODE_CLASS (GET_MODE (sel
)) == MODE_VECTOR_INT
);
6718 if (GET_CODE (sel
) == CONST_VECTOR
)
6720 icode
= direct_optab_handler (vec_perm_const_optab
, mode
);
6721 if (icode
!= CODE_FOR_nothing
)
6723 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
6728 /* Fall back to a constant byte-based permutation. */
6729 if (qimode
!= VOIDmode
)
6731 vec
= rtvec_alloc (w
);
6732 for (i
= 0; i
< e
; ++i
)
6734 unsigned int j
, this_e
;
6736 this_e
= INTVAL (CONST_VECTOR_ELT (sel
, i
));
6737 this_e
&= 2 * e
- 1;
6740 for (j
= 0; j
< u
; ++j
)
6741 RTVEC_ELT (vec
, i
* u
+ j
) = GEN_INT (this_e
+ j
);
6743 sel_qi
= gen_rtx_CONST_VECTOR (qimode
, vec
);
6745 icode
= direct_optab_handler (vec_perm_const_optab
, qimode
);
6746 if (icode
!= CODE_FOR_nothing
)
6748 tmp
= mode
!= qimode
? gen_reg_rtx (qimode
) : target
;
6749 tmp
= expand_vec_perm_1 (icode
, tmp
, gen_lowpart (qimode
, v0
),
6750 gen_lowpart (qimode
, v1
), sel_qi
);
6752 return gen_lowpart (mode
, tmp
);
6757 /* Otherwise expand as a fully variable permuation. */
6758 icode
= direct_optab_handler (vec_perm_optab
, mode
);
6759 if (icode
!= CODE_FOR_nothing
)
6761 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
6766 /* As a special case to aid several targets, lower the element-based
6767 permutation to a byte-based permutation and try again. */
6768 if (qimode
== VOIDmode
)
6770 icode
= direct_optab_handler (vec_perm_optab
, qimode
);
6771 if (icode
== CODE_FOR_nothing
)
6776 /* Multiply each element by its byte size. */
6777 machine_mode selmode
= GET_MODE (sel
);
6779 sel
= expand_simple_binop (selmode
, PLUS
, sel
, sel
,
6780 sel
, 0, OPTAB_DIRECT
);
6782 sel
= expand_simple_binop (selmode
, ASHIFT
, sel
,
6783 GEN_INT (exact_log2 (u
)),
6784 sel
, 0, OPTAB_DIRECT
);
6785 gcc_assert (sel
!= NULL
);
6787 /* Broadcast the low byte each element into each of its bytes. */
6788 vec
= rtvec_alloc (w
);
6789 for (i
= 0; i
< w
; ++i
)
6791 int this_e
= i
/ u
* u
;
6792 if (BYTES_BIG_ENDIAN
)
6794 RTVEC_ELT (vec
, i
) = GEN_INT (this_e
);
6796 tmp
= gen_rtx_CONST_VECTOR (qimode
, vec
);
6797 sel
= gen_lowpart (qimode
, sel
);
6798 sel
= expand_vec_perm (qimode
, sel
, sel
, tmp
, NULL
);
6799 gcc_assert (sel
!= NULL
);
6801 /* Add the byte offset to each byte element. */
6802 /* Note that the definition of the indicies here is memory ordering,
6803 so there should be no difference between big and little endian. */
6804 vec
= rtvec_alloc (w
);
6805 for (i
= 0; i
< w
; ++i
)
6806 RTVEC_ELT (vec
, i
) = GEN_INT (i
% u
);
6807 tmp
= gen_rtx_CONST_VECTOR (qimode
, vec
);
6808 sel_qi
= expand_simple_binop (qimode
, PLUS
, sel
, tmp
,
6809 sel
, 0, OPTAB_DIRECT
);
6810 gcc_assert (sel_qi
!= NULL
);
6813 tmp
= mode
!= qimode
? gen_reg_rtx (qimode
) : target
;
6814 tmp
= expand_vec_perm_1 (icode
, tmp
, gen_lowpart (qimode
, v0
),
6815 gen_lowpart (qimode
, v1
), sel_qi
);
6817 tmp
= gen_lowpart (mode
, tmp
);
6821 /* Return insn code for a conditional operator with a comparison in
6822 mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE. */
6824 static inline enum insn_code
6825 get_vcond_icode (machine_mode vmode
, machine_mode cmode
, bool uns
)
6827 enum insn_code icode
= CODE_FOR_nothing
;
6829 icode
= convert_optab_handler (vcondu_optab
, vmode
, cmode
);
6831 icode
= convert_optab_handler (vcond_optab
, vmode
, cmode
);
6835 /* Return TRUE iff, appropriate vector insns are available
6836 for vector cond expr with vector type VALUE_TYPE and a comparison
6837 with operand vector types in CMP_OP_TYPE. */
6840 expand_vec_cond_expr_p (tree value_type
, tree cmp_op_type
)
6842 machine_mode value_mode
= TYPE_MODE (value_type
);
6843 machine_mode cmp_op_mode
= TYPE_MODE (cmp_op_type
);
6844 if (GET_MODE_SIZE (value_mode
) != GET_MODE_SIZE (cmp_op_mode
)
6845 || GET_MODE_NUNITS (value_mode
) != GET_MODE_NUNITS (cmp_op_mode
)
6846 || get_vcond_icode (TYPE_MODE (value_type
), TYPE_MODE (cmp_op_type
),
6847 TYPE_UNSIGNED (cmp_op_type
)) == CODE_FOR_nothing
)
6852 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
6856 expand_vec_cond_expr (tree vec_cond_type
, tree op0
, tree op1
, tree op2
,
6859 struct expand_operand ops
[6];
6860 enum insn_code icode
;
6861 rtx comparison
, rtx_op1
, rtx_op2
;
6862 machine_mode mode
= TYPE_MODE (vec_cond_type
);
6863 machine_mode cmp_op_mode
;
6866 enum tree_code tcode
;
6868 if (COMPARISON_CLASS_P (op0
))
6870 op0a
= TREE_OPERAND (op0
, 0);
6871 op0b
= TREE_OPERAND (op0
, 1);
6872 tcode
= TREE_CODE (op0
);
6877 gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (op0
)));
6879 op0b
= build_zero_cst (TREE_TYPE (op0
));
6882 unsignedp
= TYPE_UNSIGNED (TREE_TYPE (op0a
));
6883 cmp_op_mode
= TYPE_MODE (TREE_TYPE (op0a
));
6886 gcc_assert (GET_MODE_SIZE (mode
) == GET_MODE_SIZE (cmp_op_mode
)
6887 && GET_MODE_NUNITS (mode
) == GET_MODE_NUNITS (cmp_op_mode
));
6889 icode
= get_vcond_icode (mode
, cmp_op_mode
, unsignedp
);
6890 if (icode
== CODE_FOR_nothing
)
6893 comparison
= vector_compare_rtx (tcode
, op0a
, op0b
, unsignedp
, icode
);
6894 rtx_op1
= expand_normal (op1
);
6895 rtx_op2
= expand_normal (op2
);
6897 create_output_operand (&ops
[0], target
, mode
);
6898 create_input_operand (&ops
[1], rtx_op1
, mode
);
6899 create_input_operand (&ops
[2], rtx_op2
, mode
);
6900 create_fixed_operand (&ops
[3], comparison
);
6901 create_fixed_operand (&ops
[4], XEXP (comparison
, 0));
6902 create_fixed_operand (&ops
[5], XEXP (comparison
, 1));
6903 expand_insn (icode
, 6, ops
);
6904 return ops
[0].value
;
6907 /* Return non-zero if a highpart multiply is supported of can be synthisized.
6908 For the benefit of expand_mult_highpart, the return value is 1 for direct,
6909 2 for even/odd widening, and 3 for hi/lo widening. */
6912 can_mult_highpart_p (machine_mode mode
, bool uns_p
)
6918 op
= uns_p
? umul_highpart_optab
: smul_highpart_optab
;
6919 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6922 /* If the mode is an integral vector, synth from widening operations. */
6923 if (GET_MODE_CLASS (mode
) != MODE_VECTOR_INT
)
6926 nunits
= GET_MODE_NUNITS (mode
);
6927 sel
= XALLOCAVEC (unsigned char, nunits
);
6929 op
= uns_p
? vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
6930 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6932 op
= uns_p
? vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
6933 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6935 for (i
= 0; i
< nunits
; ++i
)
6936 sel
[i
] = !BYTES_BIG_ENDIAN
+ (i
& ~1) + ((i
& 1) ? nunits
: 0);
6937 if (can_vec_perm_p (mode
, false, sel
))
6942 op
= uns_p
? vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
6943 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6945 op
= uns_p
? vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
6946 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
6948 for (i
= 0; i
< nunits
; ++i
)
6949 sel
[i
] = 2 * i
+ (BYTES_BIG_ENDIAN
? 0 : 1);
6950 if (can_vec_perm_p (mode
, false, sel
))
6958 /* Expand a highpart multiply. */
6961 expand_mult_highpart (machine_mode mode
, rtx op0
, rtx op1
,
6962 rtx target
, bool uns_p
)
6964 struct expand_operand eops
[3];
6965 enum insn_code icode
;
6966 int method
, i
, nunits
;
6972 method
= can_mult_highpart_p (mode
, uns_p
);
6978 tab1
= uns_p
? umul_highpart_optab
: smul_highpart_optab
;
6979 return expand_binop (mode
, tab1
, op0
, op1
, target
, uns_p
,
6982 tab1
= uns_p
? vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
6983 tab2
= uns_p
? vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
6986 tab1
= uns_p
? vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
6987 tab2
= uns_p
? vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
6988 if (BYTES_BIG_ENDIAN
)
6999 icode
= optab_handler (tab1
, mode
);
7000 nunits
= GET_MODE_NUNITS (mode
);
7001 wmode
= insn_data
[icode
].operand
[0].mode
;
7002 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode
) == nunits
);
7003 gcc_checking_assert (GET_MODE_SIZE (wmode
) == GET_MODE_SIZE (mode
));
7005 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
7006 create_input_operand (&eops
[1], op0
, mode
);
7007 create_input_operand (&eops
[2], op1
, mode
);
7008 expand_insn (icode
, 3, eops
);
7009 m1
= gen_lowpart (mode
, eops
[0].value
);
7011 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
7012 create_input_operand (&eops
[1], op0
, mode
);
7013 create_input_operand (&eops
[2], op1
, mode
);
7014 expand_insn (optab_handler (tab2
, mode
), 3, eops
);
7015 m2
= gen_lowpart (mode
, eops
[0].value
);
7017 v
= rtvec_alloc (nunits
);
7020 for (i
= 0; i
< nunits
; ++i
)
7021 RTVEC_ELT (v
, i
) = GEN_INT (!BYTES_BIG_ENDIAN
+ (i
& ~1)
7022 + ((i
& 1) ? nunits
: 0));
7026 for (i
= 0; i
< nunits
; ++i
)
7027 RTVEC_ELT (v
, i
) = GEN_INT (2 * i
+ (BYTES_BIG_ENDIAN
? 0 : 1));
7029 perm
= gen_rtx_CONST_VECTOR (mode
, v
);
7031 return expand_vec_perm (mode
, m1
, m2
, perm
, target
);
7034 /* Return true if target supports vector masked load/store for mode. */
7036 can_vec_mask_load_store_p (machine_mode mode
, bool is_load
)
7038 optab op
= is_load
? maskload_optab
: maskstore_optab
;
7040 unsigned int vector_sizes
;
7042 /* If mode is vector mode, check it directly. */
7043 if (VECTOR_MODE_P (mode
))
7044 return optab_handler (op
, mode
) != CODE_FOR_nothing
;
7046 /* Otherwise, return true if there is some vector mode with
7047 the mask load/store supported. */
7049 /* See if there is any chance the mask load or store might be
7050 vectorized. If not, punt. */
7051 vmode
= targetm
.vectorize
.preferred_simd_mode (mode
);
7052 if (!VECTOR_MODE_P (vmode
))
7055 if (optab_handler (op
, vmode
) != CODE_FOR_nothing
)
7058 vector_sizes
= targetm
.vectorize
.autovectorize_vector_sizes ();
7059 while (vector_sizes
!= 0)
7061 unsigned int cur
= 1 << floor_log2 (vector_sizes
);
7062 vector_sizes
&= ~cur
;
7063 if (cur
<= GET_MODE_SIZE (mode
))
7065 vmode
= mode_for_vector (mode
, cur
/ GET_MODE_SIZE (mode
));
7066 if (VECTOR_MODE_P (vmode
)
7067 && optab_handler (op
, vmode
) != CODE_FOR_nothing
)
7073 /* Return true if there is a compare_and_swap pattern. */
7076 can_compare_and_swap_p (machine_mode mode
, bool allow_libcall
)
7078 enum insn_code icode
;
7080 /* Check for __atomic_compare_and_swap. */
7081 icode
= direct_optab_handler (atomic_compare_and_swap_optab
, mode
);
7082 if (icode
!= CODE_FOR_nothing
)
7085 /* Check for __sync_compare_and_swap. */
7086 icode
= optab_handler (sync_compare_and_swap_optab
, mode
);
7087 if (icode
!= CODE_FOR_nothing
)
7089 if (allow_libcall
&& optab_libfunc (sync_compare_and_swap_optab
, mode
))
7092 /* No inline compare and swap. */
7096 /* Return true if an atomic exchange can be performed. */
7099 can_atomic_exchange_p (machine_mode mode
, bool allow_libcall
)
7101 enum insn_code icode
;
7103 /* Check for __atomic_exchange. */
7104 icode
= direct_optab_handler (atomic_exchange_optab
, mode
);
7105 if (icode
!= CODE_FOR_nothing
)
7108 /* Don't check __sync_test_and_set, as on some platforms that
7109 has reduced functionality. Targets that really do support
7110 a proper exchange should simply be updated to the __atomics. */
7112 return can_compare_and_swap_p (mode
, allow_libcall
);
7116 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
7120 find_cc_set (rtx x
, const_rtx pat
, void *data
)
7122 if (REG_P (x
) && GET_MODE_CLASS (GET_MODE (x
)) == MODE_CC
7123 && GET_CODE (pat
) == SET
)
7125 rtx
*p_cc_reg
= (rtx
*) data
;
7126 gcc_assert (!*p_cc_reg
);
7131 /* This is a helper function for the other atomic operations. This function
7132 emits a loop that contains SEQ that iterates until a compare-and-swap
7133 operation at the end succeeds. MEM is the memory to be modified. SEQ is
7134 a set of instructions that takes a value from OLD_REG as an input and
7135 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
7136 set to the current contents of MEM. After SEQ, a compare-and-swap will
7137 attempt to update MEM with NEW_REG. The function returns true when the
7138 loop was generated successfully. */
7141 expand_compare_and_swap_loop (rtx mem
, rtx old_reg
, rtx new_reg
, rtx seq
)
7143 machine_mode mode
= GET_MODE (mem
);
7144 rtx_code_label
*label
;
7145 rtx cmp_reg
, success
, oldval
;
7147 /* The loop we want to generate looks like
7153 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
7157 Note that we only do the plain load from memory once. Subsequent
7158 iterations use the value loaded by the compare-and-swap pattern. */
7160 label
= gen_label_rtx ();
7161 cmp_reg
= gen_reg_rtx (mode
);
7163 emit_move_insn (cmp_reg
, mem
);
7165 emit_move_insn (old_reg
, cmp_reg
);
7171 if (!expand_atomic_compare_and_swap (&success
, &oldval
, mem
, old_reg
,
7172 new_reg
, false, MEMMODEL_SEQ_CST
,
7176 if (oldval
!= cmp_reg
)
7177 emit_move_insn (cmp_reg
, oldval
);
7179 /* Mark this jump predicted not taken. */
7180 emit_cmp_and_jump_insns (success
, const0_rtx
, EQ
, const0_rtx
,
7181 GET_MODE (success
), 1, label
, 0);
7186 /* This function tries to emit an atomic_exchange intruction. VAL is written
7187 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
7188 using TARGET if possible. */
7191 maybe_emit_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
7193 machine_mode mode
= GET_MODE (mem
);
7194 enum insn_code icode
;
7196 /* If the target supports the exchange directly, great. */
7197 icode
= direct_optab_handler (atomic_exchange_optab
, mode
);
7198 if (icode
!= CODE_FOR_nothing
)
7200 struct expand_operand ops
[4];
7202 create_output_operand (&ops
[0], target
, mode
);
7203 create_fixed_operand (&ops
[1], mem
);
7204 create_input_operand (&ops
[2], val
, mode
);
7205 create_integer_operand (&ops
[3], model
);
7206 if (maybe_expand_insn (icode
, 4, ops
))
7207 return ops
[0].value
;
7213 /* This function tries to implement an atomic exchange operation using
7214 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
7215 The previous contents of *MEM are returned, using TARGET if possible.
7216 Since this instructionn is an acquire barrier only, stronger memory
7217 models may require additional barriers to be emitted. */
7220 maybe_emit_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
,
7221 enum memmodel model
)
7223 machine_mode mode
= GET_MODE (mem
);
7224 enum insn_code icode
;
7225 rtx_insn
*last_insn
= get_last_insn ();
7227 icode
= optab_handler (sync_lock_test_and_set_optab
, mode
);
7229 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
7230 exists, and the memory model is stronger than acquire, add a release
7231 barrier before the instruction. */
7233 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
7234 || (model
& MEMMODEL_MASK
) == MEMMODEL_RELEASE
7235 || (model
& MEMMODEL_MASK
) == MEMMODEL_ACQ_REL
)
7236 expand_mem_thread_fence (model
);
7238 if (icode
!= CODE_FOR_nothing
)
7240 struct expand_operand ops
[3];
7241 create_output_operand (&ops
[0], target
, mode
);
7242 create_fixed_operand (&ops
[1], mem
);
7243 create_input_operand (&ops
[2], val
, mode
);
7244 if (maybe_expand_insn (icode
, 3, ops
))
7245 return ops
[0].value
;
7248 /* If an external test-and-set libcall is provided, use that instead of
7249 any external compare-and-swap that we might get from the compare-and-
7250 swap-loop expansion later. */
7251 if (!can_compare_and_swap_p (mode
, false))
7253 rtx libfunc
= optab_libfunc (sync_lock_test_and_set_optab
, mode
);
7254 if (libfunc
!= NULL
)
7258 addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
7259 return emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
7260 mode
, 2, addr
, ptr_mode
,
7265 /* If the test_and_set can't be emitted, eliminate any barrier that might
7266 have been emitted. */
7267 delete_insns_since (last_insn
);
7271 /* This function tries to implement an atomic exchange operation using a
7272 compare_and_swap loop. VAL is written to *MEM. The previous contents of
7273 *MEM are returned, using TARGET if possible. No memory model is required
7274 since a compare_and_swap loop is seq-cst. */
7277 maybe_emit_compare_and_swap_exchange_loop (rtx target
, rtx mem
, rtx val
)
7279 machine_mode mode
= GET_MODE (mem
);
7281 if (can_compare_and_swap_p (mode
, true))
7283 if (!target
|| !register_operand (target
, mode
))
7284 target
= gen_reg_rtx (mode
);
7285 if (expand_compare_and_swap_loop (mem
, target
, val
, NULL_RTX
))
7292 /* This function tries to implement an atomic test-and-set operation
7293 using the atomic_test_and_set instruction pattern. A boolean value
7294 is returned from the operation, using TARGET if possible. */
7296 #ifndef HAVE_atomic_test_and_set
7297 #define HAVE_atomic_test_and_set 0
7298 #define CODE_FOR_atomic_test_and_set CODE_FOR_nothing
7302 maybe_emit_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
7304 machine_mode pat_bool_mode
;
7305 struct expand_operand ops
[3];
7307 if (!HAVE_atomic_test_and_set
)
7310 /* While we always get QImode from __atomic_test_and_set, we get
7311 other memory modes from __sync_lock_test_and_set. Note that we
7312 use no endian adjustment here. This matches the 4.6 behavior
7313 in the Sparc backend. */
7315 (insn_data
[CODE_FOR_atomic_test_and_set
].operand
[1].mode
== QImode
);
7316 if (GET_MODE (mem
) != QImode
)
7317 mem
= adjust_address_nv (mem
, QImode
, 0);
7319 pat_bool_mode
= insn_data
[CODE_FOR_atomic_test_and_set
].operand
[0].mode
;
7320 create_output_operand (&ops
[0], target
, pat_bool_mode
);
7321 create_fixed_operand (&ops
[1], mem
);
7322 create_integer_operand (&ops
[2], model
);
7324 if (maybe_expand_insn (CODE_FOR_atomic_test_and_set
, 3, ops
))
7325 return ops
[0].value
;
7329 /* This function expands the legacy _sync_lock test_and_set operation which is
7330 generally an atomic exchange. Some limited targets only allow the
7331 constant 1 to be stored. This is an ACQUIRE operation.
7333 TARGET is an optional place to stick the return value.
7334 MEM is where VAL is stored. */
7337 expand_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
)
7341 /* Try an atomic_exchange first. */
7342 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, MEMMODEL_ACQUIRE
);
7346 ret
= maybe_emit_sync_lock_test_and_set (target
, mem
, val
, MEMMODEL_ACQUIRE
);
7350 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
7354 /* If there are no other options, try atomic_test_and_set if the value
7355 being stored is 1. */
7356 if (val
== const1_rtx
)
7357 ret
= maybe_emit_atomic_test_and_set (target
, mem
, MEMMODEL_ACQUIRE
);
7362 /* This function expands the atomic test_and_set operation:
7363 atomically store a boolean TRUE into MEM and return the previous value.
7365 MEMMODEL is the memory model variant to use.
7366 TARGET is an optional place to stick the return value. */
7369 expand_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
7371 machine_mode mode
= GET_MODE (mem
);
7372 rtx ret
, trueval
, subtarget
;
7374 ret
= maybe_emit_atomic_test_and_set (target
, mem
, model
);
7378 /* Be binary compatible with non-default settings of trueval, and different
7379 cpu revisions. E.g. one revision may have atomic-test-and-set, but
7380 another only has atomic-exchange. */
7381 if (targetm
.atomic_test_and_set_trueval
== 1)
7383 trueval
= const1_rtx
;
7384 subtarget
= target
? target
: gen_reg_rtx (mode
);
7388 trueval
= gen_int_mode (targetm
.atomic_test_and_set_trueval
, mode
);
7389 subtarget
= gen_reg_rtx (mode
);
7392 /* Try the atomic-exchange optab... */
7393 ret
= maybe_emit_atomic_exchange (subtarget
, mem
, trueval
, model
);
7395 /* ... then an atomic-compare-and-swap loop ... */
7397 ret
= maybe_emit_compare_and_swap_exchange_loop (subtarget
, mem
, trueval
);
7399 /* ... before trying the vaguely defined legacy lock_test_and_set. */
7401 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, trueval
, model
);
7403 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
7404 things with the value 1. Thus we try again without trueval. */
7405 if (!ret
&& targetm
.atomic_test_and_set_trueval
!= 1)
7406 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, const1_rtx
, model
);
7408 /* Failing all else, assume a single threaded environment and simply
7409 perform the operation. */
7412 /* If the result is ignored skip the move to target. */
7413 if (subtarget
!= const0_rtx
)
7414 emit_move_insn (subtarget
, mem
);
7416 emit_move_insn (mem
, trueval
);
7420 /* Recall that have to return a boolean value; rectify if trueval
7421 is not exactly one. */
7422 if (targetm
.atomic_test_and_set_trueval
!= 1)
7423 ret
= emit_store_flag_force (target
, NE
, ret
, const0_rtx
, mode
, 0, 1);
7428 /* This function expands the atomic exchange operation:
7429 atomically store VAL in MEM and return the previous value in MEM.
7431 MEMMODEL is the memory model variant to use.
7432 TARGET is an optional place to stick the return value. */
7435 expand_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
7439 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, model
);
7441 /* Next try a compare-and-swap loop for the exchange. */
7443 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
7448 /* This function expands the atomic compare exchange operation:
7450 *PTARGET_BOOL is an optional place to store the boolean success/failure.
7451 *PTARGET_OVAL is an optional place to store the old value from memory.
7452 Both target parameters may be NULL to indicate that we do not care about
7453 that return value. Both target parameters are updated on success to
7454 the actual location of the corresponding result.
7456 MEMMODEL is the memory model variant to use.
7458 The return value of the function is true for success. */
7461 expand_atomic_compare_and_swap (rtx
*ptarget_bool
, rtx
*ptarget_oval
,
7462 rtx mem
, rtx expected
, rtx desired
,
7463 bool is_weak
, enum memmodel succ_model
,
7464 enum memmodel fail_model
)
7466 machine_mode mode
= GET_MODE (mem
);
7467 struct expand_operand ops
[8];
7468 enum insn_code icode
;
7469 rtx target_oval
, target_bool
= NULL_RTX
;
7472 /* Load expected into a register for the compare and swap. */
7473 if (MEM_P (expected
))
7474 expected
= copy_to_reg (expected
);
7476 /* Make sure we always have some place to put the return oldval.
7477 Further, make sure that place is distinct from the input expected,
7478 just in case we need that path down below. */
7479 if (ptarget_oval
== NULL
7480 || (target_oval
= *ptarget_oval
) == NULL
7481 || reg_overlap_mentioned_p (expected
, target_oval
))
7482 target_oval
= gen_reg_rtx (mode
);
7484 icode
= direct_optab_handler (atomic_compare_and_swap_optab
, mode
);
7485 if (icode
!= CODE_FOR_nothing
)
7487 machine_mode bool_mode
= insn_data
[icode
].operand
[0].mode
;
7489 /* Make sure we always have a place for the bool operand. */
7490 if (ptarget_bool
== NULL
7491 || (target_bool
= *ptarget_bool
) == NULL
7492 || GET_MODE (target_bool
) != bool_mode
)
7493 target_bool
= gen_reg_rtx (bool_mode
);
7495 /* Emit the compare_and_swap. */
7496 create_output_operand (&ops
[0], target_bool
, bool_mode
);
7497 create_output_operand (&ops
[1], target_oval
, mode
);
7498 create_fixed_operand (&ops
[2], mem
);
7499 create_input_operand (&ops
[3], expected
, mode
);
7500 create_input_operand (&ops
[4], desired
, mode
);
7501 create_integer_operand (&ops
[5], is_weak
);
7502 create_integer_operand (&ops
[6], succ_model
);
7503 create_integer_operand (&ops
[7], fail_model
);
7504 if (maybe_expand_insn (icode
, 8, ops
))
7506 /* Return success/failure. */
7507 target_bool
= ops
[0].value
;
7508 target_oval
= ops
[1].value
;
7513 /* Otherwise fall back to the original __sync_val_compare_and_swap
7514 which is always seq-cst. */
7515 icode
= optab_handler (sync_compare_and_swap_optab
, mode
);
7516 if (icode
!= CODE_FOR_nothing
)
7520 create_output_operand (&ops
[0], target_oval
, mode
);
7521 create_fixed_operand (&ops
[1], mem
);
7522 create_input_operand (&ops
[2], expected
, mode
);
7523 create_input_operand (&ops
[3], desired
, mode
);
7524 if (!maybe_expand_insn (icode
, 4, ops
))
7527 target_oval
= ops
[0].value
;
7529 /* If the caller isn't interested in the boolean return value,
7530 skip the computation of it. */
7531 if (ptarget_bool
== NULL
)
7534 /* Otherwise, work out if the compare-and-swap succeeded. */
7536 if (have_insn_for (COMPARE
, CCmode
))
7537 note_stores (PATTERN (get_last_insn ()), find_cc_set
, &cc_reg
);
7540 target_bool
= emit_store_flag_force (target_bool
, EQ
, cc_reg
,
7541 const0_rtx
, VOIDmode
, 0, 1);
7544 goto success_bool_from_val
;
7547 /* Also check for library support for __sync_val_compare_and_swap. */
7548 libfunc
= optab_libfunc (sync_compare_and_swap_optab
, mode
);
7549 if (libfunc
!= NULL
)
7551 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
7552 target_oval
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
7553 mode
, 3, addr
, ptr_mode
,
7554 expected
, mode
, desired
, mode
);
7556 /* Compute the boolean return value only if requested. */
7558 goto success_bool_from_val
;
7566 success_bool_from_val
:
7567 target_bool
= emit_store_flag_force (target_bool
, EQ
, target_oval
,
7568 expected
, VOIDmode
, 1, 1);
7570 /* Make sure that the oval output winds up where the caller asked. */
7572 *ptarget_oval
= target_oval
;
7574 *ptarget_bool
= target_bool
;
7578 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
7581 expand_asm_memory_barrier (void)
7585 asm_op
= gen_rtx_ASM_OPERANDS (VOIDmode
, empty_string
, empty_string
, 0,
7586 rtvec_alloc (0), rtvec_alloc (0),
7587 rtvec_alloc (0), UNKNOWN_LOCATION
);
7588 MEM_VOLATILE_P (asm_op
) = 1;
7590 clob
= gen_rtx_SCRATCH (VOIDmode
);
7591 clob
= gen_rtx_MEM (BLKmode
, clob
);
7592 clob
= gen_rtx_CLOBBER (VOIDmode
, clob
);
7594 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, asm_op
, clob
)));
7597 /* This routine will either emit the mem_thread_fence pattern or issue a
7598 sync_synchronize to generate a fence for memory model MEMMODEL. */
7600 #ifndef HAVE_mem_thread_fence
7601 # define HAVE_mem_thread_fence 0
7602 # define gen_mem_thread_fence(x) (gcc_unreachable (), NULL_RTX)
7604 #ifndef HAVE_memory_barrier
7605 # define HAVE_memory_barrier 0
7606 # define gen_memory_barrier() (gcc_unreachable (), NULL_RTX)
7610 expand_mem_thread_fence (enum memmodel model
)
7612 if (HAVE_mem_thread_fence
)
7613 emit_insn (gen_mem_thread_fence (GEN_INT (model
)));
7614 else if ((model
& MEMMODEL_MASK
) != MEMMODEL_RELAXED
)
7616 if (HAVE_memory_barrier
)
7617 emit_insn (gen_memory_barrier ());
7618 else if (synchronize_libfunc
!= NULL_RTX
)
7619 emit_library_call (synchronize_libfunc
, LCT_NORMAL
, VOIDmode
, 0);
7621 expand_asm_memory_barrier ();
7625 /* This routine will either emit the mem_signal_fence pattern or issue a
7626 sync_synchronize to generate a fence for memory model MEMMODEL. */
7628 #ifndef HAVE_mem_signal_fence
7629 # define HAVE_mem_signal_fence 0
7630 # define gen_mem_signal_fence(x) (gcc_unreachable (), NULL_RTX)
7634 expand_mem_signal_fence (enum memmodel model
)
7636 if (HAVE_mem_signal_fence
)
7637 emit_insn (gen_mem_signal_fence (GEN_INT (model
)));
7638 else if ((model
& MEMMODEL_MASK
) != MEMMODEL_RELAXED
)
7640 /* By default targets are coherent between a thread and the signal
7641 handler running on the same thread. Thus this really becomes a
7642 compiler barrier, in that stores must not be sunk past
7643 (or raised above) a given point. */
7644 expand_asm_memory_barrier ();
7648 /* This function expands the atomic load operation:
7649 return the atomically loaded value in MEM.
7651 MEMMODEL is the memory model variant to use.
7652 TARGET is an option place to stick the return value. */
7655 expand_atomic_load (rtx target
, rtx mem
, enum memmodel model
)
7657 machine_mode mode
= GET_MODE (mem
);
7658 enum insn_code icode
;
7660 /* If the target supports the load directly, great. */
7661 icode
= direct_optab_handler (atomic_load_optab
, mode
);
7662 if (icode
!= CODE_FOR_nothing
)
7664 struct expand_operand ops
[3];
7666 create_output_operand (&ops
[0], target
, mode
);
7667 create_fixed_operand (&ops
[1], mem
);
7668 create_integer_operand (&ops
[2], model
);
7669 if (maybe_expand_insn (icode
, 3, ops
))
7670 return ops
[0].value
;
7673 /* If the size of the object is greater than word size on this target,
7674 then we assume that a load will not be atomic. */
7675 if (GET_MODE_PRECISION (mode
) > BITS_PER_WORD
)
7677 /* Issue val = compare_and_swap (mem, 0, 0).
7678 This may cause the occasional harmless store of 0 when the value is
7679 already 0, but it seems to be OK according to the standards guys. */
7680 if (expand_atomic_compare_and_swap (NULL
, &target
, mem
, const0_rtx
,
7681 const0_rtx
, false, model
, model
))
7684 /* Otherwise there is no atomic load, leave the library call. */
7688 /* Otherwise assume loads are atomic, and emit the proper barriers. */
7689 if (!target
|| target
== const0_rtx
)
7690 target
= gen_reg_rtx (mode
);
7692 /* For SEQ_CST, emit a barrier before the load. */
7693 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
)
7694 expand_mem_thread_fence (model
);
7696 emit_move_insn (target
, mem
);
7698 /* Emit the appropriate barrier after the load. */
7699 expand_mem_thread_fence (model
);
7704 /* This function expands the atomic store operation:
7705 Atomically store VAL in MEM.
7706 MEMMODEL is the memory model variant to use.
7707 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
7708 function returns const0_rtx if a pattern was emitted. */
7711 expand_atomic_store (rtx mem
, rtx val
, enum memmodel model
, bool use_release
)
7713 machine_mode mode
= GET_MODE (mem
);
7714 enum insn_code icode
;
7715 struct expand_operand ops
[3];
7717 /* If the target supports the store directly, great. */
7718 icode
= direct_optab_handler (atomic_store_optab
, mode
);
7719 if (icode
!= CODE_FOR_nothing
)
7721 create_fixed_operand (&ops
[0], mem
);
7722 create_input_operand (&ops
[1], val
, mode
);
7723 create_integer_operand (&ops
[2], model
);
7724 if (maybe_expand_insn (icode
, 3, ops
))
7728 /* If using __sync_lock_release is a viable alternative, try it. */
7731 icode
= direct_optab_handler (sync_lock_release_optab
, mode
);
7732 if (icode
!= CODE_FOR_nothing
)
7734 create_fixed_operand (&ops
[0], mem
);
7735 create_input_operand (&ops
[1], const0_rtx
, mode
);
7736 if (maybe_expand_insn (icode
, 2, ops
))
7738 /* lock_release is only a release barrier. */
7739 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
)
7740 expand_mem_thread_fence (model
);
7746 /* If the size of the object is greater than word size on this target,
7747 a default store will not be atomic, Try a mem_exchange and throw away
7748 the result. If that doesn't work, don't do anything. */
7749 if (GET_MODE_PRECISION (mode
) > BITS_PER_WORD
)
7751 rtx target
= maybe_emit_atomic_exchange (NULL_RTX
, mem
, val
, model
);
7753 target
= maybe_emit_compare_and_swap_exchange_loop (NULL_RTX
, mem
, val
);
7760 /* Otherwise assume stores are atomic, and emit the proper barriers. */
7761 expand_mem_thread_fence (model
);
7763 emit_move_insn (mem
, val
);
7765 /* For SEQ_CST, also emit a barrier after the store. */
7766 if ((model
& MEMMODEL_MASK
) == MEMMODEL_SEQ_CST
)
7767 expand_mem_thread_fence (model
);
7773 /* Structure containing the pointers and values required to process the
7774 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
7776 struct atomic_op_functions
7778 direct_optab mem_fetch_before
;
7779 direct_optab mem_fetch_after
;
7780 direct_optab mem_no_result
;
7783 direct_optab no_result
;
7784 enum rtx_code reverse_code
;
7788 /* Fill in structure pointed to by OP with the various optab entries for an
7789 operation of type CODE. */
7792 get_atomic_op_for_code (struct atomic_op_functions
*op
, enum rtx_code code
)
7794 gcc_assert (op
!= NULL
);
7796 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
7797 in the source code during compilation, and the optab entries are not
7798 computable until runtime. Fill in the values at runtime. */
7802 op
->mem_fetch_before
= atomic_fetch_add_optab
;
7803 op
->mem_fetch_after
= atomic_add_fetch_optab
;
7804 op
->mem_no_result
= atomic_add_optab
;
7805 op
->fetch_before
= sync_old_add_optab
;
7806 op
->fetch_after
= sync_new_add_optab
;
7807 op
->no_result
= sync_add_optab
;
7808 op
->reverse_code
= MINUS
;
7811 op
->mem_fetch_before
= atomic_fetch_sub_optab
;
7812 op
->mem_fetch_after
= atomic_sub_fetch_optab
;
7813 op
->mem_no_result
= atomic_sub_optab
;
7814 op
->fetch_before
= sync_old_sub_optab
;
7815 op
->fetch_after
= sync_new_sub_optab
;
7816 op
->no_result
= sync_sub_optab
;
7817 op
->reverse_code
= PLUS
;
7820 op
->mem_fetch_before
= atomic_fetch_xor_optab
;
7821 op
->mem_fetch_after
= atomic_xor_fetch_optab
;
7822 op
->mem_no_result
= atomic_xor_optab
;
7823 op
->fetch_before
= sync_old_xor_optab
;
7824 op
->fetch_after
= sync_new_xor_optab
;
7825 op
->no_result
= sync_xor_optab
;
7826 op
->reverse_code
= XOR
;
7829 op
->mem_fetch_before
= atomic_fetch_and_optab
;
7830 op
->mem_fetch_after
= atomic_and_fetch_optab
;
7831 op
->mem_no_result
= atomic_and_optab
;
7832 op
->fetch_before
= sync_old_and_optab
;
7833 op
->fetch_after
= sync_new_and_optab
;
7834 op
->no_result
= sync_and_optab
;
7835 op
->reverse_code
= UNKNOWN
;
7838 op
->mem_fetch_before
= atomic_fetch_or_optab
;
7839 op
->mem_fetch_after
= atomic_or_fetch_optab
;
7840 op
->mem_no_result
= atomic_or_optab
;
7841 op
->fetch_before
= sync_old_ior_optab
;
7842 op
->fetch_after
= sync_new_ior_optab
;
7843 op
->no_result
= sync_ior_optab
;
7844 op
->reverse_code
= UNKNOWN
;
7847 op
->mem_fetch_before
= atomic_fetch_nand_optab
;
7848 op
->mem_fetch_after
= atomic_nand_fetch_optab
;
7849 op
->mem_no_result
= atomic_nand_optab
;
7850 op
->fetch_before
= sync_old_nand_optab
;
7851 op
->fetch_after
= sync_new_nand_optab
;
7852 op
->no_result
= sync_nand_optab
;
7853 op
->reverse_code
= UNKNOWN
;
7860 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
7861 using memory order MODEL. If AFTER is true the operation needs to return
7862 the value of *MEM after the operation, otherwise the previous value.
7863 TARGET is an optional place to place the result. The result is unused if
7865 Return the result if there is a better sequence, otherwise NULL_RTX. */
7868 maybe_optimize_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
7869 enum memmodel model
, bool after
)
7871 /* If the value is prefetched, or not used, it may be possible to replace
7872 the sequence with a native exchange operation. */
7873 if (!after
|| target
== const0_rtx
)
7875 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
7876 if (code
== AND
&& val
== const0_rtx
)
7878 if (target
== const0_rtx
)
7879 target
= gen_reg_rtx (GET_MODE (mem
));
7880 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
7883 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
7884 if (code
== IOR
&& val
== constm1_rtx
)
7886 if (target
== const0_rtx
)
7887 target
= gen_reg_rtx (GET_MODE (mem
));
7888 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
7895 /* Try to emit an instruction for a specific operation varaition.
7896 OPTAB contains the OP functions.
7897 TARGET is an optional place to return the result. const0_rtx means unused.
7898 MEM is the memory location to operate on.
7899 VAL is the value to use in the operation.
7900 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
7901 MODEL is the memory model, if used.
7902 AFTER is true if the returned result is the value after the operation. */
7905 maybe_emit_op (const struct atomic_op_functions
*optab
, rtx target
, rtx mem
,
7906 rtx val
, bool use_memmodel
, enum memmodel model
, bool after
)
7908 machine_mode mode
= GET_MODE (mem
);
7909 struct expand_operand ops
[4];
7910 enum insn_code icode
;
7914 /* Check to see if there is a result returned. */
7915 if (target
== const0_rtx
)
7919 icode
= direct_optab_handler (optab
->mem_no_result
, mode
);
7920 create_integer_operand (&ops
[2], model
);
7925 icode
= direct_optab_handler (optab
->no_result
, mode
);
7929 /* Otherwise, we need to generate a result. */
7934 icode
= direct_optab_handler (after
? optab
->mem_fetch_after
7935 : optab
->mem_fetch_before
, mode
);
7936 create_integer_operand (&ops
[3], model
);
7941 icode
= optab_handler (after
? optab
->fetch_after
7942 : optab
->fetch_before
, mode
);
7945 create_output_operand (&ops
[op_counter
++], target
, mode
);
7947 if (icode
== CODE_FOR_nothing
)
7950 create_fixed_operand (&ops
[op_counter
++], mem
);
7951 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7952 create_convert_operand_to (&ops
[op_counter
++], val
, mode
, true);
7954 if (maybe_expand_insn (icode
, num_ops
, ops
))
7955 return (target
== const0_rtx
? const0_rtx
: ops
[0].value
);
7961 /* This function expands an atomic fetch_OP or OP_fetch operation:
7962 TARGET is an option place to stick the return value. const0_rtx indicates
7963 the result is unused.
7964 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7965 CODE is the operation being performed (OP)
7966 MEMMODEL is the memory model variant to use.
7967 AFTER is true to return the result of the operation (OP_fetch).
7968 AFTER is false to return the value before the operation (fetch_OP).
7970 This function will *only* generate instructions if there is a direct
7971 optab. No compare and swap loops or libcalls will be generated. */
7974 expand_atomic_fetch_op_no_fallback (rtx target
, rtx mem
, rtx val
,
7975 enum rtx_code code
, enum memmodel model
,
7978 machine_mode mode
= GET_MODE (mem
);
7979 struct atomic_op_functions optab
;
7981 bool unused_result
= (target
== const0_rtx
);
7983 get_atomic_op_for_code (&optab
, code
);
7985 /* Check to see if there are any better instructions. */
7986 result
= maybe_optimize_fetch_op (target
, mem
, val
, code
, model
, after
);
7990 /* Check for the case where the result isn't used and try those patterns. */
7993 /* Try the memory model variant first. */
7994 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, true);
7998 /* Next try the old style withuot a memory model. */
7999 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, true);
8003 /* There is no no-result pattern, so try patterns with a result. */
8007 /* Try the __atomic version. */
8008 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, after
);
8012 /* Try the older __sync version. */
8013 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, after
);
8017 /* If the fetch value can be calculated from the other variation of fetch,
8018 try that operation. */
8019 if (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
)
8021 /* Try the __atomic version, then the older __sync version. */
8022 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, !after
);
8024 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, !after
);
8028 /* If the result isn't used, no need to do compensation code. */
8032 /* Issue compensation code. Fetch_after == fetch_before OP val.
8033 Fetch_before == after REVERSE_OP val. */
8035 code
= optab
.reverse_code
;
8038 result
= expand_simple_binop (mode
, AND
, result
, val
, NULL_RTX
,
8039 true, OPTAB_LIB_WIDEN
);
8040 result
= expand_simple_unop (mode
, NOT
, result
, target
, true);
8043 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
8044 true, OPTAB_LIB_WIDEN
);
8049 /* No direct opcode can be generated. */
8055 /* This function expands an atomic fetch_OP or OP_fetch operation:
8056 TARGET is an option place to stick the return value. const0_rtx indicates
8057 the result is unused.
8058 atomically fetch MEM, perform the operation with VAL and return it to MEM.
8059 CODE is the operation being performed (OP)
8060 MEMMODEL is the memory model variant to use.
8061 AFTER is true to return the result of the operation (OP_fetch).
8062 AFTER is false to return the value before the operation (fetch_OP). */
8064 expand_atomic_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
8065 enum memmodel model
, bool after
)
8067 machine_mode mode
= GET_MODE (mem
);
8069 bool unused_result
= (target
== const0_rtx
);
8071 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, val
, code
, model
,
8077 /* Add/sub can be implemented by doing the reverse operation with -(val). */
8078 if (code
== PLUS
|| code
== MINUS
)
8081 enum rtx_code reverse
= (code
== PLUS
? MINUS
: PLUS
);
8084 tmp
= expand_simple_unop (mode
, NEG
, val
, NULL_RTX
, true);
8085 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, tmp
, reverse
,
8089 /* PLUS worked so emit the insns and return. */
8096 /* PLUS did not work, so throw away the negation code and continue. */
8100 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
8101 if (!can_compare_and_swap_p (mode
, false))
8105 enum rtx_code orig_code
= code
;
8106 struct atomic_op_functions optab
;
8108 get_atomic_op_for_code (&optab
, code
);
8109 libfunc
= optab_libfunc (after
? optab
.fetch_after
8110 : optab
.fetch_before
, mode
);
8112 && (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
))
8116 code
= optab
.reverse_code
;
8117 libfunc
= optab_libfunc (after
? optab
.fetch_before
8118 : optab
.fetch_after
, mode
);
8120 if (libfunc
!= NULL
)
8122 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
8123 result
= emit_library_call_value (libfunc
, NULL
, LCT_NORMAL
, mode
,
8124 2, addr
, ptr_mode
, val
, mode
);
8126 if (!unused_result
&& fixup
)
8127 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
8128 true, OPTAB_LIB_WIDEN
);
8132 /* We need the original code for any further attempts. */
8136 /* If nothing else has succeeded, default to a compare and swap loop. */
8137 if (can_compare_and_swap_p (mode
, true))
8140 rtx t0
= gen_reg_rtx (mode
), t1
;
8144 /* If the result is used, get a register for it. */
8147 if (!target
|| !register_operand (target
, mode
))
8148 target
= gen_reg_rtx (mode
);
8149 /* If fetch_before, copy the value now. */
8151 emit_move_insn (target
, t0
);
8154 target
= const0_rtx
;
8159 t1
= expand_simple_binop (mode
, AND
, t1
, val
, NULL_RTX
,
8160 true, OPTAB_LIB_WIDEN
);
8161 t1
= expand_simple_unop (mode
, code
, t1
, NULL_RTX
, true);
8164 t1
= expand_simple_binop (mode
, code
, t1
, val
, NULL_RTX
, true,
8167 /* For after, copy the value now. */
8168 if (!unused_result
&& after
)
8169 emit_move_insn (target
, t1
);
8170 insn
= get_insns ();
8173 if (t1
!= NULL
&& expand_compare_and_swap_loop (mem
, t0
, t1
, insn
))
8180 /* Return true if OPERAND is suitable for operand number OPNO of
8181 instruction ICODE. */
8184 insn_operand_matches (enum insn_code icode
, unsigned int opno
, rtx operand
)
8186 return (!insn_data
[(int) icode
].operand
[opno
].predicate
8187 || (insn_data
[(int) icode
].operand
[opno
].predicate
8188 (operand
, insn_data
[(int) icode
].operand
[opno
].mode
)));
8191 /* TARGET is a target of a multiword operation that we are going to
8192 implement as a series of word-mode operations. Return true if
8193 TARGET is suitable for this purpose. */
8196 valid_multiword_target_p (rtx target
)
8201 mode
= GET_MODE (target
);
8202 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
+= UNITS_PER_WORD
)
8203 if (!validate_subreg (word_mode
, mode
, target
, i
))
8208 /* Like maybe_legitimize_operand, but do not change the code of the
8209 current rtx value. */
8212 maybe_legitimize_operand_same_code (enum insn_code icode
, unsigned int opno
,
8213 struct expand_operand
*op
)
8215 /* See if the operand matches in its current form. */
8216 if (insn_operand_matches (icode
, opno
, op
->value
))
8219 /* If the operand is a memory whose address has no side effects,
8220 try forcing the address into a non-virtual pseudo register.
8221 The check for side effects is important because copy_to_mode_reg
8222 cannot handle things like auto-modified addresses. */
8223 if (insn_data
[(int) icode
].operand
[opno
].allows_mem
&& MEM_P (op
->value
))
8228 addr
= XEXP (mem
, 0);
8229 if (!(REG_P (addr
) && REGNO (addr
) > LAST_VIRTUAL_REGISTER
)
8230 && !side_effects_p (addr
))
8235 last
= get_last_insn ();
8236 mode
= get_address_mode (mem
);
8237 mem
= replace_equiv_address (mem
, copy_to_mode_reg (mode
, addr
));
8238 if (insn_operand_matches (icode
, opno
, mem
))
8243 delete_insns_since (last
);
8250 /* Try to make OP match operand OPNO of instruction ICODE. Return true
8251 on success, storing the new operand value back in OP. */
8254 maybe_legitimize_operand (enum insn_code icode
, unsigned int opno
,
8255 struct expand_operand
*op
)
8257 machine_mode mode
, imode
;
8258 bool old_volatile_ok
, result
;
8264 old_volatile_ok
= volatile_ok
;
8266 result
= maybe_legitimize_operand_same_code (icode
, opno
, op
);
8267 volatile_ok
= old_volatile_ok
;
8271 gcc_assert (mode
!= VOIDmode
);
8273 && op
->value
!= const0_rtx
8274 && GET_MODE (op
->value
) == mode
8275 && maybe_legitimize_operand_same_code (icode
, opno
, op
))
8278 op
->value
= gen_reg_rtx (mode
);
8283 gcc_assert (mode
!= VOIDmode
);
8284 gcc_assert (GET_MODE (op
->value
) == VOIDmode
8285 || GET_MODE (op
->value
) == mode
);
8286 if (maybe_legitimize_operand_same_code (icode
, opno
, op
))
8289 op
->value
= copy_to_mode_reg (mode
, op
->value
);
8292 case EXPAND_CONVERT_TO
:
8293 gcc_assert (mode
!= VOIDmode
);
8294 op
->value
= convert_to_mode (mode
, op
->value
, op
->unsigned_p
);
8297 case EXPAND_CONVERT_FROM
:
8298 if (GET_MODE (op
->value
) != VOIDmode
)
8299 mode
= GET_MODE (op
->value
);
8301 /* The caller must tell us what mode this value has. */
8302 gcc_assert (mode
!= VOIDmode
);
8304 imode
= insn_data
[(int) icode
].operand
[opno
].mode
;
8305 if (imode
!= VOIDmode
&& imode
!= mode
)
8307 op
->value
= convert_modes (imode
, mode
, op
->value
, op
->unsigned_p
);
8312 case EXPAND_ADDRESS
:
8313 gcc_assert (mode
!= VOIDmode
);
8314 op
->value
= convert_memory_address (mode
, op
->value
);
8317 case EXPAND_INTEGER
:
8318 mode
= insn_data
[(int) icode
].operand
[opno
].mode
;
8319 if (mode
!= VOIDmode
&& const_int_operand (op
->value
, mode
))
8323 return insn_operand_matches (icode
, opno
, op
->value
);
8326 /* Make OP describe an input operand that should have the same value
8327 as VALUE, after any mode conversion that the target might request.
8328 TYPE is the type of VALUE. */
8331 create_convert_operand_from_type (struct expand_operand
*op
,
8332 rtx value
, tree type
)
8334 create_convert_operand_from (op
, value
, TYPE_MODE (type
),
8335 TYPE_UNSIGNED (type
));
8338 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
8339 of instruction ICODE. Return true on success, leaving the new operand
8340 values in the OPS themselves. Emit no code on failure. */
8343 maybe_legitimize_operands (enum insn_code icode
, unsigned int opno
,
8344 unsigned int nops
, struct expand_operand
*ops
)
8349 last
= get_last_insn ();
8350 for (i
= 0; i
< nops
; i
++)
8351 if (!maybe_legitimize_operand (icode
, opno
+ i
, &ops
[i
]))
8353 delete_insns_since (last
);
8359 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
8360 as its operands. Return the instruction pattern on success,
8361 and emit any necessary set-up code. Return null and emit no
8365 maybe_gen_insn (enum insn_code icode
, unsigned int nops
,
8366 struct expand_operand
*ops
)
8368 gcc_assert (nops
== (unsigned int) insn_data
[(int) icode
].n_generator_args
);
8369 if (!maybe_legitimize_operands (icode
, 0, nops
, ops
))
8375 return GEN_FCN (icode
) (ops
[0].value
);
8377 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
);
8379 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
);
8381 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8384 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8385 ops
[3].value
, ops
[4].value
);
8387 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8388 ops
[3].value
, ops
[4].value
, ops
[5].value
);
8390 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8391 ops
[3].value
, ops
[4].value
, ops
[5].value
,
8394 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8395 ops
[3].value
, ops
[4].value
, ops
[5].value
,
8396 ops
[6].value
, ops
[7].value
);
8398 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
8399 ops
[3].value
, ops
[4].value
, ops
[5].value
,
8400 ops
[6].value
, ops
[7].value
, ops
[8].value
);
8405 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
8406 as its operands. Return true on success and emit no code on failure. */
8409 maybe_expand_insn (enum insn_code icode
, unsigned int nops
,
8410 struct expand_operand
*ops
)
8412 rtx pat
= maybe_gen_insn (icode
, nops
, ops
);
8421 /* Like maybe_expand_insn, but for jumps. */
8424 maybe_expand_jump_insn (enum insn_code icode
, unsigned int nops
,
8425 struct expand_operand
*ops
)
8427 rtx pat
= maybe_gen_insn (icode
, nops
, ops
);
8430 emit_jump_insn (pat
);
8436 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
8440 expand_insn (enum insn_code icode
, unsigned int nops
,
8441 struct expand_operand
*ops
)
8443 if (!maybe_expand_insn (icode
, nops
, ops
))
8447 /* Like expand_insn, but for jumps. */
8450 expand_jump_insn (enum insn_code icode
, unsigned int nops
,
8451 struct expand_operand
*ops
)
8453 if (!maybe_expand_jump_insn (icode
, nops
, ops
))
8457 /* Reduce conditional compilation elsewhere. */
8460 #define CODE_FOR_insv CODE_FOR_nothing
8464 #define CODE_FOR_extv CODE_FOR_nothing
8467 #define HAVE_extzv 0
8468 #define CODE_FOR_extzv CODE_FOR_nothing
8471 /* Enumerates the possible types of structure operand to an
8473 enum extraction_type
{ ET_unaligned_mem
, ET_reg
};
8475 /* Check whether insv, extv or extzv pattern ICODE can be used for an
8476 insertion or extraction of type TYPE on a structure of mode MODE.
8477 Return true if so and fill in *INSN accordingly. STRUCT_OP is the
8478 operand number of the structure (the first sign_extract or zero_extract
8479 operand) and FIELD_OP is the operand number of the field (the other
8480 side of the set from the sign_extract or zero_extract). */
8483 get_traditional_extraction_insn (extraction_insn
*insn
,
8484 enum extraction_type type
,
8486 enum insn_code icode
,
8487 int struct_op
, int field_op
)
8489 const struct insn_data_d
*data
= &insn_data
[icode
];
8491 machine_mode struct_mode
= data
->operand
[struct_op
].mode
;
8492 if (struct_mode
== VOIDmode
)
8493 struct_mode
= word_mode
;
8494 if (mode
!= struct_mode
)
8497 machine_mode field_mode
= data
->operand
[field_op
].mode
;
8498 if (field_mode
== VOIDmode
)
8499 field_mode
= word_mode
;
8501 machine_mode pos_mode
= data
->operand
[struct_op
+ 2].mode
;
8502 if (pos_mode
== VOIDmode
)
8503 pos_mode
= word_mode
;
8505 insn
->icode
= icode
;
8506 insn
->field_mode
= field_mode
;
8507 insn
->struct_mode
= (type
== ET_unaligned_mem
? byte_mode
: struct_mode
);
8508 insn
->pos_mode
= pos_mode
;
8512 /* Return true if an optab exists to perform an insertion or extraction
8513 of type TYPE in mode MODE. Describe the instruction in *INSN if so.
8515 REG_OPTAB is the optab to use for register structures and
8516 MISALIGN_OPTAB is the optab to use for misaligned memory structures.
8517 POS_OP is the operand number of the bit position. */
8520 get_optab_extraction_insn (struct extraction_insn
*insn
,
8521 enum extraction_type type
,
8522 machine_mode mode
, direct_optab reg_optab
,
8523 direct_optab misalign_optab
, int pos_op
)
8525 direct_optab optab
= (type
== ET_unaligned_mem
? misalign_optab
: reg_optab
);
8526 enum insn_code icode
= direct_optab_handler (optab
, mode
);
8527 if (icode
== CODE_FOR_nothing
)
8530 const struct insn_data_d
*data
= &insn_data
[icode
];
8532 insn
->icode
= icode
;
8533 insn
->field_mode
= mode
;
8534 insn
->struct_mode
= (type
== ET_unaligned_mem
? BLKmode
: mode
);
8535 insn
->pos_mode
= data
->operand
[pos_op
].mode
;
8536 if (insn
->pos_mode
== VOIDmode
)
8537 insn
->pos_mode
= word_mode
;
8541 /* Return true if an instruction exists to perform an insertion or
8542 extraction (PATTERN says which) of type TYPE in mode MODE.
8543 Describe the instruction in *INSN if so. */
8546 get_extraction_insn (extraction_insn
*insn
,
8547 enum extraction_pattern pattern
,
8548 enum extraction_type type
,
8555 && get_traditional_extraction_insn (insn
, type
, mode
,
8556 CODE_FOR_insv
, 0, 3))
8558 return get_optab_extraction_insn (insn
, type
, mode
, insv_optab
,
8559 insvmisalign_optab
, 2);
8563 && get_traditional_extraction_insn (insn
, type
, mode
,
8564 CODE_FOR_extv
, 1, 0))
8566 return get_optab_extraction_insn (insn
, type
, mode
, extv_optab
,
8567 extvmisalign_optab
, 3);
8571 && get_traditional_extraction_insn (insn
, type
, mode
,
8572 CODE_FOR_extzv
, 1, 0))
8574 return get_optab_extraction_insn (insn
, type
, mode
, extzv_optab
,
8575 extzvmisalign_optab
, 3);
8582 /* Return true if an instruction exists to access a field of mode
8583 FIELDMODE in a structure that has STRUCT_BITS significant bits.
8584 Describe the "best" such instruction in *INSN if so. PATTERN and
8585 TYPE describe the type of insertion or extraction we want to perform.
8587 For an insertion, the number of significant structure bits includes
8588 all bits of the target. For an extraction, it need only include the
8589 most significant bit of the field. Larger widths are acceptable
8593 get_best_extraction_insn (extraction_insn
*insn
,
8594 enum extraction_pattern pattern
,
8595 enum extraction_type type
,
8596 unsigned HOST_WIDE_INT struct_bits
,
8597 machine_mode field_mode
)
8599 machine_mode mode
= smallest_mode_for_size (struct_bits
, MODE_INT
);
8600 while (mode
!= VOIDmode
)
8602 if (get_extraction_insn (insn
, pattern
, type
, mode
))
8604 while (mode
!= VOIDmode
8605 && GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (field_mode
)
8606 && !TRULY_NOOP_TRUNCATION_MODES_P (insn
->field_mode
,
8609 get_extraction_insn (insn
, pattern
, type
, mode
);
8610 mode
= GET_MODE_WIDER_MODE (mode
);
8614 mode
= GET_MODE_WIDER_MODE (mode
);
8619 /* Return true if an instruction exists to access a field of mode
8620 FIELDMODE in a register structure that has STRUCT_BITS significant bits.
8621 Describe the "best" such instruction in *INSN if so. PATTERN describes
8622 the type of insertion or extraction we want to perform.
8624 For an insertion, the number of significant structure bits includes
8625 all bits of the target. For an extraction, it need only include the
8626 most significant bit of the field. Larger widths are acceptable
8630 get_best_reg_extraction_insn (extraction_insn
*insn
,
8631 enum extraction_pattern pattern
,
8632 unsigned HOST_WIDE_INT struct_bits
,
8633 machine_mode field_mode
)
8635 return get_best_extraction_insn (insn
, pattern
, ET_reg
, struct_bits
,
8639 /* Return true if an instruction exists to access a field of BITSIZE
8640 bits starting BITNUM bits into a memory structure. Describe the
8641 "best" such instruction in *INSN if so. PATTERN describes the type
8642 of insertion or extraction we want to perform and FIELDMODE is the
8643 natural mode of the extracted field.
8645 The instructions considered here only access bytes that overlap
8646 the bitfield; they do not touch any surrounding bytes. */
8649 get_best_mem_extraction_insn (extraction_insn
*insn
,
8650 enum extraction_pattern pattern
,
8651 HOST_WIDE_INT bitsize
, HOST_WIDE_INT bitnum
,
8652 machine_mode field_mode
)
8654 unsigned HOST_WIDE_INT struct_bits
= (bitnum
% BITS_PER_UNIT
8656 + BITS_PER_UNIT
- 1);
8657 struct_bits
-= struct_bits
% BITS_PER_UNIT
;
8658 return get_best_extraction_insn (insn
, pattern
, ET_unaligned_mem
,
8659 struct_bits
, field_mode
);
8662 /* Determine whether "1 << x" is relatively cheap in word_mode. */
8665 lshift_cheap_p (bool speed_p
)
8667 /* FIXME: This should be made target dependent via this "this_target"
8668 mechanism, similar to e.g. can_copy_init_p in gcse.c. */
8669 static bool init
[2] = { false, false };
8670 static bool cheap
[2] = { true, true };
8672 /* If the targer has no lshift in word_mode, the operation will most
8673 probably not be cheap. ??? Does GCC even work for such targets? */
8674 if (optab_handler (ashl_optab
, word_mode
) == CODE_FOR_nothing
)
8679 rtx reg
= gen_raw_REG (word_mode
, 10000);
8680 int cost
= set_src_cost (gen_rtx_ASHIFT (word_mode
, const1_rtx
, reg
),
8682 cheap
[speed_p
] = cost
< COSTS_N_INSNS (3);
8683 init
[speed_p
] = true;
8686 return cheap
[speed_p
];
8689 #include "gt-optabs.h"