1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2022 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"
35 #include "diagnostic-core.h"
36 #include "rtx-vector-builder.h"
38 /* Include insn-config.h before expr.h so that HAVE_conditional_move
39 is properly defined. */
40 #include "stor-layout.h"
45 #include "optabs-tree.h"
47 #include "internal-fn.h"
48 #include "langhooks.h"
50 static void prepare_float_lib_cmp (rtx
, rtx
, enum rtx_code
, rtx
*,
52 static rtx
expand_unop_direct (machine_mode
, optab
, rtx
, rtx
, int);
53 static void emit_libcall_block_1 (rtx_insn
*, rtx
, rtx
, rtx
, bool);
55 static rtx
emit_conditional_move_1 (rtx
, rtx
, rtx
, rtx
, machine_mode
);
57 /* Debug facility for use in GDB. */
58 void debug_optab_libfuncs (void);
60 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
61 the result of operation CODE applied to OP0 (and OP1 if it is a binary
62 operation). OP0_MODE is OP0's mode.
64 If the last insn does not set TARGET, don't do anything, but return 1.
66 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
67 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
68 try again, ensuring that TARGET is not one of the operands. */
71 add_equal_note (rtx_insn
*insns
, rtx target
, enum rtx_code code
, rtx op0
,
72 rtx op1
, machine_mode op0_mode
)
78 gcc_assert (insns
&& INSN_P (insns
) && NEXT_INSN (insns
));
80 if (GET_RTX_CLASS (code
) != RTX_COMM_ARITH
81 && GET_RTX_CLASS (code
) != RTX_BIN_ARITH
82 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
83 && GET_RTX_CLASS (code
) != RTX_COMPARE
84 && GET_RTX_CLASS (code
) != RTX_UNARY
)
87 if (GET_CODE (target
) == ZERO_EXTRACT
)
90 for (last_insn
= insns
;
91 NEXT_INSN (last_insn
) != NULL_RTX
;
92 last_insn
= NEXT_INSN (last_insn
))
95 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
96 a value changing in the insn, so the note would be invalid for CSE. */
97 if (reg_overlap_mentioned_p (target
, op0
)
98 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
101 && (rtx_equal_p (target
, op0
)
102 || (op1
&& rtx_equal_p (target
, op1
))))
104 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
105 over expanding it as temp = MEM op X, MEM = temp. If the target
106 supports MEM = MEM op X instructions, it is sometimes too hard
107 to reconstruct that form later, especially if X is also a memory,
108 and due to multiple occurrences of addresses the address might
109 be forced into register unnecessarily.
110 Note that not emitting the REG_EQUIV note might inhibit
111 CSE in some cases. */
112 set
= single_set (last_insn
);
114 && GET_CODE (SET_SRC (set
)) == code
115 && MEM_P (SET_DEST (set
))
116 && (rtx_equal_p (SET_DEST (set
), XEXP (SET_SRC (set
), 0))
117 || (op1
&& rtx_equal_p (SET_DEST (set
),
118 XEXP (SET_SRC (set
), 1)))))
124 set
= set_for_reg_notes (last_insn
);
128 if (! rtx_equal_p (SET_DEST (set
), target
)
129 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
130 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
131 || ! rtx_equal_p (XEXP (SET_DEST (set
), 0), target
)))
134 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
144 if (op0_mode
!= VOIDmode
&& GET_MODE (target
) != op0_mode
)
146 note
= gen_rtx_fmt_e (code
, op0_mode
, copy_rtx (op0
));
147 if (GET_MODE_UNIT_SIZE (op0_mode
)
148 > GET_MODE_UNIT_SIZE (GET_MODE (target
)))
149 note
= simplify_gen_unary (TRUNCATE
, GET_MODE (target
),
152 note
= simplify_gen_unary (ZERO_EXTEND
, GET_MODE (target
),
158 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
162 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
164 set_unique_reg_note (last_insn
, REG_EQUAL
, note
);
169 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
170 for a widening operation would be. In most cases this would be OP0, but if
171 that's a constant it'll be VOIDmode, which isn't useful. */
174 widened_mode (machine_mode to_mode
, rtx op0
, rtx op1
)
176 machine_mode m0
= GET_MODE (op0
);
177 machine_mode m1
= GET_MODE (op1
);
180 if (m0
== VOIDmode
&& m1
== VOIDmode
)
182 else if (m0
== VOIDmode
|| GET_MODE_UNIT_SIZE (m0
) < GET_MODE_UNIT_SIZE (m1
))
187 if (GET_MODE_UNIT_SIZE (result
) > GET_MODE_UNIT_SIZE (to_mode
))
193 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
194 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
195 not actually do a sign-extend or zero-extend, but can leave the
196 higher-order bits of the result rtx undefined, for example, in the case
197 of logical operations, but not right shifts. */
200 widen_operand (rtx op
, machine_mode mode
, machine_mode oldmode
,
201 int unsignedp
, int no_extend
)
204 scalar_int_mode int_mode
;
206 /* If we don't have to extend and this is a constant, return it. */
207 if (no_extend
&& GET_MODE (op
) == VOIDmode
)
210 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
211 extend since it will be more efficient to do so unless the signedness of
212 a promoted object differs from our extension. */
214 || !is_a
<scalar_int_mode
> (mode
, &int_mode
)
215 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)
216 && SUBREG_CHECK_PROMOTED_SIGN (op
, unsignedp
)))
217 return convert_modes (mode
, oldmode
, op
, unsignedp
);
219 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
221 if (GET_MODE_SIZE (int_mode
) <= UNITS_PER_WORD
)
222 return gen_lowpart (int_mode
, force_reg (GET_MODE (op
), op
));
224 /* Otherwise, get an object of MODE, clobber it, and set the low-order
227 result
= gen_reg_rtx (int_mode
);
228 emit_clobber (result
);
229 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
233 /* Expand vector widening operations.
235 There are two different classes of operations handled here:
236 1) Operations whose result is wider than all the arguments to the operation.
237 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
238 In this case OP0 and optionally OP1 would be initialized,
239 but WIDE_OP wouldn't (not relevant for this case).
240 2) Operations whose result is of the same size as the last argument to the
241 operation, but wider than all the other arguments to the operation.
242 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
243 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
245 E.g, when called to expand the following operations, this is how
246 the arguments will be initialized:
248 widening-sum 2 oprnd0 - oprnd1
249 widening-dot-product 3 oprnd0 oprnd1 oprnd2
250 widening-mult 2 oprnd0 oprnd1 -
251 type-promotion (vec-unpack) 1 oprnd0 - - */
254 expand_widen_pattern_expr (sepops ops
, rtx op0
, rtx op1
, rtx wide_op
,
255 rtx target
, int unsignedp
)
257 class expand_operand eops
[4];
258 tree oprnd0
, oprnd1
, oprnd2
;
259 machine_mode wmode
= VOIDmode
, tmode0
, tmode1
= VOIDmode
;
260 optab widen_pattern_optab
;
261 enum insn_code icode
;
262 int nops
= TREE_CODE_LENGTH (ops
->code
);
267 oprnd1
= nops
>= 2 ? ops
->op1
: NULL_TREE
;
268 oprnd2
= nops
>= 3 ? ops
->op2
: NULL_TREE
;
270 tmode0
= TYPE_MODE (TREE_TYPE (oprnd0
));
271 if (ops
->code
== VEC_UNPACK_FIX_TRUNC_HI_EXPR
272 || ops
->code
== VEC_UNPACK_FIX_TRUNC_LO_EXPR
)
273 /* The sign is from the result type rather than operand's type
276 = optab_for_tree_code (ops
->code
, ops
->type
, optab_default
);
277 else if ((ops
->code
== VEC_UNPACK_HI_EXPR
278 || ops
->code
== VEC_UNPACK_LO_EXPR
)
279 && VECTOR_BOOLEAN_TYPE_P (ops
->type
)
280 && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (oprnd0
))
281 && TYPE_MODE (ops
->type
) == TYPE_MODE (TREE_TYPE (oprnd0
))
282 && SCALAR_INT_MODE_P (TYPE_MODE (ops
->type
)))
284 /* For VEC_UNPACK_{LO,HI}_EXPR if the mode of op0 and result is
285 the same scalar mode for VECTOR_BOOLEAN_TYPE_P vectors, use
286 vec_unpacks_sbool_{lo,hi}_optab, so that we can pass in
287 the pattern number of elements in the wider vector. */
289 = (ops
->code
== VEC_UNPACK_HI_EXPR
290 ? vec_unpacks_sbool_hi_optab
: vec_unpacks_sbool_lo_optab
);
293 else if (ops
->code
== DOT_PROD_EXPR
)
295 enum optab_subtype subtype
= optab_default
;
296 signop sign1
= TYPE_SIGN (TREE_TYPE (oprnd0
));
297 signop sign2
= TYPE_SIGN (TREE_TYPE (oprnd1
));
300 else if (sign1
== SIGNED
&& sign2
== UNSIGNED
)
302 subtype
= optab_vector_mixed_sign
;
303 /* Same as optab_vector_mixed_sign but flip the operands. */
304 std::swap (op0
, op1
);
306 else if (sign1
== UNSIGNED
&& sign2
== SIGNED
)
307 subtype
= optab_vector_mixed_sign
;
312 = optab_for_tree_code (ops
->code
, TREE_TYPE (oprnd0
), subtype
);
316 = optab_for_tree_code (ops
->code
, TREE_TYPE (oprnd0
), optab_default
);
317 if (ops
->code
== WIDEN_MULT_PLUS_EXPR
318 || ops
->code
== WIDEN_MULT_MINUS_EXPR
)
319 icode
= find_widening_optab_handler (widen_pattern_optab
,
320 TYPE_MODE (TREE_TYPE (ops
->op2
)),
323 icode
= optab_handler (widen_pattern_optab
, tmode0
);
324 gcc_assert (icode
!= CODE_FOR_nothing
);
327 tmode1
= TYPE_MODE (TREE_TYPE (oprnd1
));
331 op1
= GEN_INT (TYPE_VECTOR_SUBPARTS (TREE_TYPE (oprnd0
)).to_constant ());
335 /* The last operand is of a wider mode than the rest of the operands. */
340 gcc_assert (tmode1
== tmode0
);
342 wmode
= TYPE_MODE (TREE_TYPE (oprnd2
));
346 create_output_operand (&eops
[op
++], target
, TYPE_MODE (ops
->type
));
347 create_convert_operand_from (&eops
[op
++], op0
, tmode0
, unsignedp
);
349 create_convert_operand_from (&eops
[op
++], op1
, tmode1
, unsignedp
);
351 create_convert_operand_from (&eops
[op
++], wide_op
, wmode
, unsignedp
);
352 expand_insn (icode
, op
, eops
);
353 return eops
[0].value
;
356 /* Generate code to perform an operation specified by TERNARY_OPTAB
357 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
359 UNSIGNEDP is for the case where we have to widen the operands
360 to perform the operation. It says to use zero-extension.
362 If TARGET is nonzero, the value
363 is generated there, if it is convenient to do so.
364 In all cases an rtx is returned for the locus of the value;
365 this may or may not be TARGET. */
368 expand_ternary_op (machine_mode mode
, optab ternary_optab
, rtx op0
,
369 rtx op1
, rtx op2
, rtx target
, int unsignedp
)
371 class expand_operand ops
[4];
372 enum insn_code icode
= optab_handler (ternary_optab
, mode
);
374 gcc_assert (optab_handler (ternary_optab
, mode
) != CODE_FOR_nothing
);
376 create_output_operand (&ops
[0], target
, mode
);
377 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
378 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
379 create_convert_operand_from (&ops
[3], op2
, mode
, unsignedp
);
380 expand_insn (icode
, 4, ops
);
385 /* Like expand_binop, but return a constant rtx if the result can be
386 calculated at compile time. The arguments and return value are
387 otherwise the same as for expand_binop. */
390 simplify_expand_binop (machine_mode mode
, optab binoptab
,
391 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
392 enum optab_methods methods
)
394 if (CONSTANT_P (op0
) && CONSTANT_P (op1
))
396 rtx x
= simplify_binary_operation (optab_to_code (binoptab
),
402 return expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
);
405 /* Like simplify_expand_binop, but always put the result in TARGET.
406 Return true if the expansion succeeded. */
409 force_expand_binop (machine_mode mode
, optab binoptab
,
410 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
411 enum optab_methods methods
)
413 rtx x
= simplify_expand_binop (mode
, binoptab
, op0
, op1
,
414 target
, unsignedp
, methods
);
418 emit_move_insn (target
, x
);
422 /* Create a new vector value in VMODE with all elements set to OP. The
423 mode of OP must be the element mode of VMODE. If OP is a constant,
424 then the return value will be a constant. */
427 expand_vector_broadcast (machine_mode vmode
, rtx op
)
432 gcc_checking_assert (VECTOR_MODE_P (vmode
));
434 if (valid_for_const_vector_p (vmode
, op
))
435 return gen_const_vec_duplicate (vmode
, op
);
437 insn_code icode
= optab_handler (vec_duplicate_optab
, vmode
);
438 if (icode
!= CODE_FOR_nothing
)
440 class expand_operand ops
[2];
441 create_output_operand (&ops
[0], NULL_RTX
, vmode
);
442 create_input_operand (&ops
[1], op
, GET_MODE (op
));
443 expand_insn (icode
, 2, ops
);
447 if (!GET_MODE_NUNITS (vmode
).is_constant (&n
))
450 /* ??? If the target doesn't have a vec_init, then we have no easy way
451 of performing this operation. Most of this sort of generic support
452 is hidden away in the vector lowering support in gimple. */
453 icode
= convert_optab_handler (vec_init_optab
, vmode
,
454 GET_MODE_INNER (vmode
));
455 if (icode
== CODE_FOR_nothing
)
458 vec
= rtvec_alloc (n
);
459 for (int i
= 0; i
< n
; ++i
)
460 RTVEC_ELT (vec
, i
) = op
;
461 rtx ret
= gen_reg_rtx (vmode
);
462 emit_insn (GEN_FCN (icode
) (ret
, gen_rtx_PARALLEL (vmode
, vec
)));
467 /* This subroutine of expand_doubleword_shift handles the cases in which
468 the effective shift value is >= BITS_PER_WORD. The arguments and return
469 value are the same as for the parent routine, except that SUPERWORD_OP1
470 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
471 INTO_TARGET may be null if the caller has decided to calculate it. */
474 expand_superword_shift (optab binoptab
, rtx outof_input
, rtx superword_op1
,
475 rtx outof_target
, rtx into_target
,
476 int unsignedp
, enum optab_methods methods
)
478 if (into_target
!= 0)
479 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, superword_op1
,
480 into_target
, unsignedp
, methods
))
483 if (outof_target
!= 0)
485 /* For a signed right shift, we must fill OUTOF_TARGET with copies
486 of the sign bit, otherwise we must fill it with zeros. */
487 if (binoptab
!= ashr_optab
)
488 emit_move_insn (outof_target
, CONST0_RTX (word_mode
));
490 if (!force_expand_binop (word_mode
, binoptab
, outof_input
,
491 gen_int_shift_amount (word_mode
,
493 outof_target
, unsignedp
, methods
))
499 /* This subroutine of expand_doubleword_shift handles the cases in which
500 the effective shift value is < BITS_PER_WORD. The arguments and return
501 value are the same as for the parent routine. */
504 expand_subword_shift (scalar_int_mode op1_mode
, optab binoptab
,
505 rtx outof_input
, rtx into_input
, rtx op1
,
506 rtx outof_target
, rtx into_target
,
507 int unsignedp
, enum optab_methods methods
,
508 unsigned HOST_WIDE_INT shift_mask
)
510 optab reverse_unsigned_shift
, unsigned_shift
;
513 reverse_unsigned_shift
= (binoptab
== ashl_optab
? lshr_optab
: ashl_optab
);
514 unsigned_shift
= (binoptab
== ashl_optab
? ashl_optab
: lshr_optab
);
516 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
517 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
518 the opposite direction to BINOPTAB. */
519 if (CONSTANT_P (op1
) || shift_mask
>= BITS_PER_WORD
)
521 carries
= outof_input
;
522 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
,
523 op1_mode
), op1_mode
);
524 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
529 /* We must avoid shifting by BITS_PER_WORD bits since that is either
530 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
531 has unknown behavior. Do a single shift first, then shift by the
532 remainder. It's OK to use ~OP1 as the remainder if shift counts
533 are truncated to the mode size. */
534 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
535 outof_input
, const1_rtx
, 0, unsignedp
, methods
);
536 if (shift_mask
== BITS_PER_WORD
- 1)
538 tmp
= immed_wide_int_const
539 (wi::minus_one (GET_MODE_PRECISION (op1_mode
)), op1_mode
);
540 tmp
= simplify_expand_binop (op1_mode
, xor_optab
, op1
, tmp
,
545 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
- 1,
546 op1_mode
), op1_mode
);
547 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
551 if (tmp
== 0 || carries
== 0)
553 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
554 carries
, tmp
, 0, unsignedp
, methods
);
558 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
559 so the result can go directly into INTO_TARGET if convenient. */
560 tmp
= expand_binop (word_mode
, unsigned_shift
, into_input
, op1
,
561 into_target
, unsignedp
, methods
);
565 /* Now OR in the bits carried over from OUTOF_INPUT. */
566 if (!force_expand_binop (word_mode
, ior_optab
, tmp
, carries
,
567 into_target
, unsignedp
, methods
))
570 /* Use a standard word_mode shift for the out-of half. */
571 if (outof_target
!= 0)
572 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
573 outof_target
, unsignedp
, methods
))
580 /* Try implementing expand_doubleword_shift using conditional moves.
581 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
582 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
583 are the shift counts to use in the former and latter case. All other
584 arguments are the same as the parent routine. */
587 expand_doubleword_shift_condmove (scalar_int_mode op1_mode
, optab binoptab
,
588 enum rtx_code cmp_code
, rtx cmp1
, rtx cmp2
,
589 rtx outof_input
, rtx into_input
,
590 rtx subword_op1
, rtx superword_op1
,
591 rtx outof_target
, rtx into_target
,
592 int unsignedp
, enum optab_methods methods
,
593 unsigned HOST_WIDE_INT shift_mask
)
595 rtx outof_superword
, into_superword
;
597 /* Put the superword version of the output into OUTOF_SUPERWORD and
599 outof_superword
= outof_target
!= 0 ? gen_reg_rtx (word_mode
) : 0;
600 if (outof_target
!= 0 && subword_op1
== superword_op1
)
602 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
603 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
604 into_superword
= outof_target
;
605 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
606 outof_superword
, 0, unsignedp
, methods
))
611 into_superword
= gen_reg_rtx (word_mode
);
612 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
613 outof_superword
, into_superword
,
618 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
619 if (!expand_subword_shift (op1_mode
, binoptab
,
620 outof_input
, into_input
, subword_op1
,
621 outof_target
, into_target
,
622 unsignedp
, methods
, shift_mask
))
625 /* Select between them. Do the INTO half first because INTO_SUPERWORD
626 might be the current value of OUTOF_TARGET. */
627 if (!emit_conditional_move (into_target
, { cmp_code
, cmp1
, cmp2
, op1_mode
},
628 into_target
, into_superword
, word_mode
, false))
631 if (outof_target
!= 0)
632 if (!emit_conditional_move (outof_target
,
633 { cmp_code
, cmp1
, cmp2
, op1_mode
},
634 outof_target
, outof_superword
,
641 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
642 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
643 input operand; the shift moves bits in the direction OUTOF_INPUT->
644 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
645 of the target. OP1 is the shift count and OP1_MODE is its mode.
646 If OP1 is constant, it will have been truncated as appropriate
647 and is known to be nonzero.
649 If SHIFT_MASK is zero, the result of word shifts is undefined when the
650 shift count is outside the range [0, BITS_PER_WORD). This routine must
651 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
653 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
654 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
655 fill with zeros or sign bits as appropriate.
657 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
658 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
659 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
660 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
663 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
664 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
665 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
666 function wants to calculate it itself.
668 Return true if the shift could be successfully synthesized. */
671 expand_doubleword_shift (scalar_int_mode op1_mode
, optab binoptab
,
672 rtx outof_input
, rtx into_input
, rtx op1
,
673 rtx outof_target
, rtx into_target
,
674 int unsignedp
, enum optab_methods methods
,
675 unsigned HOST_WIDE_INT shift_mask
)
677 rtx superword_op1
, tmp
, cmp1
, cmp2
;
678 enum rtx_code cmp_code
;
680 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
681 fill the result with sign or zero bits as appropriate. If so, the value
682 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
683 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
684 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
686 This isn't worthwhile for constant shifts since the optimizers will
687 cope better with in-range shift counts. */
688 if (shift_mask
>= BITS_PER_WORD
690 && !CONSTANT_P (op1
))
692 if (!expand_doubleword_shift (op1_mode
, binoptab
,
693 outof_input
, into_input
, op1
,
695 unsignedp
, methods
, shift_mask
))
697 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
698 outof_target
, unsignedp
, methods
))
703 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
704 is true when the effective shift value is less than BITS_PER_WORD.
705 Set SUPERWORD_OP1 to the shift count that should be used to shift
706 OUTOF_INPUT into INTO_TARGET when the condition is false. */
707 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
, op1_mode
), op1_mode
);
708 if (!CONSTANT_P (op1
) && shift_mask
== BITS_PER_WORD
- 1)
710 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
711 is a subword shift count. */
712 cmp1
= simplify_expand_binop (op1_mode
, and_optab
, op1
, tmp
,
714 cmp2
= CONST0_RTX (op1_mode
);
720 /* Set CMP1 to OP1 - BITS_PER_WORD. */
721 cmp1
= simplify_expand_binop (op1_mode
, sub_optab
, op1
, tmp
,
723 cmp2
= CONST0_RTX (op1_mode
);
725 superword_op1
= cmp1
;
730 /* If we can compute the condition at compile time, pick the
731 appropriate subroutine. */
732 tmp
= simplify_relational_operation (cmp_code
, SImode
, op1_mode
, cmp1
, cmp2
);
733 if (tmp
!= 0 && CONST_INT_P (tmp
))
735 if (tmp
== const0_rtx
)
736 return expand_superword_shift (binoptab
, outof_input
, superword_op1
,
737 outof_target
, into_target
,
740 return expand_subword_shift (op1_mode
, binoptab
,
741 outof_input
, into_input
, op1
,
742 outof_target
, into_target
,
743 unsignedp
, methods
, shift_mask
);
746 /* Try using conditional moves to generate straight-line code. */
747 if (HAVE_conditional_move
)
749 rtx_insn
*start
= get_last_insn ();
750 if (expand_doubleword_shift_condmove (op1_mode
, binoptab
,
751 cmp_code
, cmp1
, cmp2
,
752 outof_input
, into_input
,
754 outof_target
, into_target
,
755 unsignedp
, methods
, shift_mask
))
757 delete_insns_since (start
);
760 /* As a last resort, use branches to select the correct alternative. */
761 rtx_code_label
*subword_label
= gen_label_rtx ();
762 rtx_code_label
*done_label
= gen_label_rtx ();
765 do_compare_rtx_and_jump (cmp1
, cmp2
, cmp_code
, false, op1_mode
,
767 profile_probability::uninitialized ());
770 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
771 outof_target
, into_target
,
775 emit_jump_insn (targetm
.gen_jump (done_label
));
777 emit_label (subword_label
);
779 if (!expand_subword_shift (op1_mode
, binoptab
,
780 outof_input
, into_input
, op1
,
781 outof_target
, into_target
,
782 unsignedp
, methods
, shift_mask
))
785 emit_label (done_label
);
789 /* Subroutine of expand_binop. Perform a double word multiplication of
790 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
791 as the target's word_mode. This function return NULL_RTX if anything
792 goes wrong, in which case it may have already emitted instructions
793 which need to be deleted.
795 If we want to multiply two two-word values and have normal and widening
796 multiplies of single-word values, we can do this with three smaller
799 The multiplication proceeds as follows:
800 _______________________
801 [__op0_high_|__op0_low__]
802 _______________________
803 * [__op1_high_|__op1_low__]
804 _______________________________________________
805 _______________________
806 (1) [__op0_low__*__op1_low__]
807 _______________________
808 (2a) [__op0_low__*__op1_high_]
809 _______________________
810 (2b) [__op0_high_*__op1_low__]
811 _______________________
812 (3) [__op0_high_*__op1_high_]
815 This gives a 4-word result. Since we are only interested in the
816 lower 2 words, partial result (3) and the upper words of (2a) and
817 (2b) don't need to be calculated. Hence (2a) and (2b) can be
818 calculated using non-widening multiplication.
820 (1), however, needs to be calculated with an unsigned widening
821 multiplication. If this operation is not directly supported we
822 try using a signed widening multiplication and adjust the result.
823 This adjustment works as follows:
825 If both operands are positive then no adjustment is needed.
827 If the operands have different signs, for example op0_low < 0 and
828 op1_low >= 0, the instruction treats the most significant bit of
829 op0_low as a sign bit instead of a bit with significance
830 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
831 with 2**BITS_PER_WORD - op0_low, and two's complements the
832 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
835 Similarly, if both operands are negative, we need to add
836 (op0_low + op1_low) * 2**BITS_PER_WORD.
838 We use a trick to adjust quickly. We logically shift op0_low right
839 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
840 op0_high (op1_high) before it is used to calculate 2b (2a). If no
841 logical shift exists, we do an arithmetic right shift and subtract
845 expand_doubleword_mult (machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
846 bool umulp
, enum optab_methods methods
)
848 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
849 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
850 rtx wordm1
= (umulp
? NULL_RTX
851 : gen_int_shift_amount (word_mode
, BITS_PER_WORD
- 1));
852 rtx product
, adjust
, product_high
, temp
;
854 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
855 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
856 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
857 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
859 /* If we're using an unsigned multiply to directly compute the product
860 of the low-order words of the operands and perform any required
861 adjustments of the operands, we begin by trying two more multiplications
862 and then computing the appropriate sum.
864 We have checked above that the required addition is provided.
865 Full-word addition will normally always succeed, especially if
866 it is provided at all, so we don't worry about its failure. The
867 multiplication may well fail, however, so we do handle that. */
871 /* ??? This could be done with emit_store_flag where available. */
872 temp
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
873 NULL_RTX
, 1, methods
);
875 op0_high
= expand_binop (word_mode
, add_optab
, op0_high
, temp
,
876 NULL_RTX
, 0, OPTAB_DIRECT
);
879 temp
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
880 NULL_RTX
, 0, methods
);
883 op0_high
= expand_binop (word_mode
, sub_optab
, op0_high
, temp
,
884 NULL_RTX
, 0, OPTAB_DIRECT
);
891 adjust
= expand_binop (word_mode
, smul_optab
, op0_high
, op1_low
,
892 NULL_RTX
, 0, OPTAB_DIRECT
);
896 /* OP0_HIGH should now be dead. */
900 /* ??? This could be done with emit_store_flag where available. */
901 temp
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
902 NULL_RTX
, 1, methods
);
904 op1_high
= expand_binop (word_mode
, add_optab
, op1_high
, temp
,
905 NULL_RTX
, 0, OPTAB_DIRECT
);
908 temp
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
909 NULL_RTX
, 0, methods
);
912 op1_high
= expand_binop (word_mode
, sub_optab
, op1_high
, temp
,
913 NULL_RTX
, 0, OPTAB_DIRECT
);
920 temp
= expand_binop (word_mode
, smul_optab
, op1_high
, op0_low
,
921 NULL_RTX
, 0, OPTAB_DIRECT
);
925 /* OP1_HIGH should now be dead. */
927 adjust
= expand_binop (word_mode
, add_optab
, adjust
, temp
,
928 NULL_RTX
, 0, OPTAB_DIRECT
);
930 if (target
&& !REG_P (target
))
933 /* *_widen_optab needs to determine operand mode, make sure at least
934 one operand has non-VOID mode. */
935 if (GET_MODE (op0_low
) == VOIDmode
&& GET_MODE (op1_low
) == VOIDmode
)
936 op0_low
= force_reg (word_mode
, op0_low
);
939 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
940 target
, 1, OPTAB_DIRECT
);
942 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
943 target
, 1, OPTAB_DIRECT
);
948 product_high
= operand_subword (product
, high
, 1, mode
);
949 adjust
= expand_binop (word_mode
, add_optab
, product_high
, adjust
,
950 NULL_RTX
, 0, OPTAB_DIRECT
);
951 emit_move_insn (product_high
, adjust
);
955 /* Subroutine of expand_binop. Optimize unsigned double-word OP0 % OP1 for
956 constant OP1. If for some bit in [BITS_PER_WORD / 2, BITS_PER_WORD] range
957 (prefer higher bits) ((1w << bit) % OP1) == 1, then the modulo can be
958 computed in word-mode as ((OP0 & (bit - 1)) + ((OP0 >> bit) & (bit - 1))
959 + (OP0 >> (2 * bit))) % OP1. Whether we need to sum 2, 3 or 4 values
960 depends on the bit value, if 2, then carry from the addition needs to be
961 added too, i.e. like:
962 sum += __builtin_add_overflow (low, high, &sum)
964 Optimize signed double-word OP0 % OP1 similarly, just apply some correction
965 factor to the sum before doing unsigned remainder, in the form of
966 sum += (((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & const);
967 then perform unsigned
968 remainder = sum % OP1;
970 remainder += ((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1); */
973 expand_doubleword_mod (machine_mode mode
, rtx op0
, rtx op1
, bool unsignedp
)
975 if (INTVAL (op1
) <= 1 || (INTVAL (op1
) & 1) == 0)
978 rtx_insn
*last
= get_last_insn ();
979 for (int bit
= BITS_PER_WORD
; bit
>= BITS_PER_WORD
/ 2; bit
--)
981 wide_int w
= wi::shifted_mask (bit
, 1, false, 2 * BITS_PER_WORD
);
982 if (wi::ne_p (wi::umod_trunc (w
, INTVAL (op1
)), 1))
984 rtx sum
= NULL_RTX
, mask
= NULL_RTX
;
985 if (bit
== BITS_PER_WORD
)
987 /* For signed modulo we need to add correction to the sum
988 and that might again overflow. */
991 if (optab_handler (uaddv4_optab
, word_mode
) == CODE_FOR_nothing
)
993 tree wtype
= lang_hooks
.types
.type_for_mode (word_mode
, 1);
994 if (wtype
== NULL_TREE
)
996 tree ctype
= build_complex_type (wtype
);
997 if (TYPE_MODE (ctype
) != GET_MODE_COMPLEX_MODE (word_mode
))
999 machine_mode cmode
= TYPE_MODE (ctype
);
1000 rtx op00
= operand_subword_force (op0
, 0, mode
);
1001 rtx op01
= operand_subword_force (op0
, 1, mode
);
1002 rtx cres
= gen_rtx_CONCAT (cmode
, gen_reg_rtx (word_mode
),
1003 gen_reg_rtx (word_mode
));
1004 tree lhs
= make_tree (ctype
, cres
);
1005 tree arg0
= make_tree (wtype
, op00
);
1006 tree arg1
= make_tree (wtype
, op01
);
1007 expand_addsub_overflow (UNKNOWN_LOCATION
, PLUS_EXPR
, lhs
, arg0
,
1008 arg1
, true, true, true, false, NULL
);
1009 sum
= expand_simple_binop (word_mode
, PLUS
, XEXP (cres
, 0),
1010 XEXP (cres
, 1), NULL_RTX
, 1,
1012 if (sum
== NULL_RTX
)
1017 /* Code below uses GEN_INT, so we need the masks to be representable
1018 in HOST_WIDE_INTs. */
1019 if (bit
>= HOST_BITS_PER_WIDE_INT
)
1021 /* If op0 is e.g. -1 or -2 unsigned, then the 2 additions might
1022 overflow. Consider 64-bit -1ULL for word size 32, if we add
1023 0x7fffffffU + 0x7fffffffU + 3U, it wraps around to 1. */
1024 if (bit
== BITS_PER_WORD
- 1)
1027 int count
= (2 * BITS_PER_WORD
+ bit
- 1) / bit
;
1028 rtx sum_corr
= NULL_RTX
;
1032 /* For signed modulo, compute it as unsigned modulo of
1033 sum with a correction added to it if OP0 is negative,
1034 such that the result can be computed as unsigned
1035 remainder + ((OP1 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1). */
1036 w
= wi::min_value (2 * BITS_PER_WORD
, SIGNED
);
1037 wide_int wmod1
= wi::umod_trunc (w
, INTVAL (op1
));
1038 wide_int wmod2
= wi::smod_trunc (w
, INTVAL (op1
));
1039 /* wmod2 == -wmod1. */
1040 wmod2
= wmod2
+ (INTVAL (op1
) - 1);
1041 if (wi::ne_p (wmod1
, wmod2
))
1043 wide_int wcorr
= wmod2
- wmod1
;
1045 wcorr
= wcorr
+ INTVAL (op1
);
1046 /* Now verify if the count sums can't overflow, and punt
1048 w
= wi::mask (bit
, false, 2 * BITS_PER_WORD
);
1049 w
= w
* (count
- 1);
1050 w
= w
+ wi::mask (2 * BITS_PER_WORD
- (count
- 1) * bit
,
1051 false, 2 * BITS_PER_WORD
);
1053 w
= wi::lrshift (w
, BITS_PER_WORD
);
1054 if (wi::ne_p (w
, 0))
1057 mask
= operand_subword_force (op0
, WORDS_BIG_ENDIAN
? 0 : 1,
1059 mask
= expand_simple_binop (word_mode
, ASHIFTRT
, mask
,
1060 GEN_INT (BITS_PER_WORD
- 1),
1061 NULL_RTX
, 0, OPTAB_DIRECT
);
1062 if (mask
== NULL_RTX
)
1064 sum_corr
= immed_wide_int_const (wcorr
, word_mode
);
1065 sum_corr
= expand_simple_binop (word_mode
, AND
, mask
,
1066 sum_corr
, NULL_RTX
, 1,
1068 if (sum_corr
== NULL_RTX
)
1073 for (int i
= 0; i
< count
; i
++)
1077 v
= expand_simple_binop (mode
, LSHIFTRT
, v
, GEN_INT (i
* bit
),
1078 NULL_RTX
, 1, OPTAB_DIRECT
);
1081 v
= lowpart_subreg (word_mode
, v
, mode
);
1085 v
= expand_simple_binop (word_mode
, AND
, v
,
1086 GEN_INT ((HOST_WIDE_INT_1U
<< bit
)
1091 if (sum
== NULL_RTX
)
1094 sum
= expand_simple_binop (word_mode
, PLUS
, sum
, v
, NULL_RTX
,
1096 if (sum
== NULL_RTX
)
1101 sum
= expand_simple_binop (word_mode
, PLUS
, sum
, sum_corr
,
1102 NULL_RTX
, 1, OPTAB_DIRECT
);
1103 if (sum
== NULL_RTX
)
1107 rtx remainder
= expand_divmod (1, TRUNC_MOD_EXPR
, word_mode
, NULL
, NULL
,
1108 sum
, gen_int_mode (INTVAL (op1
),
1110 NULL_RTX
, 1, OPTAB_DIRECT
);
1111 if (remainder
== NULL_RTX
)
1116 if (mask
== NULL_RTX
)
1118 mask
= operand_subword_force (op0
, WORDS_BIG_ENDIAN
? 0 : 1,
1120 mask
= expand_simple_binop (word_mode
, ASHIFTRT
, mask
,
1121 GEN_INT (BITS_PER_WORD
- 1),
1122 NULL_RTX
, 0, OPTAB_DIRECT
);
1123 if (mask
== NULL_RTX
)
1126 mask
= expand_simple_binop (word_mode
, AND
, mask
,
1127 gen_int_mode (1 - INTVAL (op1
),
1129 NULL_RTX
, 1, OPTAB_DIRECT
);
1130 if (mask
== NULL_RTX
)
1132 remainder
= expand_simple_binop (word_mode
, PLUS
, remainder
,
1133 mask
, NULL_RTX
, 1, OPTAB_DIRECT
);
1134 if (remainder
== NULL_RTX
)
1138 remainder
= convert_modes (mode
, word_mode
, remainder
, unsignedp
);
1139 /* Punt if we need any library calls. */
1141 last
= NEXT_INSN (last
);
1143 last
= get_insns ();
1144 for (; last
; last
= NEXT_INSN (last
))
1152 /* Similarly to the above function, but compute both quotient and remainder.
1153 Quotient can be computed from the remainder as:
1154 rem = op0 % op1; // Handled using expand_doubleword_mod
1155 quot = (op0 - rem) * inv; // inv is multiplicative inverse of op1 modulo
1156 // 2 * BITS_PER_WORD
1158 We can also handle cases where op1 is a multiple of power of two constant
1159 and constant handled by expand_doubleword_mod.
1160 op11 = 1 << __builtin_ctz (op1);
1162 rem1 = op0 % op12; // Handled using expand_doubleword_mod
1163 quot1 = (op0 - rem1) * inv; // inv is multiplicative inverse of op12 modulo
1164 // 2 * BITS_PER_WORD
1165 rem = (quot1 % op11) * op12 + rem1;
1166 quot = quot1 / op11; */
1169 expand_doubleword_divmod (machine_mode mode
, rtx op0
, rtx op1
, rtx
*rem
,
1174 /* Negative dividend should have been optimized into positive,
1175 similarly modulo by 1 and modulo by power of two is optimized
1177 if (INTVAL (op1
) <= 1 || pow2p_hwi (INTVAL (op1
)))
1180 rtx op11
= const1_rtx
;
1182 if ((INTVAL (op1
) & 1) == 0)
1184 int bit
= ctz_hwi (INTVAL (op1
));
1185 op11
= GEN_INT (HOST_WIDE_INT_1
<< bit
);
1186 op12
= GEN_INT (INTVAL (op1
) >> bit
);
1189 rtx rem1
= expand_doubleword_mod (mode
, op0
, op12
, unsignedp
);
1190 if (rem1
== NULL_RTX
)
1193 int prec
= 2 * BITS_PER_WORD
;
1194 wide_int a
= wide_int::from (INTVAL (op12
), prec
+ 1, UNSIGNED
);
1195 wide_int b
= wi::shifted_mask (prec
, 1, false, prec
+ 1);
1196 wide_int m
= wide_int::from (wi::mod_inv (a
, b
), prec
, UNSIGNED
);
1197 rtx inv
= immed_wide_int_const (m
, mode
);
1199 rtx_insn
*last
= get_last_insn ();
1200 rtx quot1
= expand_simple_binop (mode
, MINUS
, op0
, rem1
,
1201 NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1202 if (quot1
== NULL_RTX
)
1205 quot1
= expand_simple_binop (mode
, MULT
, quot1
, inv
,
1206 NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1207 if (quot1
== NULL_RTX
)
1210 if (op11
!= const1_rtx
)
1212 rtx rem2
= expand_divmod (1, TRUNC_MOD_EXPR
, mode
, NULL
, NULL
, quot1
,
1213 op11
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1214 if (rem2
== NULL_RTX
)
1217 rem2
= expand_simple_binop (mode
, MULT
, rem2
, op12
, NULL_RTX
,
1218 unsignedp
, OPTAB_DIRECT
);
1219 if (rem2
== NULL_RTX
)
1222 rem2
= expand_simple_binop (mode
, PLUS
, rem2
, rem1
, NULL_RTX
,
1223 unsignedp
, OPTAB_DIRECT
);
1224 if (rem2
== NULL_RTX
)
1227 rtx quot2
= expand_divmod (0, TRUNC_DIV_EXPR
, mode
, NULL
, NULL
, quot1
,
1228 op11
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1229 if (quot2
== NULL_RTX
)
1236 /* Punt if we need any library calls. */
1238 last
= NEXT_INSN (last
);
1240 last
= get_insns ();
1241 for (; last
; last
= NEXT_INSN (last
))
1249 /* Wrapper around expand_binop which takes an rtx code to specify
1250 the operation to perform, not an optab pointer. All other
1251 arguments are the same. */
1253 expand_simple_binop (machine_mode mode
, enum rtx_code code
, rtx op0
,
1254 rtx op1
, rtx target
, int unsignedp
,
1255 enum optab_methods methods
)
1257 optab binop
= code_to_optab (code
);
1260 return expand_binop (mode
, binop
, op0
, op1
, target
, unsignedp
, methods
);
1263 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1264 binop. Order them according to commutative_operand_precedence and, if
1265 possible, try to put TARGET or a pseudo first. */
1267 swap_commutative_operands_with_target (rtx target
, rtx op0
, rtx op1
)
1269 int op0_prec
= commutative_operand_precedence (op0
);
1270 int op1_prec
= commutative_operand_precedence (op1
);
1272 if (op0_prec
< op1_prec
)
1275 if (op0_prec
> op1_prec
)
1278 /* With equal precedence, both orders are ok, but it is better if the
1279 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1280 if (target
== 0 || REG_P (target
))
1281 return (REG_P (op1
) && !REG_P (op0
)) || target
== op1
;
1283 return rtx_equal_p (op1
, target
);
1286 /* Return true if BINOPTAB implements a shift operation. */
1289 shift_optab_p (optab binoptab
)
1291 switch (optab_to_code (binoptab
))
1307 /* Return true if BINOPTAB implements a commutative binary operation. */
1310 commutative_optab_p (optab binoptab
)
1312 return (GET_RTX_CLASS (optab_to_code (binoptab
)) == RTX_COMM_ARITH
1313 || binoptab
== smul_widen_optab
1314 || binoptab
== umul_widen_optab
1315 || binoptab
== smul_highpart_optab
1316 || binoptab
== umul_highpart_optab
);
1319 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
1320 optimizing, and if the operand is a constant that costs more than
1321 1 instruction, force the constant into a register and return that
1322 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1325 avoid_expensive_constant (machine_mode mode
, optab binoptab
,
1326 int opn
, rtx x
, bool unsignedp
)
1328 bool speed
= optimize_insn_for_speed_p ();
1330 if (mode
!= VOIDmode
1333 && (rtx_cost (x
, mode
, optab_to_code (binoptab
), opn
, speed
)
1334 > set_src_cost (x
, mode
, speed
)))
1336 if (CONST_INT_P (x
))
1338 HOST_WIDE_INT intval
= trunc_int_for_mode (INTVAL (x
), mode
);
1339 if (intval
!= INTVAL (x
))
1340 x
= GEN_INT (intval
);
1343 x
= convert_modes (mode
, VOIDmode
, x
, unsignedp
);
1344 x
= force_reg (mode
, x
);
1349 /* Helper function for expand_binop: handle the case where there
1350 is an insn ICODE that directly implements the indicated operation.
1351 Returns null if this is not possible. */
1353 expand_binop_directly (enum insn_code icode
, machine_mode mode
, optab binoptab
,
1355 rtx target
, int unsignedp
, enum optab_methods methods
,
1358 machine_mode xmode0
= insn_data
[(int) icode
].operand
[1].mode
;
1359 machine_mode xmode1
= insn_data
[(int) icode
].operand
[2].mode
;
1360 machine_mode mode0
, mode1
, tmp_mode
;
1361 class expand_operand ops
[3];
1364 rtx xop0
= op0
, xop1
= op1
;
1365 bool canonicalize_op1
= false;
1367 /* If it is a commutative operator and the modes would match
1368 if we would swap the operands, we can save the conversions. */
1369 commutative_p
= commutative_optab_p (binoptab
);
1371 && GET_MODE (xop0
) != xmode0
&& GET_MODE (xop1
) != xmode1
1372 && GET_MODE (xop0
) == xmode1
&& GET_MODE (xop1
) == xmode0
)
1373 std::swap (xop0
, xop1
);
1375 /* If we are optimizing, force expensive constants into a register. */
1376 xop0
= avoid_expensive_constant (xmode0
, binoptab
, 0, xop0
, unsignedp
);
1377 if (!shift_optab_p (binoptab
))
1378 xop1
= avoid_expensive_constant (xmode1
, binoptab
, 1, xop1
, unsignedp
);
1380 /* Shifts and rotates often use a different mode for op1 from op0;
1381 for VOIDmode constants we don't know the mode, so force it
1382 to be canonicalized using convert_modes. */
1383 canonicalize_op1
= true;
1385 /* In case the insn wants input operands in modes different from
1386 those of the actual operands, convert the operands. It would
1387 seem that we don't need to convert CONST_INTs, but we do, so
1388 that they're properly zero-extended, sign-extended or truncated
1391 mode0
= GET_MODE (xop0
) != VOIDmode
? GET_MODE (xop0
) : mode
;
1392 if (xmode0
!= VOIDmode
&& xmode0
!= mode0
)
1394 xop0
= convert_modes (xmode0
, mode0
, xop0
, unsignedp
);
1398 mode1
= ((GET_MODE (xop1
) != VOIDmode
|| canonicalize_op1
)
1399 ? GET_MODE (xop1
) : mode
);
1400 if (xmode1
!= VOIDmode
&& xmode1
!= mode1
)
1402 xop1
= convert_modes (xmode1
, mode1
, xop1
, unsignedp
);
1406 /* If operation is commutative,
1407 try to make the first operand a register.
1408 Even better, try to make it the same as the target.
1409 Also try to make the last operand a constant. */
1411 && swap_commutative_operands_with_target (target
, xop0
, xop1
))
1412 std::swap (xop0
, xop1
);
1414 /* Now, if insn's predicates don't allow our operands, put them into
1417 if (binoptab
== vec_pack_trunc_optab
1418 || binoptab
== vec_pack_usat_optab
1419 || binoptab
== vec_pack_ssat_optab
1420 || binoptab
== vec_pack_ufix_trunc_optab
1421 || binoptab
== vec_pack_sfix_trunc_optab
1422 || binoptab
== vec_packu_float_optab
1423 || binoptab
== vec_packs_float_optab
)
1425 /* The mode of the result is different then the mode of the
1427 tmp_mode
= insn_data
[(int) icode
].operand
[0].mode
;
1428 if (VECTOR_MODE_P (mode
)
1429 && maybe_ne (GET_MODE_NUNITS (tmp_mode
), 2 * GET_MODE_NUNITS (mode
)))
1431 delete_insns_since (last
);
1438 create_output_operand (&ops
[0], target
, tmp_mode
);
1439 create_input_operand (&ops
[1], xop0
, mode0
);
1440 create_input_operand (&ops
[2], xop1
, mode1
);
1441 pat
= maybe_gen_insn (icode
, 3, ops
);
1444 /* If PAT is composed of more than one insn, try to add an appropriate
1445 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1446 operand, call expand_binop again, this time without a target. */
1447 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
1448 && ! add_equal_note (pat
, ops
[0].value
,
1449 optab_to_code (binoptab
),
1450 ops
[1].value
, ops
[2].value
, mode0
))
1452 delete_insns_since (last
);
1453 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
1454 unsignedp
, methods
);
1458 return ops
[0].value
;
1460 delete_insns_since (last
);
1464 /* Generate code to perform an operation specified by BINOPTAB
1465 on operands OP0 and OP1, with result having machine-mode MODE.
1467 UNSIGNEDP is for the case where we have to widen the operands
1468 to perform the operation. It says to use zero-extension.
1470 If TARGET is nonzero, the value
1471 is generated there, if it is convenient to do so.
1472 In all cases an rtx is returned for the locus of the value;
1473 this may or may not be TARGET. */
1476 expand_binop (machine_mode mode
, optab binoptab
, rtx op0
, rtx op1
,
1477 rtx target
, int unsignedp
, enum optab_methods methods
)
1479 enum optab_methods next_methods
1480 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
1481 ? OPTAB_WIDEN
: methods
);
1482 enum mode_class mclass
;
1483 enum insn_code icode
;
1484 machine_mode wider_mode
;
1485 scalar_int_mode int_mode
;
1488 rtx_insn
*entry_last
= get_last_insn ();
1491 mclass
= GET_MODE_CLASS (mode
);
1493 /* If subtracting an integer constant, convert this into an addition of
1494 the negated constant. */
1496 if (binoptab
== sub_optab
&& CONST_INT_P (op1
))
1498 op1
= negate_rtx (mode
, op1
);
1499 binoptab
= add_optab
;
1501 /* For shifts, constant invalid op1 might be expanded from different
1502 mode than MODE. As those are invalid, force them to a register
1503 to avoid further problems during expansion. */
1504 else if (CONST_INT_P (op1
)
1505 && shift_optab_p (binoptab
)
1506 && UINTVAL (op1
) >= GET_MODE_BITSIZE (GET_MODE_INNER (mode
)))
1508 op1
= gen_int_mode (INTVAL (op1
), GET_MODE_INNER (mode
));
1509 op1
= force_reg (GET_MODE_INNER (mode
), op1
);
1512 /* Record where to delete back to if we backtrack. */
1513 last
= get_last_insn ();
1515 /* If we can do it with a three-operand insn, do so. */
1517 if (methods
!= OPTAB_MUST_WIDEN
)
1519 if (convert_optab_p (binoptab
))
1521 machine_mode from_mode
= widened_mode (mode
, op0
, op1
);
1522 icode
= find_widening_optab_handler (binoptab
, mode
, from_mode
);
1525 icode
= optab_handler (binoptab
, mode
);
1526 if (icode
!= CODE_FOR_nothing
)
1528 temp
= expand_binop_directly (icode
, mode
, binoptab
, op0
, op1
,
1529 target
, unsignedp
, methods
, last
);
1535 /* If we were trying to rotate, and that didn't work, try rotating
1536 the other direction before falling back to shifts and bitwise-or. */
1537 if (((binoptab
== rotl_optab
1538 && (icode
= optab_handler (rotr_optab
, mode
)) != CODE_FOR_nothing
)
1539 || (binoptab
== rotr_optab
1540 && (icode
= optab_handler (rotl_optab
, mode
)) != CODE_FOR_nothing
))
1541 && is_int_mode (mode
, &int_mode
))
1543 optab otheroptab
= (binoptab
== rotl_optab
? rotr_optab
: rotl_optab
);
1545 unsigned int bits
= GET_MODE_PRECISION (int_mode
);
1547 if (CONST_INT_P (op1
))
1548 newop1
= gen_int_shift_amount (int_mode
, bits
- INTVAL (op1
));
1549 else if (targetm
.shift_truncation_mask (int_mode
) == bits
- 1)
1550 newop1
= negate_rtx (GET_MODE (op1
), op1
);
1552 newop1
= expand_binop (GET_MODE (op1
), sub_optab
,
1553 gen_int_mode (bits
, GET_MODE (op1
)), op1
,
1554 NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1556 temp
= expand_binop_directly (icode
, int_mode
, otheroptab
, op0
, newop1
,
1557 target
, unsignedp
, methods
, last
);
1562 /* If this is a multiply, see if we can do a widening operation that
1563 takes operands of this mode and makes a wider mode. */
1565 if (binoptab
== smul_optab
1566 && GET_MODE_2XWIDER_MODE (mode
).exists (&wider_mode
)
1567 && (convert_optab_handler ((unsignedp
1569 : smul_widen_optab
),
1570 wider_mode
, mode
) != CODE_FOR_nothing
))
1572 /* *_widen_optab needs to determine operand mode, make sure at least
1573 one operand has non-VOID mode. */
1574 if (GET_MODE (op0
) == VOIDmode
&& GET_MODE (op1
) == VOIDmode
)
1575 op0
= force_reg (mode
, op0
);
1576 temp
= expand_binop (wider_mode
,
1577 unsignedp
? umul_widen_optab
: smul_widen_optab
,
1578 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1582 if (GET_MODE_CLASS (mode
) == MODE_INT
1583 && TRULY_NOOP_TRUNCATION_MODES_P (mode
, GET_MODE (temp
)))
1584 return gen_lowpart (mode
, temp
);
1586 return convert_to_mode (mode
, temp
, unsignedp
);
1590 /* If this is a vector shift by a scalar, see if we can do a vector
1591 shift by a vector. If so, broadcast the scalar into a vector. */
1592 if (mclass
== MODE_VECTOR_INT
)
1594 optab otheroptab
= unknown_optab
;
1596 if (binoptab
== ashl_optab
)
1597 otheroptab
= vashl_optab
;
1598 else if (binoptab
== ashr_optab
)
1599 otheroptab
= vashr_optab
;
1600 else if (binoptab
== lshr_optab
)
1601 otheroptab
= vlshr_optab
;
1602 else if (binoptab
== rotl_optab
)
1603 otheroptab
= vrotl_optab
;
1604 else if (binoptab
== rotr_optab
)
1605 otheroptab
= vrotr_optab
;
1608 && (icode
= optab_handler (otheroptab
, mode
)) != CODE_FOR_nothing
)
1610 /* The scalar may have been extended to be too wide. Truncate
1611 it back to the proper size to fit in the broadcast vector. */
1612 scalar_mode inner_mode
= GET_MODE_INNER (mode
);
1613 if (!CONST_INT_P (op1
)
1614 && (GET_MODE_BITSIZE (as_a
<scalar_int_mode
> (GET_MODE (op1
)))
1615 > GET_MODE_BITSIZE (inner_mode
)))
1616 op1
= force_reg (inner_mode
,
1617 simplify_gen_unary (TRUNCATE
, inner_mode
, op1
,
1619 rtx vop1
= expand_vector_broadcast (mode
, op1
);
1622 temp
= expand_binop_directly (icode
, mode
, otheroptab
, op0
, vop1
,
1623 target
, unsignedp
, methods
, last
);
1630 /* Look for a wider mode of the same class for which we think we
1631 can open-code the operation. Check for a widening multiply at the
1632 wider mode as well. */
1634 if (CLASS_HAS_WIDER_MODES_P (mclass
)
1635 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
1636 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
1638 machine_mode next_mode
;
1639 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
1640 || (binoptab
== smul_optab
1641 && GET_MODE_WIDER_MODE (wider_mode
).exists (&next_mode
)
1642 && (find_widening_optab_handler ((unsignedp
1644 : smul_widen_optab
),
1646 != CODE_FOR_nothing
)))
1648 rtx xop0
= op0
, xop1
= op1
;
1651 /* For certain integer operations, we need not actually extend
1652 the narrow operands, as long as we will truncate
1653 the results to the same narrowness. */
1655 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1656 || binoptab
== xor_optab
1657 || binoptab
== add_optab
|| binoptab
== sub_optab
1658 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1659 && mclass
== MODE_INT
)
1662 xop0
= avoid_expensive_constant (mode
, binoptab
, 0,
1664 if (binoptab
!= ashl_optab
)
1665 xop1
= avoid_expensive_constant (mode
, binoptab
, 1,
1669 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
1671 /* The second operand of a shift must always be extended. */
1672 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1673 no_extend
&& binoptab
!= ashl_optab
);
1675 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1676 unsignedp
, OPTAB_DIRECT
);
1679 if (mclass
!= MODE_INT
1680 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
1683 target
= gen_reg_rtx (mode
);
1684 convert_move (target
, temp
, 0);
1688 return gen_lowpart (mode
, temp
);
1691 delete_insns_since (last
);
1695 /* If operation is commutative,
1696 try to make the first operand a register.
1697 Even better, try to make it the same as the target.
1698 Also try to make the last operand a constant. */
1699 if (commutative_optab_p (binoptab
)
1700 && swap_commutative_operands_with_target (target
, op0
, op1
))
1701 std::swap (op0
, op1
);
1703 /* These can be done a word at a time. */
1704 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
1705 && is_int_mode (mode
, &int_mode
)
1706 && GET_MODE_SIZE (int_mode
) > UNITS_PER_WORD
1707 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1712 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1713 won't be accurate, so use a new target. */
1717 || reg_overlap_mentioned_p (target
, op0
)
1718 || reg_overlap_mentioned_p (target
, op1
)
1719 || !valid_multiword_target_p (target
))
1720 target
= gen_reg_rtx (int_mode
);
1724 /* Do the actual arithmetic. */
1725 machine_mode op0_mode
= GET_MODE (op0
);
1726 machine_mode op1_mode
= GET_MODE (op1
);
1727 if (op0_mode
== VOIDmode
)
1728 op0_mode
= int_mode
;
1729 if (op1_mode
== VOIDmode
)
1730 op1_mode
= int_mode
;
1731 for (i
= 0; i
< GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
; i
++)
1733 rtx target_piece
= operand_subword (target
, i
, 1, int_mode
);
1734 rtx x
= expand_binop (word_mode
, binoptab
,
1735 operand_subword_force (op0
, i
, op0_mode
),
1736 operand_subword_force (op1
, i
, op1_mode
),
1737 target_piece
, unsignedp
, next_methods
);
1742 if (target_piece
!= x
)
1743 emit_move_insn (target_piece
, x
);
1746 insns
= get_insns ();
1749 if (i
== GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
)
1756 /* Synthesize double word shifts from single word shifts. */
1757 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
1758 || binoptab
== ashr_optab
)
1759 && is_int_mode (mode
, &int_mode
)
1760 && (CONST_INT_P (op1
) || optimize_insn_for_speed_p ())
1761 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
1762 && GET_MODE_PRECISION (int_mode
) == GET_MODE_BITSIZE (int_mode
)
1763 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
1764 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1765 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1767 unsigned HOST_WIDE_INT shift_mask
, double_shift_mask
;
1768 scalar_int_mode op1_mode
;
1770 double_shift_mask
= targetm
.shift_truncation_mask (int_mode
);
1771 shift_mask
= targetm
.shift_truncation_mask (word_mode
);
1772 op1_mode
= (GET_MODE (op1
) != VOIDmode
1773 ? as_a
<scalar_int_mode
> (GET_MODE (op1
))
1776 /* Apply the truncation to constant shifts. */
1777 if (double_shift_mask
> 0 && CONST_INT_P (op1
))
1778 op1
= gen_int_mode (INTVAL (op1
) & double_shift_mask
, op1_mode
);
1780 if (op1
== CONST0_RTX (op1_mode
))
1783 /* Make sure that this is a combination that expand_doubleword_shift
1784 can handle. See the comments there for details. */
1785 if (double_shift_mask
== 0
1786 || (shift_mask
== BITS_PER_WORD
- 1
1787 && double_shift_mask
== BITS_PER_WORD
* 2 - 1))
1790 rtx into_target
, outof_target
;
1791 rtx into_input
, outof_input
;
1792 int left_shift
, outof_word
;
1794 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1795 won't be accurate, so use a new target. */
1799 || reg_overlap_mentioned_p (target
, op0
)
1800 || reg_overlap_mentioned_p (target
, op1
)
1801 || !valid_multiword_target_p (target
))
1802 target
= gen_reg_rtx (int_mode
);
1806 /* OUTOF_* is the word we are shifting bits away from, and
1807 INTO_* is the word that we are shifting bits towards, thus
1808 they differ depending on the direction of the shift and
1809 WORDS_BIG_ENDIAN. */
1811 left_shift
= binoptab
== ashl_optab
;
1812 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1814 outof_target
= operand_subword (target
, outof_word
, 1, int_mode
);
1815 into_target
= operand_subword (target
, 1 - outof_word
, 1, int_mode
);
1817 outof_input
= operand_subword_force (op0
, outof_word
, int_mode
);
1818 into_input
= operand_subword_force (op0
, 1 - outof_word
, int_mode
);
1820 if (expand_doubleword_shift (op1_mode
, binoptab
,
1821 outof_input
, into_input
, op1
,
1822 outof_target
, into_target
,
1823 unsignedp
, next_methods
, shift_mask
))
1825 insns
= get_insns ();
1835 /* Synthesize double word rotates from single word shifts. */
1836 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
1837 && is_int_mode (mode
, &int_mode
)
1838 && CONST_INT_P (op1
)
1839 && GET_MODE_PRECISION (int_mode
) == 2 * BITS_PER_WORD
1840 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1841 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1844 rtx into_target
, outof_target
;
1845 rtx into_input
, outof_input
;
1847 int shift_count
, left_shift
, outof_word
;
1849 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1850 won't be accurate, so use a new target. Do this also if target is not
1851 a REG, first because having a register instead may open optimization
1852 opportunities, and second because if target and op0 happen to be MEMs
1853 designating the same location, we would risk clobbering it too early
1854 in the code sequence we generate below. */
1859 || reg_overlap_mentioned_p (target
, op0
)
1860 || reg_overlap_mentioned_p (target
, op1
)
1861 || !valid_multiword_target_p (target
))
1862 target
= gen_reg_rtx (int_mode
);
1866 shift_count
= INTVAL (op1
);
1868 /* OUTOF_* is the word we are shifting bits away from, and
1869 INTO_* is the word that we are shifting bits towards, thus
1870 they differ depending on the direction of the shift and
1871 WORDS_BIG_ENDIAN. */
1873 left_shift
= (binoptab
== rotl_optab
);
1874 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1876 outof_target
= operand_subword (target
, outof_word
, 1, int_mode
);
1877 into_target
= operand_subword (target
, 1 - outof_word
, 1, int_mode
);
1879 outof_input
= operand_subword_force (op0
, outof_word
, int_mode
);
1880 into_input
= operand_subword_force (op0
, 1 - outof_word
, int_mode
);
1882 if (shift_count
== BITS_PER_WORD
)
1884 /* This is just a word swap. */
1885 emit_move_insn (outof_target
, into_input
);
1886 emit_move_insn (into_target
, outof_input
);
1891 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1892 HOST_WIDE_INT first_shift_count
, second_shift_count
;
1893 optab reverse_unsigned_shift
, unsigned_shift
;
1895 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1896 ? lshr_optab
: ashl_optab
);
1898 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1899 ? ashl_optab
: lshr_optab
);
1901 if (shift_count
> BITS_PER_WORD
)
1903 first_shift_count
= shift_count
- BITS_PER_WORD
;
1904 second_shift_count
= 2 * BITS_PER_WORD
- shift_count
;
1908 first_shift_count
= BITS_PER_WORD
- shift_count
;
1909 second_shift_count
= shift_count
;
1911 rtx first_shift_count_rtx
1912 = gen_int_shift_amount (word_mode
, first_shift_count
);
1913 rtx second_shift_count_rtx
1914 = gen_int_shift_amount (word_mode
, second_shift_count
);
1916 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1917 outof_input
, first_shift_count_rtx
,
1918 NULL_RTX
, unsignedp
, next_methods
);
1919 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1920 into_input
, second_shift_count_rtx
,
1921 NULL_RTX
, unsignedp
, next_methods
);
1923 if (into_temp1
!= 0 && into_temp2
!= 0)
1924 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1925 into_target
, unsignedp
, next_methods
);
1929 if (inter
!= 0 && inter
!= into_target
)
1930 emit_move_insn (into_target
, inter
);
1932 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1933 into_input
, first_shift_count_rtx
,
1934 NULL_RTX
, unsignedp
, next_methods
);
1935 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1936 outof_input
, second_shift_count_rtx
,
1937 NULL_RTX
, unsignedp
, next_methods
);
1939 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1940 inter
= expand_binop (word_mode
, ior_optab
,
1941 outof_temp1
, outof_temp2
,
1942 outof_target
, unsignedp
, next_methods
);
1944 if (inter
!= 0 && inter
!= outof_target
)
1945 emit_move_insn (outof_target
, inter
);
1948 insns
= get_insns ();
1958 /* These can be done a word at a time by propagating carries. */
1959 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1960 && is_int_mode (mode
, &int_mode
)
1961 && GET_MODE_SIZE (int_mode
) >= 2 * UNITS_PER_WORD
1962 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1965 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1966 const unsigned int nwords
= GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
;
1967 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1968 rtx xop0
, xop1
, xtarget
;
1970 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1971 value is one of those, use it. Otherwise, use 1 since it is the
1972 one easiest to get. */
1973 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1974 int normalizep
= STORE_FLAG_VALUE
;
1979 /* Prepare the operands. */
1980 xop0
= force_reg (int_mode
, op0
);
1981 xop1
= force_reg (int_mode
, op1
);
1983 xtarget
= gen_reg_rtx (int_mode
);
1985 if (target
== 0 || !REG_P (target
) || !valid_multiword_target_p (target
))
1988 /* Indicate for flow that the entire target reg is being set. */
1990 emit_clobber (xtarget
);
1992 /* Do the actual arithmetic. */
1993 for (i
= 0; i
< nwords
; i
++)
1995 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
1996 rtx target_piece
= operand_subword (xtarget
, index
, 1, int_mode
);
1997 rtx op0_piece
= operand_subword_force (xop0
, index
, int_mode
);
1998 rtx op1_piece
= operand_subword_force (xop1
, index
, int_mode
);
2001 /* Main add/subtract of the input operands. */
2002 x
= expand_binop (word_mode
, binoptab
,
2003 op0_piece
, op1_piece
,
2004 target_piece
, unsignedp
, next_methods
);
2010 /* Store carry from main add/subtract. */
2011 carry_out
= gen_reg_rtx (word_mode
);
2012 carry_out
= emit_store_flag_force (carry_out
,
2013 (binoptab
== add_optab
2016 word_mode
, 1, normalizep
);
2023 /* Add/subtract previous carry to main result. */
2024 newx
= expand_binop (word_mode
,
2025 normalizep
== 1 ? binoptab
: otheroptab
,
2027 NULL_RTX
, 1, next_methods
);
2031 /* Get out carry from adding/subtracting carry in. */
2032 rtx carry_tmp
= gen_reg_rtx (word_mode
);
2033 carry_tmp
= emit_store_flag_force (carry_tmp
,
2034 (binoptab
== add_optab
2037 word_mode
, 1, normalizep
);
2039 /* Logical-ior the two poss. carry together. */
2040 carry_out
= expand_binop (word_mode
, ior_optab
,
2041 carry_out
, carry_tmp
,
2042 carry_out
, 0, next_methods
);
2046 emit_move_insn (target_piece
, newx
);
2050 if (x
!= target_piece
)
2051 emit_move_insn (target_piece
, x
);
2054 carry_in
= carry_out
;
2057 if (i
== GET_MODE_BITSIZE (int_mode
) / (unsigned) BITS_PER_WORD
)
2059 if (optab_handler (mov_optab
, int_mode
) != CODE_FOR_nothing
2060 || ! rtx_equal_p (target
, xtarget
))
2062 rtx_insn
*temp
= emit_move_insn (target
, xtarget
);
2064 set_dst_reg_note (temp
, REG_EQUAL
,
2065 gen_rtx_fmt_ee (optab_to_code (binoptab
),
2066 int_mode
, copy_rtx (xop0
),
2077 delete_insns_since (last
);
2080 /* Attempt to synthesize double word multiplies using a sequence of word
2081 mode multiplications. We first attempt to generate a sequence using a
2082 more efficient unsigned widening multiply, and if that fails we then
2083 try using a signed widening multiply. */
2085 if (binoptab
== smul_optab
2086 && is_int_mode (mode
, &int_mode
)
2087 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
2088 && optab_handler (smul_optab
, word_mode
) != CODE_FOR_nothing
2089 && optab_handler (add_optab
, word_mode
) != CODE_FOR_nothing
)
2091 rtx product
= NULL_RTX
;
2092 if (convert_optab_handler (umul_widen_optab
, int_mode
, word_mode
)
2093 != CODE_FOR_nothing
)
2095 product
= expand_doubleword_mult (int_mode
, op0
, op1
, target
,
2098 delete_insns_since (last
);
2101 if (product
== NULL_RTX
2102 && (convert_optab_handler (smul_widen_optab
, int_mode
, word_mode
)
2103 != CODE_FOR_nothing
))
2105 product
= expand_doubleword_mult (int_mode
, op0
, op1
, target
,
2108 delete_insns_since (last
);
2111 if (product
!= NULL_RTX
)
2113 if (optab_handler (mov_optab
, int_mode
) != CODE_FOR_nothing
)
2115 rtx_insn
*move
= emit_move_insn (target
? target
: product
,
2117 set_dst_reg_note (move
,
2119 gen_rtx_fmt_ee (MULT
, int_mode
,
2122 target
? target
: product
);
2128 /* Attempt to synthetize double word modulo by constant divisor. */
2129 if ((binoptab
== umod_optab
2130 || binoptab
== smod_optab
2131 || binoptab
== udiv_optab
2132 || binoptab
== sdiv_optab
)
2134 && CONST_INT_P (op1
)
2135 && is_int_mode (mode
, &int_mode
)
2136 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
2137 && optab_handler ((binoptab
== umod_optab
|| binoptab
== udiv_optab
)
2138 ? udivmod_optab
: sdivmod_optab
,
2139 int_mode
) == CODE_FOR_nothing
2140 && optab_handler (and_optab
, word_mode
) != CODE_FOR_nothing
2141 && optab_handler (add_optab
, word_mode
) != CODE_FOR_nothing
2142 && optimize_insn_for_speed_p ())
2145 if ((binoptab
== umod_optab
|| binoptab
== smod_optab
)
2146 && (INTVAL (op1
) & 1) == 0)
2147 res
= expand_doubleword_mod (int_mode
, op0
, op1
,
2148 binoptab
== umod_optab
);
2151 rtx quot
= expand_doubleword_divmod (int_mode
, op0
, op1
, &res
,
2152 binoptab
== umod_optab
2153 || binoptab
== udiv_optab
);
2154 if (quot
== NULL_RTX
)
2156 else if (binoptab
== udiv_optab
|| binoptab
== sdiv_optab
)
2159 if (res
!= NULL_RTX
)
2161 if (optab_handler (mov_optab
, int_mode
) != CODE_FOR_nothing
)
2163 rtx_insn
*move
= emit_move_insn (target
? target
: res
,
2165 set_dst_reg_note (move
, REG_EQUAL
,
2166 gen_rtx_fmt_ee (optab_to_code (binoptab
),
2167 int_mode
, copy_rtx (op0
), op1
),
2168 target
? target
: res
);
2173 delete_insns_since (last
);
2176 /* It can't be open-coded in this mode.
2177 Use a library call if one is available and caller says that's ok. */
2179 libfunc
= optab_libfunc (binoptab
, mode
);
2181 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
2185 machine_mode op1_mode
= mode
;
2190 if (shift_optab_p (binoptab
))
2192 op1_mode
= targetm
.libgcc_shift_count_mode ();
2193 /* Specify unsigned here,
2194 since negative shift counts are meaningless. */
2195 op1x
= convert_to_mode (op1_mode
, op1
, 1);
2198 if (GET_MODE (op0
) != VOIDmode
2199 && GET_MODE (op0
) != mode
)
2200 op0
= convert_to_mode (mode
, op0
, unsignedp
);
2202 /* Pass 1 for NO_QUEUE so we don't lose any increments
2203 if the libcall is cse'd or moved. */
2204 value
= emit_library_call_value (libfunc
,
2205 NULL_RTX
, LCT_CONST
, mode
,
2206 op0
, mode
, op1x
, op1_mode
);
2208 insns
= get_insns ();
2211 bool trapv
= trapv_binoptab_p (binoptab
);
2212 target
= gen_reg_rtx (mode
);
2213 emit_libcall_block_1 (insns
, target
, value
,
2215 : gen_rtx_fmt_ee (optab_to_code (binoptab
),
2216 mode
, op0
, op1
), trapv
);
2221 delete_insns_since (last
);
2223 /* It can't be done in this mode. Can we do it in a wider mode? */
2225 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
2226 || methods
== OPTAB_MUST_WIDEN
))
2228 /* Caller says, don't even try. */
2229 delete_insns_since (entry_last
);
2233 /* Compute the value of METHODS to pass to recursive calls.
2234 Don't allow widening to be tried recursively. */
2236 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
2238 /* Look for a wider mode of the same class for which it appears we can do
2241 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2243 /* This code doesn't make sense for conversion optabs, since we
2244 wouldn't then want to extend the operands to be the same size
2246 gcc_assert (!convert_optab_p (binoptab
));
2247 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
2249 if (optab_handler (binoptab
, wider_mode
)
2250 || (methods
== OPTAB_LIB
2251 && optab_libfunc (binoptab
, wider_mode
)))
2253 rtx xop0
= op0
, xop1
= op1
;
2256 /* For certain integer operations, we need not actually extend
2257 the narrow operands, as long as we will truncate
2258 the results to the same narrowness. */
2260 if ((binoptab
== ior_optab
|| binoptab
== and_optab
2261 || binoptab
== xor_optab
2262 || binoptab
== add_optab
|| binoptab
== sub_optab
2263 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
2264 && mclass
== MODE_INT
)
2267 xop0
= widen_operand (xop0
, wider_mode
, mode
,
2268 unsignedp
, no_extend
);
2270 /* The second operand of a shift must always be extended. */
2271 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
2272 no_extend
&& binoptab
!= ashl_optab
);
2274 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
2275 unsignedp
, methods
);
2278 if (mclass
!= MODE_INT
2279 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
2282 target
= gen_reg_rtx (mode
);
2283 convert_move (target
, temp
, 0);
2287 return gen_lowpart (mode
, temp
);
2290 delete_insns_since (last
);
2295 delete_insns_since (entry_last
);
2299 /* Expand a binary operator which has both signed and unsigned forms.
2300 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2303 If we widen unsigned operands, we may use a signed wider operation instead
2304 of an unsigned wider operation, since the result would be the same. */
2307 sign_expand_binop (machine_mode mode
, optab uoptab
, optab soptab
,
2308 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
2309 enum optab_methods methods
)
2312 optab direct_optab
= unsignedp
? uoptab
: soptab
;
2315 /* Do it without widening, if possible. */
2316 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
2317 unsignedp
, OPTAB_DIRECT
);
2318 if (temp
|| methods
== OPTAB_DIRECT
)
2321 /* Try widening to a signed int. Disable any direct use of any
2322 signed insn in the current mode. */
2323 save_enable
= swap_optab_enable (soptab
, mode
, false);
2325 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
2326 unsignedp
, OPTAB_WIDEN
);
2328 /* For unsigned operands, try widening to an unsigned int. */
2329 if (!temp
&& unsignedp
)
2330 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
2331 unsignedp
, OPTAB_WIDEN
);
2332 if (temp
|| methods
== OPTAB_WIDEN
)
2335 /* Use the right width libcall if that exists. */
2336 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
2337 unsignedp
, OPTAB_LIB
);
2338 if (temp
|| methods
== OPTAB_LIB
)
2341 /* Must widen and use a libcall, use either signed or unsigned. */
2342 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
2343 unsignedp
, methods
);
2344 if (!temp
&& unsignedp
)
2345 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
2346 unsignedp
, methods
);
2349 /* Undo the fiddling above. */
2351 swap_optab_enable (soptab
, mode
, true);
2355 /* Generate code to perform an operation specified by UNOPPTAB
2356 on operand OP0, with two results to TARG0 and TARG1.
2357 We assume that the order of the operands for the instruction
2358 is TARG0, TARG1, OP0.
2360 Either TARG0 or TARG1 may be zero, but what that means is that
2361 the result is not actually wanted. We will generate it into
2362 a dummy pseudo-reg and discard it. They may not both be zero.
2364 Returns 1 if this operation can be performed; 0 if not. */
2367 expand_twoval_unop (optab unoptab
, rtx op0
, rtx targ0
, rtx targ1
,
2370 machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2371 enum mode_class mclass
;
2372 machine_mode wider_mode
;
2373 rtx_insn
*entry_last
= get_last_insn ();
2376 mclass
= GET_MODE_CLASS (mode
);
2379 targ0
= gen_reg_rtx (mode
);
2381 targ1
= gen_reg_rtx (mode
);
2383 /* Record where to go back to if we fail. */
2384 last
= get_last_insn ();
2386 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
2388 class expand_operand ops
[3];
2389 enum insn_code icode
= optab_handler (unoptab
, mode
);
2391 create_fixed_operand (&ops
[0], targ0
);
2392 create_fixed_operand (&ops
[1], targ1
);
2393 create_convert_operand_from (&ops
[2], op0
, mode
, unsignedp
);
2394 if (maybe_expand_insn (icode
, 3, ops
))
2398 /* It can't be done in this mode. Can we do it in a wider mode? */
2400 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2402 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
2404 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2406 rtx t0
= gen_reg_rtx (wider_mode
);
2407 rtx t1
= gen_reg_rtx (wider_mode
);
2408 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2410 if (expand_twoval_unop (unoptab
, cop0
, t0
, t1
, unsignedp
))
2412 convert_move (targ0
, t0
, unsignedp
);
2413 convert_move (targ1
, t1
, unsignedp
);
2417 delete_insns_since (last
);
2422 delete_insns_since (entry_last
);
2426 /* Generate code to perform an operation specified by BINOPTAB
2427 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2428 We assume that the order of the operands for the instruction
2429 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2430 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2432 Either TARG0 or TARG1 may be zero, but what that means is that
2433 the result is not actually wanted. We will generate it into
2434 a dummy pseudo-reg and discard it. They may not both be zero.
2436 Returns 1 if this operation can be performed; 0 if not. */
2439 expand_twoval_binop (optab binoptab
, rtx op0
, rtx op1
, rtx targ0
, rtx targ1
,
2442 machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2443 enum mode_class mclass
;
2444 machine_mode wider_mode
;
2445 rtx_insn
*entry_last
= get_last_insn ();
2448 mclass
= GET_MODE_CLASS (mode
);
2451 targ0
= gen_reg_rtx (mode
);
2453 targ1
= gen_reg_rtx (mode
);
2455 /* Record where to go back to if we fail. */
2456 last
= get_last_insn ();
2458 if (optab_handler (binoptab
, mode
) != CODE_FOR_nothing
)
2460 class expand_operand ops
[4];
2461 enum insn_code icode
= optab_handler (binoptab
, mode
);
2462 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2463 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2464 rtx xop0
= op0
, xop1
= op1
;
2466 /* If we are optimizing, force expensive constants into a register. */
2467 xop0
= avoid_expensive_constant (mode0
, binoptab
, 0, xop0
, unsignedp
);
2468 xop1
= avoid_expensive_constant (mode1
, binoptab
, 1, xop1
, unsignedp
);
2470 create_fixed_operand (&ops
[0], targ0
);
2471 create_convert_operand_from (&ops
[1], xop0
, mode
, unsignedp
);
2472 create_convert_operand_from (&ops
[2], xop1
, mode
, unsignedp
);
2473 create_fixed_operand (&ops
[3], targ1
);
2474 if (maybe_expand_insn (icode
, 4, ops
))
2476 delete_insns_since (last
);
2479 /* It can't be done in this mode. Can we do it in a wider mode? */
2481 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2483 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
2485 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
)
2487 rtx t0
= gen_reg_rtx (wider_mode
);
2488 rtx t1
= gen_reg_rtx (wider_mode
);
2489 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2490 rtx cop1
= convert_modes (wider_mode
, mode
, op1
, unsignedp
);
2492 if (expand_twoval_binop (binoptab
, cop0
, cop1
,
2495 convert_move (targ0
, t0
, unsignedp
);
2496 convert_move (targ1
, t1
, unsignedp
);
2500 delete_insns_since (last
);
2505 delete_insns_since (entry_last
);
2509 /* Expand the two-valued library call indicated by BINOPTAB, but
2510 preserve only one of the values. If TARG0 is non-NULL, the first
2511 value is placed into TARG0; otherwise the second value is placed
2512 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2513 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2514 This routine assumes that the value returned by the library call is
2515 as if the return value was of an integral mode twice as wide as the
2516 mode of OP0. Returns 1 if the call was successful. */
2519 expand_twoval_binop_libfunc (optab binoptab
, rtx op0
, rtx op1
,
2520 rtx targ0
, rtx targ1
, enum rtx_code code
)
2523 machine_mode libval_mode
;
2528 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2529 gcc_assert (!targ0
!= !targ1
);
2531 mode
= GET_MODE (op0
);
2532 libfunc
= optab_libfunc (binoptab
, mode
);
2536 /* The value returned by the library function will have twice as
2537 many bits as the nominal MODE. */
2538 libval_mode
= smallest_int_mode_for_size (2 * GET_MODE_BITSIZE (mode
));
2540 libval
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
2544 /* Get the part of VAL containing the value that we want. */
2545 libval
= simplify_gen_subreg (mode
, libval
, libval_mode
,
2546 targ0
? 0 : GET_MODE_SIZE (mode
));
2547 insns
= get_insns ();
2549 /* Move the into the desired location. */
2550 emit_libcall_block (insns
, targ0
? targ0
: targ1
, libval
,
2551 gen_rtx_fmt_ee (code
, mode
, op0
, op1
));
2557 /* Wrapper around expand_unop which takes an rtx code to specify
2558 the operation to perform, not an optab pointer. All other
2559 arguments are the same. */
2561 expand_simple_unop (machine_mode mode
, enum rtx_code code
, rtx op0
,
2562 rtx target
, int unsignedp
)
2564 optab unop
= code_to_optab (code
);
2567 return expand_unop (mode
, unop
, op0
, target
, unsignedp
);
2573 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2575 A similar operation can be used for clrsb. UNOPTAB says which operation
2576 we are trying to expand. */
2578 widen_leading (scalar_int_mode mode
, rtx op0
, rtx target
, optab unoptab
)
2580 opt_scalar_int_mode wider_mode_iter
;
2581 FOR_EACH_WIDER_MODE (wider_mode_iter
, mode
)
2583 scalar_int_mode wider_mode
= wider_mode_iter
.require ();
2584 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2589 last
= get_last_insn ();
2592 target
= gen_reg_rtx (mode
);
2593 xop0
= widen_operand (op0
, wider_mode
, mode
,
2594 unoptab
!= clrsb_optab
, false);
2595 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2596 unoptab
!= clrsb_optab
);
2599 (wider_mode
, sub_optab
, temp
,
2600 gen_int_mode (GET_MODE_PRECISION (wider_mode
)
2601 - GET_MODE_PRECISION (mode
),
2603 target
, true, OPTAB_DIRECT
);
2605 delete_insns_since (last
);
2613 /* Attempt to emit (clrsb:mode op0) as
2614 (plus:mode (clz:mode (xor:mode op0 (ashr:mode op0 (const_int prec-1))))
2616 if CLZ_DEFINED_VALUE_AT_ZERO (mode, val) is 2 and val is prec,
2618 (clz:mode (ior:mode (xor:mode (ashl:mode op0 (const_int 1))
2619 (ashr:mode op0 (const_int prec-1)))
2624 expand_clrsb_using_clz (scalar_int_mode mode
, rtx op0
, rtx target
)
2626 if (optimize_insn_for_size_p ()
2627 || optab_handler (clz_optab
, mode
) == CODE_FOR_nothing
)
2631 HOST_WIDE_INT val
= 0;
2632 if (CLZ_DEFINED_VALUE_AT_ZERO (mode
, val
) != 2
2633 || val
!= GET_MODE_PRECISION (mode
))
2641 temp2
= expand_binop (mode
, ashl_optab
, op0
, const1_rtx
,
2642 NULL_RTX
, 0, OPTAB_DIRECT
);
2651 rtx temp
= expand_binop (mode
, ashr_optab
, op0
,
2652 GEN_INT (GET_MODE_PRECISION (mode
) - 1),
2653 NULL_RTX
, 0, OPTAB_DIRECT
);
2657 temp
= expand_binop (mode
, xor_optab
, temp2
, temp
, NULL_RTX
, 0,
2664 temp
= expand_binop (mode
, ior_optab
, temp
, const1_rtx
,
2665 NULL_RTX
, 0, OPTAB_DIRECT
);
2669 temp
= expand_unop_direct (mode
, clz_optab
, temp
, val
? NULL_RTX
: target
,
2675 temp
= expand_binop (mode
, add_optab
, temp
, constm1_rtx
,
2676 target
, 0, OPTAB_DIRECT
);
2681 rtx_insn
*seq
= get_insns ();
2684 add_equal_note (seq
, temp
, CLRSB
, op0
, NULL_RTX
, mode
);
2689 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2690 quantities, choosing which based on whether the high word is nonzero. */
2692 expand_doubleword_clz (scalar_int_mode mode
, rtx op0
, rtx target
)
2694 rtx xop0
= force_reg (mode
, op0
);
2695 rtx subhi
= gen_highpart (word_mode
, xop0
);
2696 rtx sublo
= gen_lowpart (word_mode
, xop0
);
2697 rtx_code_label
*hi0_label
= gen_label_rtx ();
2698 rtx_code_label
*after_label
= gen_label_rtx ();
2702 /* If we were not given a target, use a word_mode register, not a
2703 'mode' register. The result will fit, and nobody is expecting
2704 anything bigger (the return type of __builtin_clz* is int). */
2706 target
= gen_reg_rtx (word_mode
);
2708 /* In any case, write to a word_mode scratch in both branches of the
2709 conditional, so we can ensure there is a single move insn setting
2710 'target' to tag a REG_EQUAL note on. */
2711 result
= gen_reg_rtx (word_mode
);
2715 /* If the high word is not equal to zero,
2716 then clz of the full value is clz of the high word. */
2717 emit_cmp_and_jump_insns (subhi
, CONST0_RTX (word_mode
), EQ
, 0,
2718 word_mode
, true, hi0_label
);
2720 temp
= expand_unop_direct (word_mode
, clz_optab
, subhi
, result
, true);
2725 convert_move (result
, temp
, true);
2727 emit_jump_insn (targetm
.gen_jump (after_label
));
2730 /* Else clz of the full value is clz of the low word plus the number
2731 of bits in the high word. */
2732 emit_label (hi0_label
);
2734 temp
= expand_unop_direct (word_mode
, clz_optab
, sublo
, 0, true);
2737 temp
= expand_binop (word_mode
, add_optab
, temp
,
2738 gen_int_mode (GET_MODE_BITSIZE (word_mode
), word_mode
),
2739 result
, true, OPTAB_DIRECT
);
2743 convert_move (result
, temp
, true);
2745 emit_label (after_label
);
2746 convert_move (target
, result
, true);
2751 add_equal_note (seq
, target
, CLZ
, xop0
, NULL_RTX
, mode
);
2760 /* Try calculating popcount of a double-word quantity as two popcount's of
2761 word-sized quantities and summing up the results. */
2763 expand_doubleword_popcount (scalar_int_mode mode
, rtx op0
, rtx target
)
2770 t0
= expand_unop_direct (word_mode
, popcount_optab
,
2771 operand_subword_force (op0
, 0, mode
), NULL_RTX
,
2773 t1
= expand_unop_direct (word_mode
, popcount_optab
,
2774 operand_subword_force (op0
, 1, mode
), NULL_RTX
,
2782 /* If we were not given a target, use a word_mode register, not a
2783 'mode' register. The result will fit, and nobody is expecting
2784 anything bigger (the return type of __builtin_popcount* is int). */
2786 target
= gen_reg_rtx (word_mode
);
2788 t
= expand_binop (word_mode
, add_optab
, t0
, t1
, target
, 0, OPTAB_DIRECT
);
2793 add_equal_note (seq
, t
, POPCOUNT
, op0
, NULL_RTX
, mode
);
2801 (parity:narrow (low (x) ^ high (x))) */
2803 expand_doubleword_parity (scalar_int_mode mode
, rtx op0
, rtx target
)
2805 rtx t
= expand_binop (word_mode
, xor_optab
,
2806 operand_subword_force (op0
, 0, mode
),
2807 operand_subword_force (op0
, 1, mode
),
2808 NULL_RTX
, 0, OPTAB_DIRECT
);
2809 return expand_unop (word_mode
, parity_optab
, t
, target
, true);
2815 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2817 widen_bswap (scalar_int_mode mode
, rtx op0
, rtx target
)
2821 opt_scalar_int_mode wider_mode_iter
;
2823 FOR_EACH_WIDER_MODE (wider_mode_iter
, mode
)
2824 if (optab_handler (bswap_optab
, wider_mode_iter
.require ())
2825 != CODE_FOR_nothing
)
2828 if (!wider_mode_iter
.exists ())
2831 scalar_int_mode wider_mode
= wider_mode_iter
.require ();
2832 last
= get_last_insn ();
2834 x
= widen_operand (op0
, wider_mode
, mode
, true, true);
2835 x
= expand_unop (wider_mode
, bswap_optab
, x
, NULL_RTX
, true);
2837 gcc_assert (GET_MODE_PRECISION (wider_mode
) == GET_MODE_BITSIZE (wider_mode
)
2838 && GET_MODE_PRECISION (mode
) == GET_MODE_BITSIZE (mode
));
2840 x
= expand_shift (RSHIFT_EXPR
, wider_mode
, x
,
2841 GET_MODE_BITSIZE (wider_mode
)
2842 - GET_MODE_BITSIZE (mode
),
2848 target
= gen_reg_rtx (mode
);
2849 emit_move_insn (target
, gen_lowpart (mode
, x
));
2852 delete_insns_since (last
);
2857 /* Try calculating bswap as two bswaps of two word-sized operands. */
2860 expand_doubleword_bswap (machine_mode mode
, rtx op
, rtx target
)
2864 t1
= expand_unop (word_mode
, bswap_optab
,
2865 operand_subword_force (op
, 0, mode
), NULL_RTX
, true);
2866 t0
= expand_unop (word_mode
, bswap_optab
,
2867 operand_subword_force (op
, 1, mode
), NULL_RTX
, true);
2869 if (target
== 0 || !valid_multiword_target_p (target
))
2870 target
= gen_reg_rtx (mode
);
2872 emit_clobber (target
);
2873 emit_move_insn (operand_subword (target
, 0, 1, mode
), t0
);
2874 emit_move_insn (operand_subword (target
, 1, 1, mode
), t1
);
2879 /* Try calculating (parity x) as (and (popcount x) 1), where
2880 popcount can also be done in a wider mode. */
2882 expand_parity (scalar_int_mode mode
, rtx op0
, rtx target
)
2884 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2885 opt_scalar_int_mode wider_mode_iter
;
2886 FOR_EACH_MODE_FROM (wider_mode_iter
, mode
)
2888 scalar_int_mode wider_mode
= wider_mode_iter
.require ();
2889 if (optab_handler (popcount_optab
, wider_mode
) != CODE_FOR_nothing
)
2894 last
= get_last_insn ();
2896 if (target
== 0 || GET_MODE (target
) != wider_mode
)
2897 target
= gen_reg_rtx (wider_mode
);
2899 xop0
= widen_operand (op0
, wider_mode
, mode
, true, false);
2900 temp
= expand_unop (wider_mode
, popcount_optab
, xop0
, NULL_RTX
,
2903 temp
= expand_binop (wider_mode
, and_optab
, temp
, const1_rtx
,
2904 target
, true, OPTAB_DIRECT
);
2908 if (mclass
!= MODE_INT
2909 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
2910 return convert_to_mode (mode
, temp
, 0);
2912 return gen_lowpart (mode
, temp
);
2915 delete_insns_since (last
);
2921 /* Try calculating ctz(x) as K - clz(x & -x) ,
2922 where K is GET_MODE_PRECISION(mode) - 1.
2924 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2925 don't have to worry about what the hardware does in that case. (If
2926 the clz instruction produces the usual value at 0, which is K, the
2927 result of this code sequence will be -1; expand_ffs, below, relies
2928 on this. It might be nice to have it be K instead, for consistency
2929 with the (very few) processors that provide a ctz with a defined
2930 value, but that would take one more instruction, and it would be
2931 less convenient for expand_ffs anyway. */
2934 expand_ctz (scalar_int_mode mode
, rtx op0
, rtx target
)
2939 if (optab_handler (clz_optab
, mode
) == CODE_FOR_nothing
)
2944 temp
= expand_unop_direct (mode
, neg_optab
, op0
, NULL_RTX
, true);
2946 temp
= expand_binop (mode
, and_optab
, op0
, temp
, NULL_RTX
,
2947 true, OPTAB_DIRECT
);
2949 temp
= expand_unop_direct (mode
, clz_optab
, temp
, NULL_RTX
, true);
2951 temp
= expand_binop (mode
, sub_optab
,
2952 gen_int_mode (GET_MODE_PRECISION (mode
) - 1, mode
),
2954 true, OPTAB_DIRECT
);
2964 add_equal_note (seq
, temp
, CTZ
, op0
, NULL_RTX
, mode
);
2970 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2971 else with the sequence used by expand_clz.
2973 The ffs builtin promises to return zero for a zero value and ctz/clz
2974 may have an undefined value in that case. If they do not give us a
2975 convenient value, we have to generate a test and branch. */
2977 expand_ffs (scalar_int_mode mode
, rtx op0
, rtx target
)
2979 HOST_WIDE_INT val
= 0;
2980 bool defined_at_zero
= false;
2984 if (optab_handler (ctz_optab
, mode
) != CODE_FOR_nothing
)
2988 temp
= expand_unop_direct (mode
, ctz_optab
, op0
, 0, true);
2992 defined_at_zero
= (CTZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2);
2994 else if (optab_handler (clz_optab
, mode
) != CODE_FOR_nothing
)
2997 temp
= expand_ctz (mode
, op0
, 0);
3001 if (CLZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2)
3003 defined_at_zero
= true;
3004 val
= (GET_MODE_PRECISION (mode
) - 1) - val
;
3010 if (defined_at_zero
&& val
== -1)
3011 /* No correction needed at zero. */;
3014 /* We don't try to do anything clever with the situation found
3015 on some processors (eg Alpha) where ctz(0:mode) ==
3016 bitsize(mode). If someone can think of a way to send N to -1
3017 and leave alone all values in the range 0..N-1 (where N is a
3018 power of two), cheaper than this test-and-branch, please add it.
3020 The test-and-branch is done after the operation itself, in case
3021 the operation sets condition codes that can be recycled for this.
3022 (This is true on i386, for instance.) */
3024 rtx_code_label
*nonzero_label
= gen_label_rtx ();
3025 emit_cmp_and_jump_insns (op0
, CONST0_RTX (mode
), NE
, 0,
3026 mode
, true, nonzero_label
);
3028 convert_move (temp
, GEN_INT (-1), false);
3029 emit_label (nonzero_label
);
3032 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
3033 to produce a value in the range 0..bitsize. */
3034 temp
= expand_binop (mode
, add_optab
, temp
, gen_int_mode (1, mode
),
3035 target
, false, OPTAB_DIRECT
);
3042 add_equal_note (seq
, temp
, FFS
, op0
, NULL_RTX
, mode
);
3051 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
3052 conditions, VAL may already be a SUBREG against which we cannot generate
3053 a further SUBREG. In this case, we expect forcing the value into a
3054 register will work around the situation. */
3057 lowpart_subreg_maybe_copy (machine_mode omode
, rtx val
,
3061 ret
= lowpart_subreg (omode
, val
, imode
);
3064 val
= force_reg (imode
, val
);
3065 ret
= lowpart_subreg (omode
, val
, imode
);
3066 gcc_assert (ret
!= NULL
);
3071 /* Expand a floating point absolute value or negation operation via a
3072 logical operation on the sign bit. */
3075 expand_absneg_bit (enum rtx_code code
, scalar_float_mode mode
,
3076 rtx op0
, rtx target
)
3078 const struct real_format
*fmt
;
3079 int bitpos
, word
, nwords
, i
;
3080 scalar_int_mode imode
;
3084 /* The format has to have a simple sign bit. */
3085 fmt
= REAL_MODE_FORMAT (mode
);
3089 bitpos
= fmt
->signbit_rw
;
3093 /* Don't create negative zeros if the format doesn't support them. */
3094 if (code
== NEG
&& !fmt
->has_signed_zero
)
3097 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3099 if (!int_mode_for_mode (mode
).exists (&imode
))
3108 if (FLOAT_WORDS_BIG_ENDIAN
)
3109 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3111 word
= bitpos
/ BITS_PER_WORD
;
3112 bitpos
= bitpos
% BITS_PER_WORD
;
3113 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
3116 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3122 || reg_overlap_mentioned_p (target
, op0
)
3123 || (nwords
> 1 && !valid_multiword_target_p (target
)))
3124 target
= gen_reg_rtx (mode
);
3130 for (i
= 0; i
< nwords
; ++i
)
3132 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
3133 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
3137 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
3139 immed_wide_int_const (mask
, imode
),
3140 targ_piece
, 1, OPTAB_LIB_WIDEN
);
3141 if (temp
!= targ_piece
)
3142 emit_move_insn (targ_piece
, temp
);
3145 emit_move_insn (targ_piece
, op0_piece
);
3148 insns
= get_insns ();
3155 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
3156 gen_lowpart (imode
, op0
),
3157 immed_wide_int_const (mask
, imode
),
3158 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3159 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3161 set_dst_reg_note (get_last_insn (), REG_EQUAL
,
3162 gen_rtx_fmt_e (code
, mode
, copy_rtx (op0
)),
3169 /* As expand_unop, but will fail rather than attempt the operation in a
3170 different mode or with a libcall. */
3172 expand_unop_direct (machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
3175 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
3177 class expand_operand ops
[2];
3178 enum insn_code icode
= optab_handler (unoptab
, mode
);
3179 rtx_insn
*last
= get_last_insn ();
3182 create_output_operand (&ops
[0], target
, mode
);
3183 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
3184 pat
= maybe_gen_insn (icode
, 2, ops
);
3187 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
3188 && ! add_equal_note (pat
, ops
[0].value
,
3189 optab_to_code (unoptab
),
3190 ops
[1].value
, NULL_RTX
, mode
))
3192 delete_insns_since (last
);
3193 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
3198 return ops
[0].value
;
3204 /* Generate code to perform an operation specified by UNOPTAB
3205 on operand OP0, with result having machine-mode MODE.
3207 UNSIGNEDP is for the case where we have to widen the operands
3208 to perform the operation. It says to use zero-extension.
3210 If TARGET is nonzero, the value
3211 is generated there, if it is convenient to do so.
3212 In all cases an rtx is returned for the locus of the value;
3213 this may or may not be TARGET. */
3216 expand_unop (machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
3219 enum mode_class mclass
= GET_MODE_CLASS (mode
);
3220 machine_mode wider_mode
;
3221 scalar_int_mode int_mode
;
3222 scalar_float_mode float_mode
;
3226 temp
= expand_unop_direct (mode
, unoptab
, op0
, target
, unsignedp
);
3230 /* It can't be done in this mode. Can we open-code it in a wider mode? */
3232 /* Widening (or narrowing) clz needs special treatment. */
3233 if (unoptab
== clz_optab
)
3235 if (is_a
<scalar_int_mode
> (mode
, &int_mode
))
3237 temp
= widen_leading (int_mode
, op0
, target
, unoptab
);
3241 if (GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
3242 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
3244 temp
= expand_doubleword_clz (int_mode
, op0
, target
);
3253 if (unoptab
== clrsb_optab
)
3255 if (is_a
<scalar_int_mode
> (mode
, &int_mode
))
3257 temp
= widen_leading (int_mode
, op0
, target
, unoptab
);
3260 temp
= expand_clrsb_using_clz (int_mode
, op0
, target
);
3267 if (unoptab
== popcount_optab
3268 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
3269 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
3270 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
3271 && optimize_insn_for_speed_p ())
3273 temp
= expand_doubleword_popcount (int_mode
, op0
, target
);
3278 if (unoptab
== parity_optab
3279 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
3280 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
3281 && (optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
3282 || optab_handler (popcount_optab
, word_mode
) != CODE_FOR_nothing
)
3283 && optimize_insn_for_speed_p ())
3285 temp
= expand_doubleword_parity (int_mode
, op0
, target
);
3290 /* Widening (or narrowing) bswap needs special treatment. */
3291 if (unoptab
== bswap_optab
)
3293 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
3294 or ROTATERT. First try these directly; if this fails, then try the
3295 obvious pair of shifts with allowed widening, as this will probably
3296 be always more efficient than the other fallback methods. */
3302 if (optab_handler (rotl_optab
, mode
) != CODE_FOR_nothing
)
3304 temp
= expand_binop (mode
, rotl_optab
, op0
,
3305 gen_int_shift_amount (mode
, 8),
3306 target
, unsignedp
, OPTAB_DIRECT
);
3311 if (optab_handler (rotr_optab
, mode
) != CODE_FOR_nothing
)
3313 temp
= expand_binop (mode
, rotr_optab
, op0
,
3314 gen_int_shift_amount (mode
, 8),
3315 target
, unsignedp
, OPTAB_DIRECT
);
3320 last
= get_last_insn ();
3322 temp1
= expand_binop (mode
, ashl_optab
, op0
,
3323 gen_int_shift_amount (mode
, 8), NULL_RTX
,
3324 unsignedp
, OPTAB_WIDEN
);
3325 temp2
= expand_binop (mode
, lshr_optab
, op0
,
3326 gen_int_shift_amount (mode
, 8), NULL_RTX
,
3327 unsignedp
, OPTAB_WIDEN
);
3330 temp
= expand_binop (mode
, ior_optab
, temp1
, temp2
, target
,
3331 unsignedp
, OPTAB_WIDEN
);
3336 delete_insns_since (last
);
3339 if (is_a
<scalar_int_mode
> (mode
, &int_mode
))
3341 temp
= widen_bswap (int_mode
, op0
, target
);
3345 /* We do not provide a 128-bit bswap in libgcc so force the use of
3346 a double bswap for 64-bit targets. */
3347 if (GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
3348 && (UNITS_PER_WORD
== 8
3349 || optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
))
3351 temp
= expand_doubleword_bswap (mode
, op0
, target
);
3360 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3361 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
3363 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
3366 rtx_insn
*last
= get_last_insn ();
3368 /* For certain operations, we need not actually extend
3369 the narrow operand, as long as we will truncate the
3370 results to the same narrowness. */
3372 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3373 (unoptab
== neg_optab
3374 || unoptab
== one_cmpl_optab
)
3375 && mclass
== MODE_INT
);
3377 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3382 if (mclass
!= MODE_INT
3383 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
3386 target
= gen_reg_rtx (mode
);
3387 convert_move (target
, temp
, 0);
3391 return gen_lowpart (mode
, temp
);
3394 delete_insns_since (last
);
3398 /* These can be done a word at a time. */
3399 if (unoptab
== one_cmpl_optab
3400 && is_int_mode (mode
, &int_mode
)
3401 && GET_MODE_SIZE (int_mode
) > UNITS_PER_WORD
3402 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
3409 || reg_overlap_mentioned_p (target
, op0
)
3410 || !valid_multiword_target_p (target
))
3411 target
= gen_reg_rtx (int_mode
);
3415 /* Do the actual arithmetic. */
3416 for (i
= 0; i
< GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
; i
++)
3418 rtx target_piece
= operand_subword (target
, i
, 1, int_mode
);
3419 rtx x
= expand_unop (word_mode
, unoptab
,
3420 operand_subword_force (op0
, i
, int_mode
),
3421 target_piece
, unsignedp
);
3423 if (target_piece
!= x
)
3424 emit_move_insn (target_piece
, x
);
3427 insns
= get_insns ();
3434 /* Emit ~op0 as op0 ^ -1. */
3435 if (unoptab
== one_cmpl_optab
3436 && (SCALAR_INT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
3437 && optab_handler (xor_optab
, mode
) != CODE_FOR_nothing
)
3439 temp
= expand_binop (mode
, xor_optab
, op0
, CONSTM1_RTX (mode
),
3440 target
, unsignedp
, OPTAB_DIRECT
);
3445 if (optab_to_code (unoptab
) == NEG
)
3447 /* Try negating floating point values by flipping the sign bit. */
3448 if (is_a
<scalar_float_mode
> (mode
, &float_mode
))
3450 temp
= expand_absneg_bit (NEG
, float_mode
, op0
, target
);
3455 /* If there is no negation pattern, and we have no negative zero,
3456 try subtracting from zero. */
3457 if (!HONOR_SIGNED_ZEROS (mode
))
3459 temp
= expand_binop (mode
, (unoptab
== negv_optab
3460 ? subv_optab
: sub_optab
),
3461 CONST0_RTX (mode
), op0
, target
,
3462 unsignedp
, OPTAB_DIRECT
);
3468 /* Try calculating parity (x) as popcount (x) % 2. */
3469 if (unoptab
== parity_optab
&& is_a
<scalar_int_mode
> (mode
, &int_mode
))
3471 temp
= expand_parity (int_mode
, op0
, target
);
3476 /* Try implementing ffs (x) in terms of clz (x). */
3477 if (unoptab
== ffs_optab
&& is_a
<scalar_int_mode
> (mode
, &int_mode
))
3479 temp
= expand_ffs (int_mode
, op0
, target
);
3484 /* Try implementing ctz (x) in terms of clz (x). */
3485 if (unoptab
== ctz_optab
&& is_a
<scalar_int_mode
> (mode
, &int_mode
))
3487 temp
= expand_ctz (int_mode
, op0
, target
);
3493 /* Now try a library call in this mode. */
3494 libfunc
= optab_libfunc (unoptab
, mode
);
3500 machine_mode outmode
= mode
;
3502 /* All of these functions return small values. Thus we choose to
3503 have them return something that isn't a double-word. */
3504 if (unoptab
== ffs_optab
|| unoptab
== clz_optab
|| unoptab
== ctz_optab
3505 || unoptab
== clrsb_optab
|| unoptab
== popcount_optab
3506 || unoptab
== parity_optab
)
3508 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node
),
3509 optab_libfunc (unoptab
, mode
)));
3513 /* Pass 1 for NO_QUEUE so we don't lose any increments
3514 if the libcall is cse'd or moved. */
3515 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, outmode
,
3517 insns
= get_insns ();
3520 target
= gen_reg_rtx (outmode
);
3521 bool trapv
= trapv_unoptab_p (unoptab
);
3523 eq_value
= NULL_RTX
;
3526 eq_value
= gen_rtx_fmt_e (optab_to_code (unoptab
), mode
, op0
);
3527 if (GET_MODE_UNIT_SIZE (outmode
) < GET_MODE_UNIT_SIZE (mode
))
3528 eq_value
= simplify_gen_unary (TRUNCATE
, outmode
, eq_value
, mode
);
3529 else if (GET_MODE_UNIT_SIZE (outmode
) > GET_MODE_UNIT_SIZE (mode
))
3530 eq_value
= simplify_gen_unary (ZERO_EXTEND
,
3531 outmode
, eq_value
, mode
);
3533 emit_libcall_block_1 (insns
, target
, value
, eq_value
, trapv
);
3538 /* It can't be done in this mode. Can we do it in a wider mode? */
3540 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3542 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
3544 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
3545 || optab_libfunc (unoptab
, wider_mode
))
3548 rtx_insn
*last
= get_last_insn ();
3550 /* For certain operations, we need not actually extend
3551 the narrow operand, as long as we will truncate the
3552 results to the same narrowness. */
3553 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3554 (unoptab
== neg_optab
3555 || unoptab
== one_cmpl_optab
3556 || unoptab
== bswap_optab
)
3557 && mclass
== MODE_INT
);
3559 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3562 /* If we are generating clz using wider mode, adjust the
3563 result. Similarly for clrsb. */
3564 if ((unoptab
== clz_optab
|| unoptab
== clrsb_optab
)
3567 scalar_int_mode wider_int_mode
3568 = as_a
<scalar_int_mode
> (wider_mode
);
3569 int_mode
= as_a
<scalar_int_mode
> (mode
);
3571 (wider_mode
, sub_optab
, temp
,
3572 gen_int_mode (GET_MODE_PRECISION (wider_int_mode
)
3573 - GET_MODE_PRECISION (int_mode
),
3575 target
, true, OPTAB_DIRECT
);
3578 /* Likewise for bswap. */
3579 if (unoptab
== bswap_optab
&& temp
!= 0)
3581 scalar_int_mode wider_int_mode
3582 = as_a
<scalar_int_mode
> (wider_mode
);
3583 int_mode
= as_a
<scalar_int_mode
> (mode
);
3584 gcc_assert (GET_MODE_PRECISION (wider_int_mode
)
3585 == GET_MODE_BITSIZE (wider_int_mode
)
3586 && GET_MODE_PRECISION (int_mode
)
3587 == GET_MODE_BITSIZE (int_mode
));
3589 temp
= expand_shift (RSHIFT_EXPR
, wider_int_mode
, temp
,
3590 GET_MODE_BITSIZE (wider_int_mode
)
3591 - GET_MODE_BITSIZE (int_mode
),
3597 if (mclass
!= MODE_INT
)
3600 target
= gen_reg_rtx (mode
);
3601 convert_move (target
, temp
, 0);
3605 return gen_lowpart (mode
, temp
);
3608 delete_insns_since (last
);
3613 /* One final attempt at implementing negation via subtraction,
3614 this time allowing widening of the operand. */
3615 if (optab_to_code (unoptab
) == NEG
&& !HONOR_SIGNED_ZEROS (mode
))
3618 temp
= expand_binop (mode
,
3619 unoptab
== negv_optab
? subv_optab
: sub_optab
,
3620 CONST0_RTX (mode
), op0
,
3621 target
, unsignedp
, OPTAB_LIB_WIDEN
);
3629 /* Emit code to compute the absolute value of OP0, with result to
3630 TARGET if convenient. (TARGET may be 0.) The return value says
3631 where the result actually is to be found.
3633 MODE is the mode of the operand; the mode of the result is
3634 different but can be deduced from MODE.
3639 expand_abs_nojump (machine_mode mode
, rtx op0
, rtx target
,
3640 int result_unsignedp
)
3644 if (GET_MODE_CLASS (mode
) != MODE_INT
3646 result_unsignedp
= 1;
3648 /* First try to do it with a special abs instruction. */
3649 temp
= expand_unop (mode
, result_unsignedp
? abs_optab
: absv_optab
,
3654 /* For floating point modes, try clearing the sign bit. */
3655 scalar_float_mode float_mode
;
3656 if (is_a
<scalar_float_mode
> (mode
, &float_mode
))
3658 temp
= expand_absneg_bit (ABS
, float_mode
, op0
, target
);
3663 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3664 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
3665 && !HONOR_SIGNED_ZEROS (mode
))
3667 rtx_insn
*last
= get_last_insn ();
3669 temp
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3672 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3678 delete_insns_since (last
);
3681 /* If this machine has expensive jumps, we can do integer absolute
3682 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3683 where W is the width of MODE. */
3685 scalar_int_mode int_mode
;
3686 if (is_int_mode (mode
, &int_mode
)
3687 && BRANCH_COST (optimize_insn_for_speed_p (),
3690 rtx extended
= expand_shift (RSHIFT_EXPR
, int_mode
, op0
,
3691 GET_MODE_PRECISION (int_mode
) - 1,
3694 temp
= expand_binop (int_mode
, xor_optab
, extended
, op0
, target
, 0,
3697 temp
= expand_binop (int_mode
,
3698 result_unsignedp
? sub_optab
: subv_optab
,
3699 temp
, extended
, target
, 0, OPTAB_LIB_WIDEN
);
3709 expand_abs (machine_mode mode
, rtx op0
, rtx target
,
3710 int result_unsignedp
, int safe
)
3713 rtx_code_label
*op1
;
3715 if (GET_MODE_CLASS (mode
) != MODE_INT
3717 result_unsignedp
= 1;
3719 temp
= expand_abs_nojump (mode
, op0
, target
, result_unsignedp
);
3723 /* If that does not win, use conditional jump and negate. */
3725 /* It is safe to use the target if it is the same
3726 as the source if this is also a pseudo register */
3727 if (op0
== target
&& REG_P (op0
)
3728 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
3731 op1
= gen_label_rtx ();
3732 if (target
== 0 || ! safe
3733 || GET_MODE (target
) != mode
3734 || (MEM_P (target
) && MEM_VOLATILE_P (target
))
3736 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
3737 target
= gen_reg_rtx (mode
);
3739 emit_move_insn (target
, op0
);
3742 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
3743 NULL_RTX
, NULL
, op1
,
3744 profile_probability::uninitialized ());
3746 op0
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3749 emit_move_insn (target
, op0
);
3755 /* Emit code to compute the one's complement absolute value of OP0
3756 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3757 (TARGET may be NULL_RTX.) The return value says where the result
3758 actually is to be found.
3760 MODE is the mode of the operand; the mode of the result is
3761 different but can be deduced from MODE. */
3764 expand_one_cmpl_abs_nojump (machine_mode mode
, rtx op0
, rtx target
)
3768 /* Not applicable for floating point modes. */
3769 if (FLOAT_MODE_P (mode
))
3772 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3773 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
)
3775 rtx_insn
*last
= get_last_insn ();
3777 temp
= expand_unop (mode
, one_cmpl_optab
, op0
, NULL_RTX
, 0);
3779 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3785 delete_insns_since (last
);
3788 /* If this machine has expensive jumps, we can do one's complement
3789 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3791 scalar_int_mode int_mode
;
3792 if (is_int_mode (mode
, &int_mode
)
3793 && BRANCH_COST (optimize_insn_for_speed_p (),
3796 rtx extended
= expand_shift (RSHIFT_EXPR
, int_mode
, op0
,
3797 GET_MODE_PRECISION (int_mode
) - 1,
3800 temp
= expand_binop (int_mode
, xor_optab
, extended
, op0
, target
, 0,
3810 /* A subroutine of expand_copysign, perform the copysign operation using the
3811 abs and neg primitives advertised to exist on the target. The assumption
3812 is that we have a split register file, and leaving op0 in fp registers,
3813 and not playing with subregs so much, will help the register allocator. */
3816 expand_copysign_absneg (scalar_float_mode mode
, rtx op0
, rtx op1
, rtx target
,
3817 int bitpos
, bool op0_is_abs
)
3819 scalar_int_mode imode
;
3820 enum insn_code icode
;
3822 rtx_code_label
*label
;
3827 /* Check if the back end provides an insn that handles signbit for the
3829 icode
= optab_handler (signbit_optab
, mode
);
3830 if (icode
!= CODE_FOR_nothing
)
3832 imode
= as_a
<scalar_int_mode
> (insn_data
[(int) icode
].operand
[0].mode
);
3833 sign
= gen_reg_rtx (imode
);
3834 emit_unop_insn (icode
, sign
, op1
, UNKNOWN
);
3838 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3840 if (!int_mode_for_mode (mode
).exists (&imode
))
3842 op1
= gen_lowpart (imode
, op1
);
3849 if (FLOAT_WORDS_BIG_ENDIAN
)
3850 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3852 word
= bitpos
/ BITS_PER_WORD
;
3853 bitpos
= bitpos
% BITS_PER_WORD
;
3854 op1
= operand_subword_force (op1
, word
, mode
);
3857 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3858 sign
= expand_binop (imode
, and_optab
, op1
,
3859 immed_wide_int_const (mask
, imode
),
3860 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3865 op0
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
3872 if (target
== NULL_RTX
)
3873 target
= copy_to_reg (op0
);
3875 emit_move_insn (target
, op0
);
3878 label
= gen_label_rtx ();
3879 emit_cmp_and_jump_insns (sign
, const0_rtx
, EQ
, NULL_RTX
, imode
, 1, label
);
3881 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3882 op0
= simplify_unary_operation (NEG
, mode
, op0
, mode
);
3884 op0
= expand_unop (mode
, neg_optab
, op0
, target
, 0);
3886 emit_move_insn (target
, op0
);
3894 /* A subroutine of expand_copysign, perform the entire copysign operation
3895 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3896 is true if op0 is known to have its sign bit clear. */
3899 expand_copysign_bit (scalar_float_mode mode
, rtx op0
, rtx op1
, rtx target
,
3900 int bitpos
, bool op0_is_abs
)
3902 scalar_int_mode imode
;
3903 int word
, nwords
, i
;
3907 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3909 if (!int_mode_for_mode (mode
).exists (&imode
))
3918 if (FLOAT_WORDS_BIG_ENDIAN
)
3919 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3921 word
= bitpos
/ BITS_PER_WORD
;
3922 bitpos
= bitpos
% BITS_PER_WORD
;
3923 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
3926 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3931 || reg_overlap_mentioned_p (target
, op0
)
3932 || reg_overlap_mentioned_p (target
, op1
)
3933 || (nwords
> 1 && !valid_multiword_target_p (target
)))
3934 target
= gen_reg_rtx (mode
);
3940 for (i
= 0; i
< nwords
; ++i
)
3942 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
3943 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
3949 = expand_binop (imode
, and_optab
, op0_piece
,
3950 immed_wide_int_const (~mask
, imode
),
3951 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3952 op1
= expand_binop (imode
, and_optab
,
3953 operand_subword_force (op1
, i
, mode
),
3954 immed_wide_int_const (mask
, imode
),
3955 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3957 temp
= expand_binop (imode
, ior_optab
, op0_piece
, op1
,
3958 targ_piece
, 1, OPTAB_LIB_WIDEN
);
3959 if (temp
!= targ_piece
)
3960 emit_move_insn (targ_piece
, temp
);
3963 emit_move_insn (targ_piece
, op0_piece
);
3966 insns
= get_insns ();
3973 op1
= expand_binop (imode
, and_optab
, gen_lowpart (imode
, op1
),
3974 immed_wide_int_const (mask
, imode
),
3975 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3977 op0
= gen_lowpart (imode
, op0
);
3979 op0
= expand_binop (imode
, and_optab
, op0
,
3980 immed_wide_int_const (~mask
, imode
),
3981 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3983 temp
= expand_binop (imode
, ior_optab
, op0
, op1
,
3984 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3985 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3991 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3992 scalar floating point mode. Return NULL if we do not know how to
3993 expand the operation inline. */
3996 expand_copysign (rtx op0
, rtx op1
, rtx target
)
3998 scalar_float_mode mode
;
3999 const struct real_format
*fmt
;
4003 mode
= as_a
<scalar_float_mode
> (GET_MODE (op0
));
4004 gcc_assert (GET_MODE (op1
) == mode
);
4006 /* First try to do it with a special instruction. */
4007 temp
= expand_binop (mode
, copysign_optab
, op0
, op1
,
4008 target
, 0, OPTAB_DIRECT
);
4012 fmt
= REAL_MODE_FORMAT (mode
);
4013 if (fmt
== NULL
|| !fmt
->has_signed_zero
)
4017 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
4019 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0
)))
4020 op0
= simplify_unary_operation (ABS
, mode
, op0
, mode
);
4024 if (fmt
->signbit_ro
>= 0
4025 && (CONST_DOUBLE_AS_FLOAT_P (op0
)
4026 || (optab_handler (neg_optab
, mode
) != CODE_FOR_nothing
4027 && optab_handler (abs_optab
, mode
) != CODE_FOR_nothing
)))
4029 temp
= expand_copysign_absneg (mode
, op0
, op1
, target
,
4030 fmt
->signbit_ro
, op0_is_abs
);
4035 if (fmt
->signbit_rw
< 0)
4037 return expand_copysign_bit (mode
, op0
, op1
, target
,
4038 fmt
->signbit_rw
, op0_is_abs
);
4041 /* Generate an instruction whose insn-code is INSN_CODE,
4042 with two operands: an output TARGET and an input OP0.
4043 TARGET *must* be nonzero, and the output is always stored there.
4044 CODE is an rtx code such that (CODE OP0) is an rtx that describes
4045 the value that is stored into TARGET.
4047 Return false if expansion failed. */
4050 maybe_emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
,
4053 class expand_operand ops
[2];
4056 create_output_operand (&ops
[0], target
, GET_MODE (target
));
4057 create_input_operand (&ops
[1], op0
, GET_MODE (op0
));
4058 pat
= maybe_gen_insn (icode
, 2, ops
);
4062 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
4064 add_equal_note (pat
, ops
[0].value
, code
, ops
[1].value
, NULL_RTX
,
4069 if (ops
[0].value
!= target
)
4070 emit_move_insn (target
, ops
[0].value
);
4073 /* Generate an instruction whose insn-code is INSN_CODE,
4074 with two operands: an output TARGET and an input OP0.
4075 TARGET *must* be nonzero, and the output is always stored there.
4076 CODE is an rtx code such that (CODE OP0) is an rtx that describes
4077 the value that is stored into TARGET. */
4080 emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
, enum rtx_code code
)
4082 bool ok
= maybe_emit_unop_insn (icode
, target
, op0
, code
);
4086 struct no_conflict_data
4089 rtx_insn
*first
, *insn
;
4093 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
4094 the currently examined clobber / store has to stay in the list of
4095 insns that constitute the actual libcall block. */
4097 no_conflict_move_test (rtx dest
, const_rtx set
, void *p0
)
4099 struct no_conflict_data
*p
= (struct no_conflict_data
*) p0
;
4101 /* If this inns directly contributes to setting the target, it must stay. */
4102 if (reg_overlap_mentioned_p (p
->target
, dest
))
4103 p
->must_stay
= true;
4104 /* If we haven't committed to keeping any other insns in the list yet,
4105 there is nothing more to check. */
4106 else if (p
->insn
== p
->first
)
4108 /* If this insn sets / clobbers a register that feeds one of the insns
4109 already in the list, this insn has to stay too. */
4110 else if (reg_overlap_mentioned_p (dest
, PATTERN (p
->first
))
4111 || (CALL_P (p
->first
) && (find_reg_fusage (p
->first
, USE
, dest
)))
4112 || reg_used_between_p (dest
, p
->first
, p
->insn
)
4113 /* Likewise if this insn depends on a register set by a previous
4114 insn in the list, or if it sets a result (presumably a hard
4115 register) that is set or clobbered by a previous insn.
4116 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
4117 SET_DEST perform the former check on the address, and the latter
4118 check on the MEM. */
4119 || (GET_CODE (set
) == SET
4120 && (modified_in_p (SET_SRC (set
), p
->first
)
4121 || modified_in_p (SET_DEST (set
), p
->first
)
4122 || modified_between_p (SET_SRC (set
), p
->first
, p
->insn
)
4123 || modified_between_p (SET_DEST (set
), p
->first
, p
->insn
))))
4124 p
->must_stay
= true;
4128 /* Emit code to make a call to a constant function or a library call.
4130 INSNS is a list containing all insns emitted in the call.
4131 These insns leave the result in RESULT. Our block is to copy RESULT
4132 to TARGET, which is logically equivalent to EQUIV.
4134 We first emit any insns that set a pseudo on the assumption that these are
4135 loading constants into registers; doing so allows them to be safely cse'ed
4136 between blocks. Then we emit all the other insns in the block, followed by
4137 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
4138 note with an operand of EQUIV. */
4141 emit_libcall_block_1 (rtx_insn
*insns
, rtx target
, rtx result
, rtx equiv
,
4142 bool equiv_may_trap
)
4144 rtx final_dest
= target
;
4145 rtx_insn
*next
, *last
, *insn
;
4147 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
4148 into a MEM later. Protect the libcall block from this change. */
4149 if (! REG_P (target
) || REG_USERVAR_P (target
))
4150 target
= gen_reg_rtx (GET_MODE (target
));
4152 /* If we're using non-call exceptions, a libcall corresponding to an
4153 operation that may trap may also trap. */
4154 /* ??? See the comment in front of make_reg_eh_region_note. */
4155 if (cfun
->can_throw_non_call_exceptions
4156 && (equiv_may_trap
|| may_trap_p (equiv
)))
4158 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
4161 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
4164 int lp_nr
= INTVAL (XEXP (note
, 0));
4165 if (lp_nr
== 0 || lp_nr
== INT_MIN
)
4166 remove_note (insn
, note
);
4172 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
4173 reg note to indicate that this call cannot throw or execute a nonlocal
4174 goto (unless there is already a REG_EH_REGION note, in which case
4176 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
4178 make_reg_eh_region_note_nothrow_nononlocal (insn
);
4181 /* First emit all insns that set pseudos. Remove them from the list as
4182 we go. Avoid insns that set pseudos which were referenced in previous
4183 insns. These can be generated by move_by_pieces, for example,
4184 to update an address. Similarly, avoid insns that reference things
4185 set in previous insns. */
4187 for (insn
= insns
; insn
; insn
= next
)
4189 rtx set
= single_set (insn
);
4191 next
= NEXT_INSN (insn
);
4193 if (set
!= 0 && REG_P (SET_DEST (set
))
4194 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
)
4196 struct no_conflict_data data
;
4198 data
.target
= const0_rtx
;
4202 note_stores (insn
, no_conflict_move_test
, &data
);
4203 if (! data
.must_stay
)
4205 if (PREV_INSN (insn
))
4206 SET_NEXT_INSN (PREV_INSN (insn
)) = next
;
4211 SET_PREV_INSN (next
) = PREV_INSN (insn
);
4217 /* Some ports use a loop to copy large arguments onto the stack.
4218 Don't move anything outside such a loop. */
4223 /* Write the remaining insns followed by the final copy. */
4224 for (insn
= insns
; insn
; insn
= next
)
4226 next
= NEXT_INSN (insn
);
4231 last
= emit_move_insn (target
, result
);
4233 set_dst_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
), target
);
4235 if (final_dest
!= target
)
4236 emit_move_insn (final_dest
, target
);
4240 emit_libcall_block (rtx_insn
*insns
, rtx target
, rtx result
, rtx equiv
)
4242 emit_libcall_block_1 (insns
, target
, result
, equiv
, false);
4245 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
4246 PURPOSE describes how this comparison will be used. CODE is the rtx
4247 comparison code we will be using.
4249 ??? Actually, CODE is slightly weaker than that. A target is still
4250 required to implement all of the normal bcc operations, but not
4251 required to implement all (or any) of the unordered bcc operations. */
4254 can_compare_p (enum rtx_code code
, machine_mode mode
,
4255 enum can_compare_purpose purpose
)
4258 test
= gen_rtx_fmt_ee (code
, mode
, const0_rtx
, const0_rtx
);
4261 enum insn_code icode
;
4263 if (purpose
== ccp_jump
4264 && (icode
= optab_handler (cbranch_optab
, mode
)) != CODE_FOR_nothing
4265 && insn_operand_matches (icode
, 0, test
))
4267 if (purpose
== ccp_store_flag
4268 && (icode
= optab_handler (cstore_optab
, mode
)) != CODE_FOR_nothing
4269 && insn_operand_matches (icode
, 1, test
))
4271 if (purpose
== ccp_cmov
4272 && optab_handler (cmov_optab
, mode
) != CODE_FOR_nothing
)
4275 mode
= GET_MODE_WIDER_MODE (mode
).else_void ();
4276 PUT_MODE (test
, mode
);
4278 while (mode
!= VOIDmode
);
4283 /* Return whether RTL code CODE corresponds to an unsigned optab. */
4286 unsigned_optab_p (enum rtx_code code
)
4288 return code
== LTU
|| code
== LEU
|| code
== GTU
|| code
== GEU
;
4291 /* Return whether the backend-emitted comparison for code CODE, comparing
4292 operands of mode VALUE_MODE and producing a result with MASK_MODE, matches
4293 operand OPNO of pattern ICODE. */
4296 insn_predicate_matches_p (enum insn_code icode
, unsigned int opno
,
4297 enum rtx_code code
, machine_mode mask_mode
,
4298 machine_mode value_mode
)
4300 rtx reg1
= alloca_raw_REG (value_mode
, LAST_VIRTUAL_REGISTER
+ 1);
4301 rtx reg2
= alloca_raw_REG (value_mode
, LAST_VIRTUAL_REGISTER
+ 2);
4302 rtx test
= alloca_rtx_fmt_ee (code
, mask_mode
, reg1
, reg2
);
4303 return insn_operand_matches (icode
, opno
, test
);
4306 /* Return whether the backend can emit a vector comparison (vec_cmp/vec_cmpu)
4307 for code CODE, comparing operands of mode VALUE_MODE and producing a result
4311 can_vec_cmp_compare_p (enum rtx_code code
, machine_mode value_mode
,
4312 machine_mode mask_mode
)
4314 enum insn_code icode
4315 = get_vec_cmp_icode (value_mode
, mask_mode
, unsigned_optab_p (code
));
4316 if (icode
== CODE_FOR_nothing
)
4319 return insn_predicate_matches_p (icode
, 1, code
, mask_mode
, value_mode
);
4322 /* Return whether the backend can emit a vector comparison (vcond/vcondu) for
4323 code CODE, comparing operands of mode CMP_OP_MODE and producing a result
4327 can_vcond_compare_p (enum rtx_code code
, machine_mode value_mode
,
4328 machine_mode cmp_op_mode
)
4330 enum insn_code icode
4331 = get_vcond_icode (value_mode
, cmp_op_mode
, unsigned_optab_p (code
));
4332 if (icode
== CODE_FOR_nothing
)
4335 return insn_predicate_matches_p (icode
, 3, code
, value_mode
, cmp_op_mode
);
4338 /* Return whether the backend can emit vector set instructions for inserting
4339 element into vector at variable index position. */
4342 can_vec_set_var_idx_p (machine_mode vec_mode
)
4344 if (!VECTOR_MODE_P (vec_mode
))
4347 machine_mode inner_mode
= GET_MODE_INNER (vec_mode
);
4349 rtx reg1
= alloca_raw_REG (vec_mode
, LAST_VIRTUAL_REGISTER
+ 1);
4350 rtx reg2
= alloca_raw_REG (inner_mode
, LAST_VIRTUAL_REGISTER
+ 2);
4352 enum insn_code icode
= optab_handler (vec_set_optab
, vec_mode
);
4354 const struct insn_data_d
*data
= &insn_data
[icode
];
4355 machine_mode idx_mode
= data
->operand
[2].mode
;
4357 rtx reg3
= alloca_raw_REG (idx_mode
, LAST_VIRTUAL_REGISTER
+ 3);
4359 return icode
!= CODE_FOR_nothing
&& insn_operand_matches (icode
, 0, reg1
)
4360 && insn_operand_matches (icode
, 1, reg2
)
4361 && insn_operand_matches (icode
, 2, reg3
);
4364 /* This function is called when we are going to emit a compare instruction that
4365 compares the values found in X and Y, using the rtl operator COMPARISON.
4367 If they have mode BLKmode, then SIZE specifies the size of both operands.
4369 UNSIGNEDP nonzero says that the operands are unsigned;
4370 this matters if they need to be widened (as given by METHODS).
4372 *PTEST is where the resulting comparison RTX is returned or NULL_RTX
4373 if we failed to produce one.
4375 *PMODE is the mode of the inputs (in case they are const_int).
4377 This function performs all the setup necessary so that the caller only has
4378 to emit a single comparison insn. This setup can involve doing a BLKmode
4379 comparison or emitting a library call to perform the comparison if no insn
4380 is available to handle it.
4381 The values which are passed in through pointers can be modified; the caller
4382 should perform the comparison on the modified values. Constant
4383 comparisons must have already been folded. */
4386 prepare_cmp_insn (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4387 int unsignedp
, enum optab_methods methods
,
4388 rtx
*ptest
, machine_mode
*pmode
)
4390 machine_mode mode
= *pmode
;
4392 machine_mode cmp_mode
;
4394 /* The other methods are not needed. */
4395 gcc_assert (methods
== OPTAB_DIRECT
|| methods
== OPTAB_WIDEN
4396 || methods
== OPTAB_LIB_WIDEN
);
4398 if (CONST_SCALAR_INT_P (y
))
4399 canonicalize_comparison (mode
, &comparison
, &y
);
4401 /* If we are optimizing, force expensive constants into a register. */
4402 if (CONSTANT_P (x
) && optimize
4403 && (rtx_cost (x
, mode
, COMPARE
, 0, optimize_insn_for_speed_p ())
4404 > COSTS_N_INSNS (1))
4405 && can_create_pseudo_p ())
4406 x
= force_reg (mode
, x
);
4408 if (CONSTANT_P (y
) && optimize
4409 && (rtx_cost (y
, mode
, COMPARE
, 1, optimize_insn_for_speed_p ())
4410 > COSTS_N_INSNS (1))
4411 && can_create_pseudo_p ())
4412 y
= force_reg (mode
, y
);
4414 /* Don't let both operands fail to indicate the mode. */
4415 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
4416 x
= force_reg (mode
, x
);
4417 if (mode
== VOIDmode
)
4418 mode
= GET_MODE (x
) != VOIDmode
? GET_MODE (x
) : GET_MODE (y
);
4420 /* Handle all BLKmode compares. */
4422 if (mode
== BLKmode
)
4424 machine_mode result_mode
;
4425 enum insn_code cmp_code
;
4428 = GEN_INT (MIN (MEM_ALIGN (x
), MEM_ALIGN (y
)) / BITS_PER_UNIT
);
4432 /* Try to use a memory block compare insn - either cmpstr
4433 or cmpmem will do. */
4434 opt_scalar_int_mode cmp_mode_iter
;
4435 FOR_EACH_MODE_IN_CLASS (cmp_mode_iter
, MODE_INT
)
4437 scalar_int_mode cmp_mode
= cmp_mode_iter
.require ();
4438 cmp_code
= direct_optab_handler (cmpmem_optab
, cmp_mode
);
4439 if (cmp_code
== CODE_FOR_nothing
)
4440 cmp_code
= direct_optab_handler (cmpstr_optab
, cmp_mode
);
4441 if (cmp_code
== CODE_FOR_nothing
)
4442 cmp_code
= direct_optab_handler (cmpstrn_optab
, cmp_mode
);
4443 if (cmp_code
== CODE_FOR_nothing
)
4446 /* Must make sure the size fits the insn's mode. */
4447 if (CONST_INT_P (size
)
4448 ? UINTVAL (size
) > GET_MODE_MASK (cmp_mode
)
4449 : (GET_MODE_BITSIZE (as_a
<scalar_int_mode
> (GET_MODE (size
)))
4450 > GET_MODE_BITSIZE (cmp_mode
)))
4453 result_mode
= insn_data
[cmp_code
].operand
[0].mode
;
4454 result
= gen_reg_rtx (result_mode
);
4455 size
= convert_to_mode (cmp_mode
, size
, 1);
4456 emit_insn (GEN_FCN (cmp_code
) (result
, x
, y
, size
, opalign
));
4458 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, result
, const0_rtx
);
4459 *pmode
= result_mode
;
4463 if (methods
!= OPTAB_LIB
&& methods
!= OPTAB_LIB_WIDEN
)
4466 /* Otherwise call a library function. */
4467 result
= emit_block_comp_via_libcall (x
, y
, size
);
4471 mode
= TYPE_MODE (integer_type_node
);
4472 methods
= OPTAB_LIB_WIDEN
;
4476 /* Don't allow operands to the compare to trap, as that can put the
4477 compare and branch in different basic blocks. */
4478 if (cfun
->can_throw_non_call_exceptions
)
4480 if (!can_create_pseudo_p () && (may_trap_p (x
) || may_trap_p (y
)))
4483 x
= copy_to_reg (x
);
4485 y
= copy_to_reg (y
);
4488 if (GET_MODE_CLASS (mode
) == MODE_CC
)
4490 enum insn_code icode
= optab_handler (cbranch_optab
, CCmode
);
4491 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
4492 gcc_assert (icode
!= CODE_FOR_nothing
4493 && insn_operand_matches (icode
, 0, test
));
4498 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
4499 FOR_EACH_WIDER_MODE_FROM (cmp_mode
, mode
)
4501 enum insn_code icode
;
4502 icode
= optab_handler (cbranch_optab
, cmp_mode
);
4503 if (icode
!= CODE_FOR_nothing
4504 && insn_operand_matches (icode
, 0, test
))
4506 rtx_insn
*last
= get_last_insn ();
4507 rtx op0
= prepare_operand (icode
, x
, 1, mode
, cmp_mode
, unsignedp
);
4508 rtx op1
= prepare_operand (icode
, y
, 2, mode
, cmp_mode
, unsignedp
);
4510 && insn_operand_matches (icode
, 1, op0
)
4511 && insn_operand_matches (icode
, 2, op1
))
4513 XEXP (test
, 0) = op0
;
4514 XEXP (test
, 1) = op1
;
4519 delete_insns_since (last
);
4522 if (methods
== OPTAB_DIRECT
)
4526 if (methods
!= OPTAB_LIB_WIDEN
)
4529 if (SCALAR_FLOAT_MODE_P (mode
))
4531 /* Small trick if UNORDERED isn't implemented by the hardware. */
4532 if (comparison
== UNORDERED
&& rtx_equal_p (x
, y
))
4534 prepare_cmp_insn (x
, y
, UNLT
, NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4540 prepare_float_lib_cmp (x
, y
, comparison
, ptest
, pmode
);
4545 machine_mode ret_mode
;
4547 /* Handle a libcall just for the mode we are using. */
4548 libfunc
= optab_libfunc (cmp_optab
, mode
);
4549 gcc_assert (libfunc
);
4551 /* If we want unsigned, and this mode has a distinct unsigned
4552 comparison routine, use that. */
4555 rtx ulibfunc
= optab_libfunc (ucmp_optab
, mode
);
4560 ret_mode
= targetm
.libgcc_cmp_return_mode ();
4561 result
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4562 ret_mode
, x
, mode
, y
, mode
);
4564 /* There are two kinds of comparison routines. Biased routines
4565 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4566 of gcc expect that the comparison operation is equivalent
4567 to the modified comparison. For signed comparisons compare the
4568 result against 1 in the biased case, and zero in the unbiased
4569 case. For unsigned comparisons always compare against 1 after
4570 biasing the unbiased result by adding 1. This gives us a way to
4572 The comparisons in the fixed-point helper library are always
4577 if (!TARGET_LIB_INT_CMP_BIASED
&& !ALL_FIXED_POINT_MODE_P (mode
))
4580 x
= plus_constant (ret_mode
, result
, 1);
4586 prepare_cmp_insn (x
, y
, comparison
, NULL_RTX
, unsignedp
, methods
,
4596 /* Before emitting an insn with code ICODE, make sure that X, which is going
4597 to be used for operand OPNUM of the insn, is converted from mode MODE to
4598 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4599 that it is accepted by the operand predicate. Return the new value. */
4602 prepare_operand (enum insn_code icode
, rtx x
, int opnum
, machine_mode mode
,
4603 machine_mode wider_mode
, int unsignedp
)
4605 if (mode
!= wider_mode
)
4606 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
4608 if (!insn_operand_matches (icode
, opnum
, x
))
4610 machine_mode op_mode
= insn_data
[(int) icode
].operand
[opnum
].mode
;
4611 if (reload_completed
)
4613 if (GET_MODE (x
) != op_mode
&& GET_MODE (x
) != VOIDmode
)
4615 x
= copy_to_mode_reg (op_mode
, x
);
4621 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4622 we can do the branch. */
4625 emit_cmp_and_jump_insn_1 (rtx test
, machine_mode mode
, rtx label
,
4626 profile_probability prob
)
4628 machine_mode optab_mode
;
4629 enum mode_class mclass
;
4630 enum insn_code icode
;
4633 mclass
= GET_MODE_CLASS (mode
);
4634 optab_mode
= (mclass
== MODE_CC
) ? CCmode
: mode
;
4635 icode
= optab_handler (cbranch_optab
, optab_mode
);
4637 gcc_assert (icode
!= CODE_FOR_nothing
);
4638 gcc_assert (insn_operand_matches (icode
, 0, test
));
4639 insn
= emit_jump_insn (GEN_FCN (icode
) (test
, XEXP (test
, 0),
4640 XEXP (test
, 1), label
));
4641 if (prob
.initialized_p ()
4642 && profile_status_for_fn (cfun
) != PROFILE_ABSENT
4645 && any_condjump_p (insn
)
4646 && !find_reg_note (insn
, REG_BR_PROB
, 0))
4647 add_reg_br_prob_note (insn
, prob
);
4650 /* Generate code to compare X with Y so that the condition codes are
4651 set and to jump to LABEL if the condition is true. If X is a
4652 constant and Y is not a constant, then the comparison is swapped to
4653 ensure that the comparison RTL has the canonical form.
4655 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4656 need to be widened. UNSIGNEDP is also used to select the proper
4657 branch condition code.
4659 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4661 MODE is the mode of the inputs (in case they are const_int).
4663 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4664 It will be potentially converted into an unsigned variant based on
4665 UNSIGNEDP to select a proper jump instruction.
4667 PROB is the probability of jumping to LABEL. */
4670 emit_cmp_and_jump_insns (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4671 machine_mode mode
, int unsignedp
, rtx label
,
4672 profile_probability prob
)
4674 rtx op0
= x
, op1
= y
;
4677 /* Swap operands and condition to ensure canonical RTL. */
4678 if (swap_commutative_operands_p (x
, y
)
4679 && can_compare_p (swap_condition (comparison
), mode
, ccp_jump
))
4682 comparison
= swap_condition (comparison
);
4685 /* If OP0 is still a constant, then both X and Y must be constants
4686 or the opposite comparison is not supported. Force X into a register
4687 to create canonical RTL. */
4688 if (CONSTANT_P (op0
))
4689 op0
= force_reg (mode
, op0
);
4692 comparison
= unsigned_condition (comparison
);
4694 prepare_cmp_insn (op0
, op1
, comparison
, size
, unsignedp
, OPTAB_LIB_WIDEN
,
4696 emit_cmp_and_jump_insn_1 (test
, mode
, label
, prob
);
4700 /* Emit a library call comparison between floating point X and Y.
4701 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4704 prepare_float_lib_cmp (rtx x
, rtx y
, enum rtx_code comparison
,
4705 rtx
*ptest
, machine_mode
*pmode
)
4707 enum rtx_code swapped
= swap_condition (comparison
);
4708 enum rtx_code reversed
= reverse_condition_maybe_unordered (comparison
);
4709 machine_mode orig_mode
= GET_MODE (x
);
4711 rtx true_rtx
, false_rtx
;
4712 rtx value
, target
, equiv
;
4715 bool reversed_p
= false;
4716 scalar_int_mode cmp_mode
= targetm
.libgcc_cmp_return_mode ();
4718 FOR_EACH_WIDER_MODE_FROM (mode
, orig_mode
)
4720 if (code_to_optab (comparison
)
4721 && (libfunc
= optab_libfunc (code_to_optab (comparison
), mode
)))
4724 if (code_to_optab (swapped
)
4725 && (libfunc
= optab_libfunc (code_to_optab (swapped
), mode
)))
4728 comparison
= swapped
;
4732 if (code_to_optab (reversed
)
4733 && (libfunc
= optab_libfunc (code_to_optab (reversed
), mode
)))
4735 comparison
= reversed
;
4741 gcc_assert (mode
!= VOIDmode
);
4743 if (mode
!= orig_mode
)
4745 x
= convert_to_mode (mode
, x
, 0);
4746 y
= convert_to_mode (mode
, y
, 0);
4749 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4750 the RTL. The allows the RTL optimizers to delete the libcall if the
4751 condition can be determined at compile-time. */
4752 if (comparison
== UNORDERED
4753 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4755 true_rtx
= const_true_rtx
;
4756 false_rtx
= const0_rtx
;
4763 true_rtx
= const0_rtx
;
4764 false_rtx
= const_true_rtx
;
4768 true_rtx
= const_true_rtx
;
4769 false_rtx
= const0_rtx
;
4773 true_rtx
= const1_rtx
;
4774 false_rtx
= const0_rtx
;
4778 true_rtx
= const0_rtx
;
4779 false_rtx
= constm1_rtx
;
4783 true_rtx
= constm1_rtx
;
4784 false_rtx
= const0_rtx
;
4788 true_rtx
= const0_rtx
;
4789 false_rtx
= const1_rtx
;
4797 if (comparison
== UNORDERED
)
4799 rtx temp
= simplify_gen_relational (NE
, cmp_mode
, mode
, x
, x
);
4800 equiv
= simplify_gen_relational (NE
, cmp_mode
, mode
, y
, y
);
4801 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4802 temp
, const_true_rtx
, equiv
);
4806 equiv
= simplify_gen_relational (comparison
, cmp_mode
, mode
, x
, y
);
4807 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4808 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4809 equiv
, true_rtx
, false_rtx
);
4813 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4814 cmp_mode
, x
, mode
, y
, mode
);
4815 insns
= get_insns ();
4818 target
= gen_reg_rtx (cmp_mode
);
4819 emit_libcall_block (insns
, target
, value
, equiv
);
4821 if (comparison
== UNORDERED
4822 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
)
4824 *ptest
= gen_rtx_fmt_ee (reversed_p
? EQ
: NE
, VOIDmode
, target
, false_rtx
);
4826 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, target
, const0_rtx
);
4831 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4834 emit_indirect_jump (rtx loc
)
4836 if (!targetm
.have_indirect_jump ())
4837 sorry ("indirect jumps are not available on this target");
4840 class expand_operand ops
[1];
4841 create_address_operand (&ops
[0], loc
);
4842 expand_jump_insn (targetm
.code_for_indirect_jump
, 1, ops
);
4848 /* Emit a conditional move instruction if the machine supports one for that
4849 condition and machine mode.
4851 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4852 the mode to use should they be constants. If it is VOIDmode, they cannot
4855 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4856 should be stored there. MODE is the mode to use should they be constants.
4857 If it is VOIDmode, they cannot both be constants.
4859 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4860 is not supported. */
4863 emit_conditional_move (rtx target
, struct rtx_comparison comp
,
4865 machine_mode mode
, int unsignedp
)
4869 enum insn_code icode
;
4870 enum rtx_code reversed
;
4872 /* If the two source operands are identical, that's just a move. */
4874 if (rtx_equal_p (op2
, op3
))
4877 target
= gen_reg_rtx (mode
);
4879 emit_move_insn (target
, op3
);
4883 /* If one operand is constant, make it the second one. Only do this
4884 if the other operand is not constant as well. */
4886 if (swap_commutative_operands_p (comp
.op0
, comp
.op1
))
4888 std::swap (comp
.op0
, comp
.op1
);
4889 comp
.code
= swap_condition (comp
.code
);
4892 /* get_condition will prefer to generate LT and GT even if the old
4893 comparison was against zero, so undo that canonicalization here since
4894 comparisons against zero are cheaper. */
4896 if (comp
.code
== LT
&& comp
.op1
== const1_rtx
)
4897 comp
.code
= LE
, comp
.op1
= const0_rtx
;
4898 else if (comp
.code
== GT
&& comp
.op1
== constm1_rtx
)
4899 comp
.code
= GE
, comp
.op1
= const0_rtx
;
4901 if (comp
.mode
== VOIDmode
)
4902 comp
.mode
= GET_MODE (comp
.op0
);
4904 enum rtx_code orig_code
= comp
.code
;
4905 bool swapped
= false;
4906 if (swap_commutative_operands_p (op2
, op3
)
4908 reversed_comparison_code_parts (comp
.code
, comp
.op0
, comp
.op1
, NULL
))
4911 std::swap (op2
, op3
);
4912 comp
.code
= reversed
;
4916 if (mode
== VOIDmode
)
4917 mode
= GET_MODE (op2
);
4919 icode
= direct_optab_handler (movcc_optab
, mode
);
4921 if (icode
== CODE_FOR_nothing
)
4925 target
= gen_reg_rtx (mode
);
4927 for (int pass
= 0; ; pass
++)
4929 comp
.code
= unsignedp
? unsigned_condition (comp
.code
) : comp
.code
;
4931 simplify_gen_relational (comp
.code
, VOIDmode
,
4932 comp
.mode
, comp
.op0
, comp
.op1
);
4934 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4935 punt and let the caller figure out how best to deal with this
4937 if (COMPARISON_P (comparison
))
4939 saved_pending_stack_adjust save
;
4940 save_pending_stack_adjust (&save
);
4941 last
= get_last_insn ();
4942 do_pending_stack_adjust ();
4943 machine_mode cmpmode
= comp
.mode
;
4944 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4945 GET_CODE (comparison
), NULL_RTX
, unsignedp
,
4946 OPTAB_WIDEN
, &comparison
, &cmpmode
);
4949 rtx res
= emit_conditional_move_1 (target
, comparison
,
4951 if (res
!= NULL_RTX
)
4954 delete_insns_since (last
);
4955 restore_pending_stack_adjust (&save
);
4961 /* If the preferred op2/op3 order is not usable, retry with other
4962 operand order, perhaps it will expand successfully. */
4964 comp
.code
= orig_code
;
4965 else if ((reversed
=
4966 reversed_comparison_code_parts (orig_code
, comp
.op0
, comp
.op1
,
4969 comp
.code
= reversed
;
4972 std::swap (op2
, op3
);
4976 /* Helper function that, in addition to COMPARISON, also tries
4977 the reversed REV_COMPARISON with swapped OP2 and OP3. As opposed
4978 to when we pass the specific constituents of a comparison, no
4979 additional insns are emitted for it. It might still be necessary
4980 to emit more than one insn for the final conditional move, though. */
4983 emit_conditional_move (rtx target
, rtx comparison
, rtx rev_comparison
,
4984 rtx op2
, rtx op3
, machine_mode mode
)
4986 rtx res
= emit_conditional_move_1 (target
, comparison
, op2
, op3
, mode
);
4988 if (res
!= NULL_RTX
)
4991 return emit_conditional_move_1 (target
, rev_comparison
, op3
, op2
, mode
);
4994 /* Helper for emitting a conditional move. */
4997 emit_conditional_move_1 (rtx target
, rtx comparison
,
4998 rtx op2
, rtx op3
, machine_mode mode
)
5000 enum insn_code icode
;
5002 if (comparison
== NULL_RTX
|| !COMPARISON_P (comparison
))
5005 /* If the two source operands are identical, that's just a move.
5006 As the comparison comes in non-canonicalized, we must make
5007 sure not to discard any possible side effects. If there are
5008 side effects, just let the target handle it. */
5009 if (!side_effects_p (comparison
) && rtx_equal_p (op2
, op3
))
5012 target
= gen_reg_rtx (mode
);
5014 emit_move_insn (target
, op3
);
5018 if (mode
== VOIDmode
)
5019 mode
= GET_MODE (op2
);
5021 icode
= direct_optab_handler (movcc_optab
, mode
);
5023 if (icode
== CODE_FOR_nothing
)
5027 target
= gen_reg_rtx (mode
);
5029 class expand_operand ops
[4];
5031 create_output_operand (&ops
[0], target
, mode
);
5032 create_fixed_operand (&ops
[1], comparison
);
5033 create_input_operand (&ops
[2], op2
, mode
);
5034 create_input_operand (&ops
[3], op3
, mode
);
5036 if (maybe_expand_insn (icode
, 4, ops
))
5038 if (ops
[0].value
!= target
)
5039 convert_move (target
, ops
[0].value
, false);
5047 /* Emit a conditional negate or bitwise complement using the
5048 negcc or notcc optabs if available. Return NULL_RTX if such operations
5049 are not available. Otherwise return the RTX holding the result.
5050 TARGET is the desired destination of the result. COMP is the comparison
5051 on which to negate. If COND is true move into TARGET the negation
5052 or bitwise complement of OP1. Otherwise move OP2 into TARGET.
5053 CODE is either NEG or NOT. MODE is the machine mode in which the
5054 operation is performed. */
5057 emit_conditional_neg_or_complement (rtx target
, rtx_code code
,
5058 machine_mode mode
, rtx cond
, rtx op1
,
5061 optab op
= unknown_optab
;
5064 else if (code
== NOT
)
5069 insn_code icode
= direct_optab_handler (op
, mode
);
5071 if (icode
== CODE_FOR_nothing
)
5075 target
= gen_reg_rtx (mode
);
5077 rtx_insn
*last
= get_last_insn ();
5078 class expand_operand ops
[4];
5080 create_output_operand (&ops
[0], target
, mode
);
5081 create_fixed_operand (&ops
[1], cond
);
5082 create_input_operand (&ops
[2], op1
, mode
);
5083 create_input_operand (&ops
[3], op2
, mode
);
5085 if (maybe_expand_insn (icode
, 4, ops
))
5087 if (ops
[0].value
!= target
)
5088 convert_move (target
, ops
[0].value
, false);
5092 delete_insns_since (last
);
5096 /* Emit a conditional addition instruction if the machine supports one for that
5097 condition and machine mode.
5099 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
5100 the mode to use should they be constants. If it is VOIDmode, they cannot
5103 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
5104 should be stored there. MODE is the mode to use should they be constants.
5105 If it is VOIDmode, they cannot both be constants.
5107 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
5108 is not supported. */
5111 emit_conditional_add (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
5112 machine_mode cmode
, rtx op2
, rtx op3
,
5113 machine_mode mode
, int unsignedp
)
5117 enum insn_code icode
;
5119 /* If one operand is constant, make it the second one. Only do this
5120 if the other operand is not constant as well. */
5122 if (swap_commutative_operands_p (op0
, op1
))
5124 std::swap (op0
, op1
);
5125 code
= swap_condition (code
);
5128 /* get_condition will prefer to generate LT and GT even if the old
5129 comparison was against zero, so undo that canonicalization here since
5130 comparisons against zero are cheaper. */
5131 if (code
== LT
&& op1
== const1_rtx
)
5132 code
= LE
, op1
= const0_rtx
;
5133 else if (code
== GT
&& op1
== constm1_rtx
)
5134 code
= GE
, op1
= const0_rtx
;
5136 if (cmode
== VOIDmode
)
5137 cmode
= GET_MODE (op0
);
5139 if (mode
== VOIDmode
)
5140 mode
= GET_MODE (op2
);
5142 icode
= optab_handler (addcc_optab
, mode
);
5144 if (icode
== CODE_FOR_nothing
)
5148 target
= gen_reg_rtx (mode
);
5150 code
= unsignedp
? unsigned_condition (code
) : code
;
5151 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
5153 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
5154 return NULL and let the caller figure out how best to deal with this
5156 if (!COMPARISON_P (comparison
))
5159 do_pending_stack_adjust ();
5160 last
= get_last_insn ();
5161 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
5162 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
5163 &comparison
, &cmode
);
5166 class expand_operand ops
[4];
5168 create_output_operand (&ops
[0], target
, mode
);
5169 create_fixed_operand (&ops
[1], comparison
);
5170 create_input_operand (&ops
[2], op2
, mode
);
5171 create_input_operand (&ops
[3], op3
, mode
);
5172 if (maybe_expand_insn (icode
, 4, ops
))
5174 if (ops
[0].value
!= target
)
5175 convert_move (target
, ops
[0].value
, false);
5179 delete_insns_since (last
);
5183 /* These functions attempt to generate an insn body, rather than
5184 emitting the insn, but if the gen function already emits them, we
5185 make no attempt to turn them back into naked patterns. */
5187 /* Generate and return an insn body to add Y to X. */
5190 gen_add2_insn (rtx x
, rtx y
)
5192 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (x
));
5194 gcc_assert (insn_operand_matches (icode
, 0, x
));
5195 gcc_assert (insn_operand_matches (icode
, 1, x
));
5196 gcc_assert (insn_operand_matches (icode
, 2, y
));
5198 return GEN_FCN (icode
) (x
, x
, y
);
5201 /* Generate and return an insn body to add r1 and c,
5202 storing the result in r0. */
5205 gen_add3_insn (rtx r0
, rtx r1
, rtx c
)
5207 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (r0
));
5209 if (icode
== CODE_FOR_nothing
5210 || !insn_operand_matches (icode
, 0, r0
)
5211 || !insn_operand_matches (icode
, 1, r1
)
5212 || !insn_operand_matches (icode
, 2, c
))
5215 return GEN_FCN (icode
) (r0
, r1
, c
);
5219 have_add2_insn (rtx x
, rtx y
)
5221 enum insn_code icode
;
5223 gcc_assert (GET_MODE (x
) != VOIDmode
);
5225 icode
= optab_handler (add_optab
, GET_MODE (x
));
5227 if (icode
== CODE_FOR_nothing
)
5230 if (!insn_operand_matches (icode
, 0, x
)
5231 || !insn_operand_matches (icode
, 1, x
)
5232 || !insn_operand_matches (icode
, 2, y
))
5238 /* Generate and return an insn body to add Y to X. */
5241 gen_addptr3_insn (rtx x
, rtx y
, rtx z
)
5243 enum insn_code icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
5245 gcc_assert (insn_operand_matches (icode
, 0, x
));
5246 gcc_assert (insn_operand_matches (icode
, 1, y
));
5247 gcc_assert (insn_operand_matches (icode
, 2, z
));
5249 return GEN_FCN (icode
) (x
, y
, z
);
5252 /* Return true if the target implements an addptr pattern and X, Y,
5253 and Z are valid for the pattern predicates. */
5256 have_addptr3_insn (rtx x
, rtx y
, rtx z
)
5258 enum insn_code icode
;
5260 gcc_assert (GET_MODE (x
) != VOIDmode
);
5262 icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
5264 if (icode
== CODE_FOR_nothing
)
5267 if (!insn_operand_matches (icode
, 0, x
)
5268 || !insn_operand_matches (icode
, 1, y
)
5269 || !insn_operand_matches (icode
, 2, z
))
5275 /* Generate and return an insn body to subtract Y from X. */
5278 gen_sub2_insn (rtx x
, rtx y
)
5280 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (x
));
5282 gcc_assert (insn_operand_matches (icode
, 0, x
));
5283 gcc_assert (insn_operand_matches (icode
, 1, x
));
5284 gcc_assert (insn_operand_matches (icode
, 2, y
));
5286 return GEN_FCN (icode
) (x
, x
, y
);
5289 /* Generate and return an insn body to subtract r1 and c,
5290 storing the result in r0. */
5293 gen_sub3_insn (rtx r0
, rtx r1
, rtx c
)
5295 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (r0
));
5297 if (icode
== CODE_FOR_nothing
5298 || !insn_operand_matches (icode
, 0, r0
)
5299 || !insn_operand_matches (icode
, 1, r1
)
5300 || !insn_operand_matches (icode
, 2, c
))
5303 return GEN_FCN (icode
) (r0
, r1
, c
);
5307 have_sub2_insn (rtx x
, rtx y
)
5309 enum insn_code icode
;
5311 gcc_assert (GET_MODE (x
) != VOIDmode
);
5313 icode
= optab_handler (sub_optab
, GET_MODE (x
));
5315 if (icode
== CODE_FOR_nothing
)
5318 if (!insn_operand_matches (icode
, 0, x
)
5319 || !insn_operand_matches (icode
, 1, x
)
5320 || !insn_operand_matches (icode
, 2, y
))
5326 /* Generate the body of an insn to extend Y (with mode MFROM)
5327 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
5330 gen_extend_insn (rtx x
, rtx y
, machine_mode mto
,
5331 machine_mode mfrom
, int unsignedp
)
5333 enum insn_code icode
= can_extend_p (mto
, mfrom
, unsignedp
);
5334 return GEN_FCN (icode
) (x
, y
);
5337 /* Generate code to convert FROM to floating point
5338 and store in TO. FROM must be fixed point and not VOIDmode.
5339 UNSIGNEDP nonzero means regard FROM as unsigned.
5340 Normally this is done by correcting the final value
5341 if it is negative. */
5344 expand_float (rtx to
, rtx from
, int unsignedp
)
5346 enum insn_code icode
;
5348 scalar_mode from_mode
, to_mode
;
5349 machine_mode fmode
, imode
;
5350 bool can_do_signed
= false;
5352 /* Crash now, because we won't be able to decide which mode to use. */
5353 gcc_assert (GET_MODE (from
) != VOIDmode
);
5355 /* Look for an insn to do the conversion. Do it in the specified
5356 modes if possible; otherwise convert either input, output or both to
5357 wider mode. If the integer mode is wider than the mode of FROM,
5358 we can do the conversion signed even if the input is unsigned. */
5360 FOR_EACH_MODE_FROM (fmode
, GET_MODE (to
))
5361 FOR_EACH_MODE_FROM (imode
, GET_MODE (from
))
5363 int doing_unsigned
= unsignedp
;
5365 if (fmode
!= GET_MODE (to
)
5366 && (significand_size (fmode
)
5367 < GET_MODE_UNIT_PRECISION (GET_MODE (from
))))
5370 icode
= can_float_p (fmode
, imode
, unsignedp
);
5371 if (icode
== CODE_FOR_nothing
&& unsignedp
)
5373 enum insn_code scode
= can_float_p (fmode
, imode
, 0);
5374 if (scode
!= CODE_FOR_nothing
)
5375 can_do_signed
= true;
5376 if (imode
!= GET_MODE (from
))
5377 icode
= scode
, doing_unsigned
= 0;
5380 if (icode
!= CODE_FOR_nothing
)
5382 if (imode
!= GET_MODE (from
))
5383 from
= convert_to_mode (imode
, from
, unsignedp
);
5385 if (fmode
!= GET_MODE (to
))
5386 target
= gen_reg_rtx (fmode
);
5388 emit_unop_insn (icode
, target
, from
,
5389 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
5392 convert_move (to
, target
, 0);
5397 /* Unsigned integer, and no way to convert directly. Convert as signed,
5398 then unconditionally adjust the result. */
5401 && is_a
<scalar_mode
> (GET_MODE (to
), &to_mode
)
5402 && is_a
<scalar_mode
> (GET_MODE (from
), &from_mode
))
5404 opt_scalar_mode fmode_iter
;
5405 rtx_code_label
*label
= gen_label_rtx ();
5407 REAL_VALUE_TYPE offset
;
5409 /* Look for a usable floating mode FMODE wider than the source and at
5410 least as wide as the target. Using FMODE will avoid rounding woes
5411 with unsigned values greater than the signed maximum value. */
5413 FOR_EACH_MODE_FROM (fmode_iter
, to_mode
)
5415 scalar_mode fmode
= fmode_iter
.require ();
5416 if (GET_MODE_PRECISION (from_mode
) < GET_MODE_BITSIZE (fmode
)
5417 && can_float_p (fmode
, from_mode
, 0) != CODE_FOR_nothing
)
5421 if (!fmode_iter
.exists (&fmode
))
5423 /* There is no such mode. Pretend the target is wide enough. */
5426 /* Avoid double-rounding when TO is narrower than FROM. */
5427 if ((significand_size (fmode
) + 1)
5428 < GET_MODE_PRECISION (from_mode
))
5431 rtx_code_label
*neglabel
= gen_label_rtx ();
5433 /* Don't use TARGET if it isn't a register, is a hard register,
5434 or is the wrong mode. */
5436 || REGNO (target
) < FIRST_PSEUDO_REGISTER
5437 || GET_MODE (target
) != fmode
)
5438 target
= gen_reg_rtx (fmode
);
5441 do_pending_stack_adjust ();
5443 /* Test whether the sign bit is set. */
5444 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
5447 /* The sign bit is not set. Convert as signed. */
5448 expand_float (target
, from
, 0);
5449 emit_jump_insn (targetm
.gen_jump (label
));
5452 /* The sign bit is set.
5453 Convert to a usable (positive signed) value by shifting right
5454 one bit, while remembering if a nonzero bit was shifted
5455 out; i.e., compute (from & 1) | (from >> 1). */
5457 emit_label (neglabel
);
5458 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
5459 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5460 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, 1, NULL_RTX
, 1);
5461 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
5463 expand_float (target
, temp
, 0);
5465 /* Multiply by 2 to undo the shift above. */
5466 temp
= expand_binop (fmode
, add_optab
, target
, target
,
5467 target
, 0, OPTAB_LIB_WIDEN
);
5469 emit_move_insn (target
, temp
);
5471 do_pending_stack_adjust ();
5477 /* If we are about to do some arithmetic to correct for an
5478 unsigned operand, do it in a pseudo-register. */
5480 if (to_mode
!= fmode
5481 || !REG_P (to
) || REGNO (to
) < FIRST_PSEUDO_REGISTER
)
5482 target
= gen_reg_rtx (fmode
);
5484 /* Convert as signed integer to floating. */
5485 expand_float (target
, from
, 0);
5487 /* If FROM is negative (and therefore TO is negative),
5488 correct its value by 2**bitwidth. */
5490 do_pending_stack_adjust ();
5491 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, from_mode
,
5495 real_2expN (&offset
, GET_MODE_PRECISION (from_mode
), fmode
);
5496 temp
= expand_binop (fmode
, add_optab
, target
,
5497 const_double_from_real_value (offset
, fmode
),
5498 target
, 0, OPTAB_LIB_WIDEN
);
5500 emit_move_insn (target
, temp
);
5502 do_pending_stack_adjust ();
5507 /* No hardware instruction available; call a library routine. */
5512 convert_optab tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
5514 if (is_narrower_int_mode (GET_MODE (from
), SImode
))
5515 from
= convert_to_mode (SImode
, from
, unsignedp
);
5517 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5518 gcc_assert (libfunc
);
5522 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5523 GET_MODE (to
), from
, GET_MODE (from
));
5524 insns
= get_insns ();
5527 emit_libcall_block (insns
, target
, value
,
5528 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FLOAT
: FLOAT
,
5529 GET_MODE (to
), from
));
5534 /* Copy result to requested destination
5535 if we have been computing in a temp location. */
5539 if (GET_MODE (target
) == GET_MODE (to
))
5540 emit_move_insn (to
, target
);
5542 convert_move (to
, target
, 0);
5546 /* Generate code to convert FROM to fixed point and store in TO. FROM
5547 must be floating point. */
5550 expand_fix (rtx to
, rtx from
, int unsignedp
)
5552 enum insn_code icode
;
5554 machine_mode fmode
, imode
;
5555 opt_scalar_mode fmode_iter
;
5556 bool must_trunc
= false;
5558 /* We first try to find a pair of modes, one real and one integer, at
5559 least as wide as FROM and TO, respectively, in which we can open-code
5560 this conversion. If the integer mode is wider than the mode of TO,
5561 we can do the conversion either signed or unsigned. */
5563 FOR_EACH_MODE_FROM (fmode
, GET_MODE (from
))
5564 FOR_EACH_MODE_FROM (imode
, GET_MODE (to
))
5566 int doing_unsigned
= unsignedp
;
5568 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
5569 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
5570 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
5572 if (icode
!= CODE_FOR_nothing
)
5574 rtx_insn
*last
= get_last_insn ();
5576 if (fmode
!= GET_MODE (from
))
5577 from1
= convert_to_mode (fmode
, from
, 0);
5581 rtx temp
= gen_reg_rtx (GET_MODE (from1
));
5582 from1
= expand_unop (GET_MODE (from1
), ftrunc_optab
, from1
,
5586 if (imode
!= GET_MODE (to
))
5587 target
= gen_reg_rtx (imode
);
5589 if (maybe_emit_unop_insn (icode
, target
, from1
,
5590 doing_unsigned
? UNSIGNED_FIX
: FIX
))
5593 convert_move (to
, target
, unsignedp
);
5596 delete_insns_since (last
);
5600 /* For an unsigned conversion, there is one more way to do it.
5601 If we have a signed conversion, we generate code that compares
5602 the real value to the largest representable positive number. If if
5603 is smaller, the conversion is done normally. Otherwise, subtract
5604 one plus the highest signed number, convert, and add it back.
5606 We only need to check all real modes, since we know we didn't find
5607 anything with a wider integer mode.
5609 This code used to extend FP value into mode wider than the destination.
5610 This is needed for decimal float modes which cannot accurately
5611 represent one plus the highest signed number of the same size, but
5612 not for binary modes. Consider, for instance conversion from SFmode
5615 The hot path through the code is dealing with inputs smaller than 2^63
5616 and doing just the conversion, so there is no bits to lose.
5618 In the other path we know the value is positive in the range 2^63..2^64-1
5619 inclusive. (as for other input overflow happens and result is undefined)
5620 So we know that the most important bit set in mantissa corresponds to
5621 2^63. The subtraction of 2^63 should not generate any rounding as it
5622 simply clears out that bit. The rest is trivial. */
5624 scalar_int_mode to_mode
;
5626 && is_a
<scalar_int_mode
> (GET_MODE (to
), &to_mode
)
5627 && HWI_COMPUTABLE_MODE_P (to_mode
))
5628 FOR_EACH_MODE_FROM (fmode_iter
, as_a
<scalar_mode
> (GET_MODE (from
)))
5630 scalar_mode fmode
= fmode_iter
.require ();
5631 if (CODE_FOR_nothing
!= can_fix_p (to_mode
, fmode
,
5633 && (!DECIMAL_FLOAT_MODE_P (fmode
)
5634 || (GET_MODE_BITSIZE (fmode
) > GET_MODE_PRECISION (to_mode
))))
5637 REAL_VALUE_TYPE offset
;
5639 rtx_code_label
*lab1
, *lab2
;
5642 bitsize
= GET_MODE_PRECISION (to_mode
);
5643 real_2expN (&offset
, bitsize
- 1, fmode
);
5644 limit
= const_double_from_real_value (offset
, fmode
);
5645 lab1
= gen_label_rtx ();
5646 lab2
= gen_label_rtx ();
5648 if (fmode
!= GET_MODE (from
))
5649 from
= convert_to_mode (fmode
, from
, 0);
5651 /* See if we need to do the subtraction. */
5652 do_pending_stack_adjust ();
5653 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
,
5654 GET_MODE (from
), 0, lab1
);
5656 /* If not, do the signed "fix" and branch around fixup code. */
5657 expand_fix (to
, from
, 0);
5658 emit_jump_insn (targetm
.gen_jump (lab2
));
5661 /* Otherwise, subtract 2**(N-1), convert to signed number,
5662 then add 2**(N-1). Do the addition using XOR since this
5663 will often generate better code. */
5665 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
5666 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
5667 expand_fix (to
, target
, 0);
5668 target
= expand_binop (to_mode
, xor_optab
, to
,
5670 (HOST_WIDE_INT_1
<< (bitsize
- 1),
5672 to
, 1, OPTAB_LIB_WIDEN
);
5675 emit_move_insn (to
, target
);
5679 if (optab_handler (mov_optab
, to_mode
) != CODE_FOR_nothing
)
5681 /* Make a place for a REG_NOTE and add it. */
5682 insn
= emit_move_insn (to
, to
);
5683 set_dst_reg_note (insn
, REG_EQUAL
,
5684 gen_rtx_fmt_e (UNSIGNED_FIX
, to_mode
,
5693 /* We can't do it with an insn, so use a library call. But first ensure
5694 that the mode of TO is at least as wide as SImode, since those are the
5695 only library calls we know about. */
5697 if (is_narrower_int_mode (GET_MODE (to
), SImode
))
5699 target
= gen_reg_rtx (SImode
);
5701 expand_fix (target
, from
, unsignedp
);
5709 convert_optab tab
= unsignedp
? ufix_optab
: sfix_optab
;
5710 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5711 gcc_assert (libfunc
);
5715 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5716 GET_MODE (to
), from
, GET_MODE (from
));
5717 insns
= get_insns ();
5720 emit_libcall_block (insns
, target
, value
,
5721 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
5722 GET_MODE (to
), from
));
5727 if (GET_MODE (to
) == GET_MODE (target
))
5728 emit_move_insn (to
, target
);
5730 convert_move (to
, target
, 0);
5735 /* Promote integer arguments for a libcall if necessary.
5736 emit_library_call_value cannot do the promotion because it does not
5737 know if it should do a signed or unsigned promotion. This is because
5738 there are no tree types defined for libcalls. */
5741 prepare_libcall_arg (rtx arg
, int uintp
)
5743 scalar_int_mode mode
;
5744 machine_mode arg_mode
;
5745 if (is_a
<scalar_int_mode
> (GET_MODE (arg
), &mode
))
5747 /* If we need to promote the integer function argument we need to do
5748 it here instead of inside emit_library_call_value because in
5749 emit_library_call_value we don't know if we should do a signed or
5750 unsigned promotion. */
5753 arg_mode
= promote_function_mode (NULL_TREE
, mode
,
5754 &unsigned_p
, NULL_TREE
, 0);
5755 if (arg_mode
!= mode
)
5756 return convert_to_mode (arg_mode
, arg
, uintp
);
5761 /* Generate code to convert FROM or TO a fixed-point.
5762 If UINTP is true, either TO or FROM is an unsigned integer.
5763 If SATP is true, we need to saturate the result. */
5766 expand_fixed_convert (rtx to
, rtx from
, int uintp
, int satp
)
5768 machine_mode to_mode
= GET_MODE (to
);
5769 machine_mode from_mode
= GET_MODE (from
);
5771 enum rtx_code this_code
;
5772 enum insn_code code
;
5777 if (to_mode
== from_mode
)
5779 emit_move_insn (to
, from
);
5785 tab
= satp
? satfractuns_optab
: fractuns_optab
;
5786 this_code
= satp
? UNSIGNED_SAT_FRACT
: UNSIGNED_FRACT_CONVERT
;
5790 tab
= satp
? satfract_optab
: fract_optab
;
5791 this_code
= satp
? SAT_FRACT
: FRACT_CONVERT
;
5793 code
= convert_optab_handler (tab
, to_mode
, from_mode
);
5794 if (code
!= CODE_FOR_nothing
)
5796 emit_unop_insn (code
, to
, from
, this_code
);
5800 libfunc
= convert_optab_libfunc (tab
, to_mode
, from_mode
);
5801 gcc_assert (libfunc
);
5803 from
= prepare_libcall_arg (from
, uintp
);
5804 from_mode
= GET_MODE (from
);
5807 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, to_mode
,
5809 insns
= get_insns ();
5812 emit_libcall_block (insns
, to
, value
,
5813 gen_rtx_fmt_e (optab_to_code (tab
), to_mode
, from
));
5816 /* Generate code to convert FROM to fixed point and store in TO. FROM
5817 must be floating point, TO must be signed. Use the conversion optab
5818 TAB to do the conversion. */
5821 expand_sfix_optab (rtx to
, rtx from
, convert_optab tab
)
5823 enum insn_code icode
;
5825 machine_mode fmode
, imode
;
5827 /* We first try to find a pair of modes, one real and one integer, at
5828 least as wide as FROM and TO, respectively, in which we can open-code
5829 this conversion. If the integer mode is wider than the mode of TO,
5830 we can do the conversion either signed or unsigned. */
5832 FOR_EACH_MODE_FROM (fmode
, GET_MODE (from
))
5833 FOR_EACH_MODE_FROM (imode
, GET_MODE (to
))
5835 icode
= convert_optab_handler (tab
, imode
, fmode
,
5836 insn_optimization_type ());
5837 if (icode
!= CODE_FOR_nothing
)
5839 rtx_insn
*last
= get_last_insn ();
5840 if (fmode
!= GET_MODE (from
))
5841 from
= convert_to_mode (fmode
, from
, 0);
5843 if (imode
!= GET_MODE (to
))
5844 target
= gen_reg_rtx (imode
);
5846 if (!maybe_emit_unop_insn (icode
, target
, from
, UNKNOWN
))
5848 delete_insns_since (last
);
5852 convert_move (to
, target
, 0);
5860 /* Report whether we have an instruction to perform the operation
5861 specified by CODE on operands of mode MODE. */
5863 have_insn_for (enum rtx_code code
, machine_mode mode
)
5865 return (code_to_optab (code
)
5866 && (optab_handler (code_to_optab (code
), mode
)
5867 != CODE_FOR_nothing
));
5870 /* Print information about the current contents of the optabs on
5874 debug_optab_libfuncs (void)
5878 /* Dump the arithmetic optabs. */
5879 for (i
= FIRST_NORM_OPTAB
; i
<= LAST_NORMLIB_OPTAB
; ++i
)
5880 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
5882 rtx l
= optab_libfunc ((optab
) i
, (machine_mode
) j
);
5885 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
5886 fprintf (stderr
, "%s\t%s:\t%s\n",
5887 GET_RTX_NAME (optab_to_code ((optab
) i
)),
5893 /* Dump the conversion optabs. */
5894 for (i
= FIRST_CONV_OPTAB
; i
<= LAST_CONVLIB_OPTAB
; ++i
)
5895 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
5896 for (k
= 0; k
< NUM_MACHINE_MODES
; ++k
)
5898 rtx l
= convert_optab_libfunc ((optab
) i
, (machine_mode
) j
,
5902 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
5903 fprintf (stderr
, "%s\t%s\t%s:\t%s\n",
5904 GET_RTX_NAME (optab_to_code ((optab
) i
)),
5912 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5913 CODE. Return 0 on failure. */
5916 gen_cond_trap (enum rtx_code code
, rtx op1
, rtx op2
, rtx tcode
)
5918 machine_mode mode
= GET_MODE (op1
);
5919 enum insn_code icode
;
5923 if (mode
== VOIDmode
)
5926 icode
= optab_handler (ctrap_optab
, mode
);
5927 if (icode
== CODE_FOR_nothing
)
5930 /* Some targets only accept a zero trap code. */
5931 if (!insn_operand_matches (icode
, 3, tcode
))
5934 do_pending_stack_adjust ();
5936 prepare_cmp_insn (op1
, op2
, code
, NULL_RTX
, false, OPTAB_DIRECT
,
5941 insn
= GEN_FCN (icode
) (trap_rtx
, XEXP (trap_rtx
, 0), XEXP (trap_rtx
, 1),
5944 /* If that failed, then give up. */
5952 insn
= get_insns ();
5957 /* Return rtx code for TCODE or UNKNOWN. Use UNSIGNEDP to select signed
5958 or unsigned operation code. */
5961 get_rtx_code_1 (enum tree_code tcode
, bool unsignedp
)
5973 code
= unsignedp
? LTU
: LT
;
5976 code
= unsignedp
? LEU
: LE
;
5979 code
= unsignedp
? GTU
: GT
;
5982 code
= unsignedp
? GEU
: GE
;
5985 case UNORDERED_EXPR
:
6025 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6026 or unsigned operation code. */
6029 get_rtx_code (enum tree_code tcode
, bool unsignedp
)
6031 enum rtx_code code
= get_rtx_code_1 (tcode
, unsignedp
);
6032 gcc_assert (code
!= UNKNOWN
);
6036 /* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to
6037 select signed or unsigned operators. OPNO holds the index of the
6038 first comparison operand for insn ICODE. Do not generate the
6039 compare instruction itself. */
6042 vector_compare_rtx (machine_mode cmp_mode
, enum tree_code tcode
,
6043 tree t_op0
, tree t_op1
, bool unsignedp
,
6044 enum insn_code icode
, unsigned int opno
)
6046 class expand_operand ops
[2];
6047 rtx rtx_op0
, rtx_op1
;
6048 machine_mode m0
, m1
;
6049 enum rtx_code rcode
= get_rtx_code (tcode
, unsignedp
);
6051 gcc_assert (TREE_CODE_CLASS (tcode
) == tcc_comparison
);
6053 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
6054 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
6055 cases, use the original mode. */
6056 rtx_op0
= expand_expr (t_op0
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op0
)),
6058 m0
= GET_MODE (rtx_op0
);
6060 m0
= TYPE_MODE (TREE_TYPE (t_op0
));
6062 rtx_op1
= expand_expr (t_op1
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op1
)),
6064 m1
= GET_MODE (rtx_op1
);
6066 m1
= TYPE_MODE (TREE_TYPE (t_op1
));
6068 create_input_operand (&ops
[0], rtx_op0
, m0
);
6069 create_input_operand (&ops
[1], rtx_op1
, m1
);
6070 if (!maybe_legitimize_operands (icode
, opno
, 2, ops
))
6072 return gen_rtx_fmt_ee (rcode
, cmp_mode
, ops
[0].value
, ops
[1].value
);
6075 /* Check if vec_perm mask SEL is a constant equivalent to a shift of
6076 the first vec_perm operand, assuming the second operand (for left shift
6077 first operand) is a constant vector of zeros. Return the shift distance
6078 in bits if so, or NULL_RTX if the vec_perm is not a shift. MODE is the
6079 mode of the value being shifted. SHIFT_OPTAB is vec_shr_optab for right
6080 shift or vec_shl_optab for left shift. */
6082 shift_amt_for_vec_perm_mask (machine_mode mode
, const vec_perm_indices
&sel
,
6085 unsigned int bitsize
= GET_MODE_UNIT_BITSIZE (mode
);
6086 poly_int64 first
= sel
[0];
6087 if (maybe_ge (sel
[0], GET_MODE_NUNITS (mode
)))
6090 if (shift_optab
== vec_shl_optab
)
6093 if (!GET_MODE_NUNITS (mode
).is_constant (&nelt
))
6095 unsigned firstidx
= 0;
6096 for (unsigned int i
= 0; i
< nelt
; i
++)
6098 if (known_eq (sel
[i
], nelt
))
6100 if (i
== 0 || firstidx
)
6105 ? maybe_ne (sel
[i
], nelt
+ i
- firstidx
)
6106 : maybe_ge (sel
[i
], nelt
))
6114 else if (!sel
.series_p (0, 1, first
, 1))
6117 if (!GET_MODE_NUNITS (mode
).is_constant (&nelt
))
6119 for (unsigned int i
= 1; i
< nelt
; i
++)
6121 poly_int64 expected
= i
+ first
;
6122 /* Indices into the second vector are all equivalent. */
6123 if (maybe_lt (sel
[i
], nelt
)
6124 ? maybe_ne (sel
[i
], expected
)
6125 : maybe_lt (expected
, nelt
))
6130 return gen_int_shift_amount (mode
, first
* bitsize
);
6133 /* A subroutine of expand_vec_perm_var for expanding one vec_perm insn. */
6136 expand_vec_perm_1 (enum insn_code icode
, rtx target
,
6137 rtx v0
, rtx v1
, rtx sel
)
6139 machine_mode tmode
= GET_MODE (target
);
6140 machine_mode smode
= GET_MODE (sel
);
6141 class expand_operand ops
[4];
6143 gcc_assert (GET_MODE_CLASS (smode
) == MODE_VECTOR_INT
6144 || related_int_vector_mode (tmode
).require () == smode
);
6145 create_output_operand (&ops
[0], target
, tmode
);
6146 create_input_operand (&ops
[3], sel
, smode
);
6148 /* Make an effort to preserve v0 == v1. The target expander is able to
6149 rely on this to determine if we're permuting a single input operand. */
6150 if (rtx_equal_p (v0
, v1
))
6152 if (!insn_operand_matches (icode
, 1, v0
))
6153 v0
= force_reg (tmode
, v0
);
6154 gcc_checking_assert (insn_operand_matches (icode
, 1, v0
));
6155 gcc_checking_assert (insn_operand_matches (icode
, 2, v0
));
6157 create_fixed_operand (&ops
[1], v0
);
6158 create_fixed_operand (&ops
[2], v0
);
6162 create_input_operand (&ops
[1], v0
, tmode
);
6163 create_input_operand (&ops
[2], v1
, tmode
);
6166 if (maybe_expand_insn (icode
, 4, ops
))
6167 return ops
[0].value
;
6171 /* Implement a permutation of vectors v0 and v1 using the permutation
6172 vector in SEL and return the result. Use TARGET to hold the result
6173 if nonnull and convenient.
6175 MODE is the mode of the vectors being permuted (V0 and V1). SEL_MODE
6176 is the TYPE_MODE associated with SEL, or BLKmode if SEL isn't known
6177 to have a particular mode. */
6180 expand_vec_perm_const (machine_mode mode
, rtx v0
, rtx v1
,
6181 const vec_perm_builder
&sel
, machine_mode sel_mode
,
6184 if (!target
|| !register_operand (target
, mode
))
6185 target
= gen_reg_rtx (mode
);
6187 /* Set QIMODE to a different vector mode with byte elements.
6188 If no such mode, or if MODE already has byte elements, use VOIDmode. */
6189 machine_mode qimode
;
6190 if (!qimode_for_vec_perm (mode
).exists (&qimode
))
6193 rtx_insn
*last
= get_last_insn ();
6195 bool single_arg_p
= rtx_equal_p (v0
, v1
);
6196 /* Always specify two input vectors here and leave the target to handle
6197 cases in which the inputs are equal. Not all backends can cope with
6198 the single-input representation when testing for a double-input
6199 target instruction. */
6200 vec_perm_indices
indices (sel
, 2, GET_MODE_NUNITS (mode
));
6202 /* See if this can be handled with a vec_shr or vec_shl. We only do this
6203 if the second (for vec_shr) or first (for vec_shl) vector is all
6205 insn_code shift_code
= CODE_FOR_nothing
;
6206 insn_code shift_code_qi
= CODE_FOR_nothing
;
6207 optab shift_optab
= unknown_optab
;
6209 if (v1
== CONST0_RTX (GET_MODE (v1
)))
6210 shift_optab
= vec_shr_optab
;
6211 else if (v0
== CONST0_RTX (GET_MODE (v0
)))
6213 shift_optab
= vec_shl_optab
;
6216 if (shift_optab
!= unknown_optab
)
6218 shift_code
= optab_handler (shift_optab
, mode
);
6219 shift_code_qi
= ((qimode
!= VOIDmode
&& qimode
!= mode
)
6220 ? optab_handler (shift_optab
, qimode
)
6221 : CODE_FOR_nothing
);
6223 if (shift_code
!= CODE_FOR_nothing
|| shift_code_qi
!= CODE_FOR_nothing
)
6225 rtx shift_amt
= shift_amt_for_vec_perm_mask (mode
, indices
, shift_optab
);
6228 class expand_operand ops
[3];
6229 if (shift_amt
== const0_rtx
)
6231 if (shift_code
!= CODE_FOR_nothing
)
6233 create_output_operand (&ops
[0], target
, mode
);
6234 create_input_operand (&ops
[1], v2
, mode
);
6235 create_convert_operand_from_type (&ops
[2], shift_amt
, sizetype
);
6236 if (maybe_expand_insn (shift_code
, 3, ops
))
6237 return ops
[0].value
;
6239 if (shift_code_qi
!= CODE_FOR_nothing
)
6241 rtx tmp
= gen_reg_rtx (qimode
);
6242 create_output_operand (&ops
[0], tmp
, qimode
);
6243 create_input_operand (&ops
[1], gen_lowpart (qimode
, v2
), qimode
);
6244 create_convert_operand_from_type (&ops
[2], shift_amt
, sizetype
);
6245 if (maybe_expand_insn (shift_code_qi
, 3, ops
))
6246 return gen_lowpart (mode
, ops
[0].value
);
6251 if (targetm
.vectorize
.vec_perm_const
!= NULL
)
6256 gcc_checking_assert (GET_MODE (v0
) == GET_MODE (v1
));
6257 machine_mode op_mode
= GET_MODE (v0
);
6258 if (targetm
.vectorize
.vec_perm_const (mode
, op_mode
, target
, v0
, v1
,
6263 /* Fall back to a constant byte-based permutation. */
6264 vec_perm_indices qimode_indices
;
6265 rtx target_qi
= NULL_RTX
, v0_qi
= NULL_RTX
, v1_qi
= NULL_RTX
;
6266 if (qimode
!= VOIDmode
)
6268 qimode_indices
.new_expanded_vector (indices
, GET_MODE_UNIT_SIZE (mode
));
6269 target_qi
= gen_reg_rtx (qimode
);
6270 v0_qi
= gen_lowpart (qimode
, v0
);
6271 v1_qi
= gen_lowpart (qimode
, v1
);
6272 if (targetm
.vectorize
.vec_perm_const
!= NULL
6273 && targetm
.vectorize
.vec_perm_const (qimode
, qimode
, target_qi
, v0_qi
,
6274 v1_qi
, qimode_indices
))
6275 return gen_lowpart (mode
, target_qi
);
6278 v0
= force_reg (mode
, v0
);
6281 v1
= force_reg (mode
, v1
);
6283 /* Otherwise expand as a fully variable permuation. */
6285 /* The optabs are only defined for selectors with the same width
6286 as the values being permuted. */
6287 machine_mode required_sel_mode
;
6288 if (!related_int_vector_mode (mode
).exists (&required_sel_mode
))
6290 delete_insns_since (last
);
6294 /* We know that it is semantically valid to treat SEL as having SEL_MODE.
6295 If that isn't the mode we want then we need to prove that using
6296 REQUIRED_SEL_MODE is OK. */
6297 if (sel_mode
!= required_sel_mode
)
6299 if (!selector_fits_mode_p (required_sel_mode
, indices
))
6301 delete_insns_since (last
);
6304 sel_mode
= required_sel_mode
;
6307 insn_code icode
= direct_optab_handler (vec_perm_optab
, mode
);
6308 if (icode
!= CODE_FOR_nothing
)
6310 rtx sel_rtx
= vec_perm_indices_to_rtx (sel_mode
, indices
);
6311 rtx tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel_rtx
);
6316 if (qimode
!= VOIDmode
6317 && selector_fits_mode_p (qimode
, qimode_indices
))
6319 icode
= direct_optab_handler (vec_perm_optab
, qimode
);
6320 if (icode
!= CODE_FOR_nothing
)
6322 rtx sel_qi
= vec_perm_indices_to_rtx (qimode
, qimode_indices
);
6323 rtx tmp
= expand_vec_perm_1 (icode
, target_qi
, v0_qi
, v1_qi
, sel_qi
);
6325 return gen_lowpart (mode
, tmp
);
6329 delete_insns_since (last
);
6333 /* Implement a permutation of vectors v0 and v1 using the permutation
6334 vector in SEL and return the result. Use TARGET to hold the result
6335 if nonnull and convenient.
6337 MODE is the mode of the vectors being permuted (V0 and V1).
6338 SEL must have the integer equivalent of MODE and is known to be
6339 unsuitable for permutes with a constant permutation vector. */
6342 expand_vec_perm_var (machine_mode mode
, rtx v0
, rtx v1
, rtx sel
, rtx target
)
6344 enum insn_code icode
;
6348 u
= GET_MODE_UNIT_SIZE (mode
);
6350 if (!target
|| GET_MODE (target
) != mode
)
6351 target
= gen_reg_rtx (mode
);
6353 icode
= direct_optab_handler (vec_perm_optab
, mode
);
6354 if (icode
!= CODE_FOR_nothing
)
6356 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
6361 /* As a special case to aid several targets, lower the element-based
6362 permutation to a byte-based permutation and try again. */
6363 machine_mode qimode
;
6364 if (!qimode_for_vec_perm (mode
).exists (&qimode
)
6365 || maybe_gt (GET_MODE_NUNITS (qimode
), GET_MODE_MASK (QImode
) + 1))
6367 icode
= direct_optab_handler (vec_perm_optab
, qimode
);
6368 if (icode
== CODE_FOR_nothing
)
6371 /* Multiply each element by its byte size. */
6372 machine_mode selmode
= GET_MODE (sel
);
6374 sel
= expand_simple_binop (selmode
, PLUS
, sel
, sel
,
6375 NULL
, 0, OPTAB_DIRECT
);
6377 sel
= expand_simple_binop (selmode
, ASHIFT
, sel
,
6378 gen_int_shift_amount (selmode
, exact_log2 (u
)),
6379 NULL
, 0, OPTAB_DIRECT
);
6380 gcc_assert (sel
!= NULL
);
6382 /* Broadcast the low byte each element into each of its bytes.
6383 The encoding has U interleaved stepped patterns, one for each
6384 byte of an element. */
6385 vec_perm_builder
const_sel (GET_MODE_SIZE (mode
), u
, 3);
6386 unsigned int low_byte_in_u
= BYTES_BIG_ENDIAN
? u
- 1 : 0;
6387 for (i
= 0; i
< 3; ++i
)
6388 for (unsigned int j
= 0; j
< u
; ++j
)
6389 const_sel
.quick_push (i
* u
+ low_byte_in_u
);
6390 sel
= gen_lowpart (qimode
, sel
);
6391 sel
= expand_vec_perm_const (qimode
, sel
, sel
, const_sel
, qimode
, NULL
);
6392 gcc_assert (sel
!= NULL
);
6394 /* Add the byte offset to each byte element. */
6395 /* Note that the definition of the indicies here is memory ordering,
6396 so there should be no difference between big and little endian. */
6397 rtx_vector_builder
byte_indices (qimode
, u
, 1);
6398 for (i
= 0; i
< u
; ++i
)
6399 byte_indices
.quick_push (GEN_INT (i
));
6400 tmp
= byte_indices
.build ();
6401 sel_qi
= expand_simple_binop (qimode
, PLUS
, sel
, tmp
,
6402 sel
, 0, OPTAB_DIRECT
);
6403 gcc_assert (sel_qi
!= NULL
);
6405 tmp
= mode
!= qimode
? gen_reg_rtx (qimode
) : target
;
6406 tmp
= expand_vec_perm_1 (icode
, tmp
, gen_lowpart (qimode
, v0
),
6407 gen_lowpart (qimode
, v1
), sel_qi
);
6409 tmp
= gen_lowpart (mode
, tmp
);
6413 /* Generate VEC_SERIES_EXPR <OP0, OP1>, returning a value of mode VMODE.
6414 Use TARGET for the result if nonnull and convenient. */
6417 expand_vec_series_expr (machine_mode vmode
, rtx op0
, rtx op1
, rtx target
)
6419 class expand_operand ops
[3];
6420 enum insn_code icode
;
6421 machine_mode emode
= GET_MODE_INNER (vmode
);
6423 icode
= direct_optab_handler (vec_series_optab
, vmode
);
6424 gcc_assert (icode
!= CODE_FOR_nothing
);
6426 create_output_operand (&ops
[0], target
, vmode
);
6427 create_input_operand (&ops
[1], op0
, emode
);
6428 create_input_operand (&ops
[2], op1
, emode
);
6430 expand_insn (icode
, 3, ops
);
6431 return ops
[0].value
;
6434 /* Generate insns for a vector comparison into a mask. */
6437 expand_vec_cmp_expr (tree type
, tree exp
, rtx target
)
6439 class expand_operand ops
[4];
6440 enum insn_code icode
;
6442 machine_mode mask_mode
= TYPE_MODE (type
);
6446 enum tree_code tcode
;
6448 op0a
= TREE_OPERAND (exp
, 0);
6449 op0b
= TREE_OPERAND (exp
, 1);
6450 tcode
= TREE_CODE (exp
);
6452 unsignedp
= TYPE_UNSIGNED (TREE_TYPE (op0a
));
6453 vmode
= TYPE_MODE (TREE_TYPE (op0a
));
6455 icode
= get_vec_cmp_icode (vmode
, mask_mode
, unsignedp
);
6456 if (icode
== CODE_FOR_nothing
)
6458 if (tcode
== EQ_EXPR
|| tcode
== NE_EXPR
)
6459 icode
= get_vec_cmp_eq_icode (vmode
, mask_mode
);
6460 if (icode
== CODE_FOR_nothing
)
6464 comparison
= vector_compare_rtx (mask_mode
, tcode
, op0a
, op0b
,
6465 unsignedp
, icode
, 2);
6466 create_output_operand (&ops
[0], target
, mask_mode
);
6467 create_fixed_operand (&ops
[1], comparison
);
6468 create_fixed_operand (&ops
[2], XEXP (comparison
, 0));
6469 create_fixed_operand (&ops
[3], XEXP (comparison
, 1));
6470 expand_insn (icode
, 4, ops
);
6471 return ops
[0].value
;
6474 /* Expand a highpart multiply. */
6477 expand_mult_highpart (machine_mode mode
, rtx op0
, rtx op1
,
6478 rtx target
, bool uns_p
)
6480 class expand_operand eops
[3];
6481 enum insn_code icode
;
6487 method
= can_mult_highpart_p (mode
, uns_p
);
6493 tab1
= uns_p
? umul_highpart_optab
: smul_highpart_optab
;
6494 return expand_binop (mode
, tab1
, op0
, op1
, target
, uns_p
,
6497 tab1
= uns_p
? vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
6498 tab2
= uns_p
? vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
6501 tab1
= uns_p
? vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
6502 tab2
= uns_p
? vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
6503 if (BYTES_BIG_ENDIAN
)
6504 std::swap (tab1
, tab2
);
6510 icode
= optab_handler (tab1
, mode
);
6511 wmode
= insn_data
[icode
].operand
[0].mode
;
6512 gcc_checking_assert (known_eq (2 * GET_MODE_NUNITS (wmode
),
6513 GET_MODE_NUNITS (mode
)));
6514 gcc_checking_assert (known_eq (GET_MODE_SIZE (wmode
), GET_MODE_SIZE (mode
)));
6516 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
6517 create_input_operand (&eops
[1], op0
, mode
);
6518 create_input_operand (&eops
[2], op1
, mode
);
6519 expand_insn (icode
, 3, eops
);
6520 m1
= gen_lowpart (mode
, eops
[0].value
);
6522 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
6523 create_input_operand (&eops
[1], op0
, mode
);
6524 create_input_operand (&eops
[2], op1
, mode
);
6525 expand_insn (optab_handler (tab2
, mode
), 3, eops
);
6526 m2
= gen_lowpart (mode
, eops
[0].value
);
6528 vec_perm_builder sel
;
6531 /* The encoding has 2 interleaved stepped patterns. */
6532 sel
.new_vector (GET_MODE_NUNITS (mode
), 2, 3);
6533 for (i
= 0; i
< 6; ++i
)
6534 sel
.quick_push (!BYTES_BIG_ENDIAN
+ (i
& ~1)
6535 + ((i
& 1) ? GET_MODE_NUNITS (mode
) : 0));
6539 /* The encoding has a single interleaved stepped pattern. */
6540 sel
.new_vector (GET_MODE_NUNITS (mode
), 1, 3);
6541 for (i
= 0; i
< 3; ++i
)
6542 sel
.quick_push (2 * i
+ (BYTES_BIG_ENDIAN
? 0 : 1));
6545 return expand_vec_perm_const (mode
, m1
, m2
, sel
, BLKmode
, target
);
6548 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
6552 find_cc_set (rtx x
, const_rtx pat
, void *data
)
6554 if (REG_P (x
) && GET_MODE_CLASS (GET_MODE (x
)) == MODE_CC
6555 && GET_CODE (pat
) == SET
)
6557 rtx
*p_cc_reg
= (rtx
*) data
;
6558 gcc_assert (!*p_cc_reg
);
6563 /* This is a helper function for the other atomic operations. This function
6564 emits a loop that contains SEQ that iterates until a compare-and-swap
6565 operation at the end succeeds. MEM is the memory to be modified. SEQ is
6566 a set of instructions that takes a value from OLD_REG as an input and
6567 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
6568 set to the current contents of MEM. After SEQ, a compare-and-swap will
6569 attempt to update MEM with NEW_REG. The function returns true when the
6570 loop was generated successfully. */
6573 expand_compare_and_swap_loop (rtx mem
, rtx old_reg
, rtx new_reg
, rtx seq
)
6575 machine_mode mode
= GET_MODE (mem
);
6576 rtx_code_label
*label
;
6577 rtx cmp_reg
, success
, oldval
;
6579 /* The loop we want to generate looks like
6585 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
6589 Note that we only do the plain load from memory once. Subsequent
6590 iterations use the value loaded by the compare-and-swap pattern. */
6592 label
= gen_label_rtx ();
6593 cmp_reg
= gen_reg_rtx (mode
);
6595 emit_move_insn (cmp_reg
, mem
);
6597 emit_move_insn (old_reg
, cmp_reg
);
6603 if (!expand_atomic_compare_and_swap (&success
, &oldval
, mem
, old_reg
,
6604 new_reg
, false, MEMMODEL_SYNC_SEQ_CST
,
6608 if (oldval
!= cmp_reg
)
6609 emit_move_insn (cmp_reg
, oldval
);
6611 /* Mark this jump predicted not taken. */
6612 emit_cmp_and_jump_insns (success
, const0_rtx
, EQ
, const0_rtx
,
6613 GET_MODE (success
), 1, label
,
6614 profile_probability::guessed_never ());
6619 /* This function tries to emit an atomic_exchange intruction. VAL is written
6620 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
6621 using TARGET if possible. */
6624 maybe_emit_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
6626 machine_mode mode
= GET_MODE (mem
);
6627 enum insn_code icode
;
6629 /* If the target supports the exchange directly, great. */
6630 icode
= direct_optab_handler (atomic_exchange_optab
, mode
);
6631 if (icode
!= CODE_FOR_nothing
)
6633 class expand_operand ops
[4];
6635 create_output_operand (&ops
[0], target
, mode
);
6636 create_fixed_operand (&ops
[1], mem
);
6637 create_input_operand (&ops
[2], val
, mode
);
6638 create_integer_operand (&ops
[3], model
);
6639 if (maybe_expand_insn (icode
, 4, ops
))
6640 return ops
[0].value
;
6646 /* This function tries to implement an atomic exchange operation using
6647 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
6648 The previous contents of *MEM are returned, using TARGET if possible.
6649 Since this instructionn is an acquire barrier only, stronger memory
6650 models may require additional barriers to be emitted. */
6653 maybe_emit_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
,
6654 enum memmodel model
)
6656 machine_mode mode
= GET_MODE (mem
);
6657 enum insn_code icode
;
6658 rtx_insn
*last_insn
= get_last_insn ();
6660 icode
= optab_handler (sync_lock_test_and_set_optab
, mode
);
6662 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
6663 exists, and the memory model is stronger than acquire, add a release
6664 barrier before the instruction. */
6666 if (is_mm_seq_cst (model
) || is_mm_release (model
) || is_mm_acq_rel (model
))
6667 expand_mem_thread_fence (model
);
6669 if (icode
!= CODE_FOR_nothing
)
6671 class expand_operand ops
[3];
6672 create_output_operand (&ops
[0], target
, mode
);
6673 create_fixed_operand (&ops
[1], mem
);
6674 create_input_operand (&ops
[2], val
, mode
);
6675 if (maybe_expand_insn (icode
, 3, ops
))
6676 return ops
[0].value
;
6679 /* If an external test-and-set libcall is provided, use that instead of
6680 any external compare-and-swap that we might get from the compare-and-
6681 swap-loop expansion later. */
6682 if (!can_compare_and_swap_p (mode
, false))
6684 rtx libfunc
= optab_libfunc (sync_lock_test_and_set_optab
, mode
);
6685 if (libfunc
!= NULL
)
6689 addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
6690 return emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
6691 mode
, addr
, ptr_mode
,
6696 /* If the test_and_set can't be emitted, eliminate any barrier that might
6697 have been emitted. */
6698 delete_insns_since (last_insn
);
6702 /* This function tries to implement an atomic exchange operation using a
6703 compare_and_swap loop. VAL is written to *MEM. The previous contents of
6704 *MEM are returned, using TARGET if possible. No memory model is required
6705 since a compare_and_swap loop is seq-cst. */
6708 maybe_emit_compare_and_swap_exchange_loop (rtx target
, rtx mem
, rtx val
)
6710 machine_mode mode
= GET_MODE (mem
);
6712 if (can_compare_and_swap_p (mode
, true))
6714 if (!target
|| !register_operand (target
, mode
))
6715 target
= gen_reg_rtx (mode
);
6716 if (expand_compare_and_swap_loop (mem
, target
, val
, NULL_RTX
))
6723 /* This function tries to implement an atomic test-and-set operation
6724 using the atomic_test_and_set instruction pattern. A boolean value
6725 is returned from the operation, using TARGET if possible. */
6728 maybe_emit_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
6730 machine_mode pat_bool_mode
;
6731 class expand_operand ops
[3];
6733 if (!targetm
.have_atomic_test_and_set ())
6736 /* While we always get QImode from __atomic_test_and_set, we get
6737 other memory modes from __sync_lock_test_and_set. Note that we
6738 use no endian adjustment here. This matches the 4.6 behavior
6739 in the Sparc backend. */
6740 enum insn_code icode
= targetm
.code_for_atomic_test_and_set
;
6741 gcc_checking_assert (insn_data
[icode
].operand
[1].mode
== QImode
);
6742 if (GET_MODE (mem
) != QImode
)
6743 mem
= adjust_address_nv (mem
, QImode
, 0);
6745 pat_bool_mode
= insn_data
[icode
].operand
[0].mode
;
6746 create_output_operand (&ops
[0], target
, pat_bool_mode
);
6747 create_fixed_operand (&ops
[1], mem
);
6748 create_integer_operand (&ops
[2], model
);
6750 if (maybe_expand_insn (icode
, 3, ops
))
6751 return ops
[0].value
;
6755 /* This function expands the legacy _sync_lock test_and_set operation which is
6756 generally an atomic exchange. Some limited targets only allow the
6757 constant 1 to be stored. This is an ACQUIRE operation.
6759 TARGET is an optional place to stick the return value.
6760 MEM is where VAL is stored. */
6763 expand_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
)
6767 /* Try an atomic_exchange first. */
6768 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, MEMMODEL_SYNC_ACQUIRE
);
6772 ret
= maybe_emit_sync_lock_test_and_set (target
, mem
, val
,
6773 MEMMODEL_SYNC_ACQUIRE
);
6777 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
6781 /* If there are no other options, try atomic_test_and_set if the value
6782 being stored is 1. */
6783 if (val
== const1_rtx
)
6784 ret
= maybe_emit_atomic_test_and_set (target
, mem
, MEMMODEL_SYNC_ACQUIRE
);
6789 /* This function expands the atomic test_and_set operation:
6790 atomically store a boolean TRUE into MEM and return the previous value.
6792 MEMMODEL is the memory model variant to use.
6793 TARGET is an optional place to stick the return value. */
6796 expand_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
6798 machine_mode mode
= GET_MODE (mem
);
6799 rtx ret
, trueval
, subtarget
;
6801 ret
= maybe_emit_atomic_test_and_set (target
, mem
, model
);
6805 /* Be binary compatible with non-default settings of trueval, and different
6806 cpu revisions. E.g. one revision may have atomic-test-and-set, but
6807 another only has atomic-exchange. */
6808 if (targetm
.atomic_test_and_set_trueval
== 1)
6810 trueval
= const1_rtx
;
6811 subtarget
= target
? target
: gen_reg_rtx (mode
);
6815 trueval
= gen_int_mode (targetm
.atomic_test_and_set_trueval
, mode
);
6816 subtarget
= gen_reg_rtx (mode
);
6819 /* Try the atomic-exchange optab... */
6820 ret
= maybe_emit_atomic_exchange (subtarget
, mem
, trueval
, model
);
6822 /* ... then an atomic-compare-and-swap loop ... */
6824 ret
= maybe_emit_compare_and_swap_exchange_loop (subtarget
, mem
, trueval
);
6826 /* ... before trying the vaguely defined legacy lock_test_and_set. */
6828 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, trueval
, model
);
6830 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
6831 things with the value 1. Thus we try again without trueval. */
6832 if (!ret
&& targetm
.atomic_test_and_set_trueval
!= 1)
6833 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, const1_rtx
, model
);
6835 /* Failing all else, assume a single threaded environment and simply
6836 perform the operation. */
6839 /* If the result is ignored skip the move to target. */
6840 if (subtarget
!= const0_rtx
)
6841 emit_move_insn (subtarget
, mem
);
6843 emit_move_insn (mem
, trueval
);
6847 /* Recall that have to return a boolean value; rectify if trueval
6848 is not exactly one. */
6849 if (targetm
.atomic_test_and_set_trueval
!= 1)
6850 ret
= emit_store_flag_force (target
, NE
, ret
, const0_rtx
, mode
, 0, 1);
6855 /* This function expands the atomic exchange operation:
6856 atomically store VAL in MEM and return the previous value in MEM.
6858 MEMMODEL is the memory model variant to use.
6859 TARGET is an optional place to stick the return value. */
6862 expand_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
6864 machine_mode mode
= GET_MODE (mem
);
6867 /* If loads are not atomic for the required size and we are not called to
6868 provide a __sync builtin, do not do anything so that we stay consistent
6869 with atomic loads of the same size. */
6870 if (!can_atomic_load_p (mode
) && !is_mm_sync (model
))
6873 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, model
);
6875 /* Next try a compare-and-swap loop for the exchange. */
6877 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
6882 /* This function expands the atomic compare exchange operation:
6884 *PTARGET_BOOL is an optional place to store the boolean success/failure.
6885 *PTARGET_OVAL is an optional place to store the old value from memory.
6886 Both target parameters may be NULL or const0_rtx to indicate that we do
6887 not care about that return value. Both target parameters are updated on
6888 success to the actual location of the corresponding result.
6890 MEMMODEL is the memory model variant to use.
6892 The return value of the function is true for success. */
6895 expand_atomic_compare_and_swap (rtx
*ptarget_bool
, rtx
*ptarget_oval
,
6896 rtx mem
, rtx expected
, rtx desired
,
6897 bool is_weak
, enum memmodel succ_model
,
6898 enum memmodel fail_model
)
6900 machine_mode mode
= GET_MODE (mem
);
6901 class expand_operand ops
[8];
6902 enum insn_code icode
;
6903 rtx target_oval
, target_bool
= NULL_RTX
;
6906 /* If loads are not atomic for the required size and we are not called to
6907 provide a __sync builtin, do not do anything so that we stay consistent
6908 with atomic loads of the same size. */
6909 if (!can_atomic_load_p (mode
) && !is_mm_sync (succ_model
))
6912 /* Load expected into a register for the compare and swap. */
6913 if (MEM_P (expected
))
6914 expected
= copy_to_reg (expected
);
6916 /* Make sure we always have some place to put the return oldval.
6917 Further, make sure that place is distinct from the input expected,
6918 just in case we need that path down below. */
6919 if (ptarget_oval
&& *ptarget_oval
== const0_rtx
)
6920 ptarget_oval
= NULL
;
6922 if (ptarget_oval
== NULL
6923 || (target_oval
= *ptarget_oval
) == NULL
6924 || reg_overlap_mentioned_p (expected
, target_oval
))
6925 target_oval
= gen_reg_rtx (mode
);
6927 icode
= direct_optab_handler (atomic_compare_and_swap_optab
, mode
);
6928 if (icode
!= CODE_FOR_nothing
)
6930 machine_mode bool_mode
= insn_data
[icode
].operand
[0].mode
;
6932 if (ptarget_bool
&& *ptarget_bool
== const0_rtx
)
6933 ptarget_bool
= NULL
;
6935 /* Make sure we always have a place for the bool operand. */
6936 if (ptarget_bool
== NULL
6937 || (target_bool
= *ptarget_bool
) == NULL
6938 || GET_MODE (target_bool
) != bool_mode
)
6939 target_bool
= gen_reg_rtx (bool_mode
);
6941 /* Emit the compare_and_swap. */
6942 create_output_operand (&ops
[0], target_bool
, bool_mode
);
6943 create_output_operand (&ops
[1], target_oval
, mode
);
6944 create_fixed_operand (&ops
[2], mem
);
6945 create_input_operand (&ops
[3], expected
, mode
);
6946 create_input_operand (&ops
[4], desired
, mode
);
6947 create_integer_operand (&ops
[5], is_weak
);
6948 create_integer_operand (&ops
[6], succ_model
);
6949 create_integer_operand (&ops
[7], fail_model
);
6950 if (maybe_expand_insn (icode
, 8, ops
))
6952 /* Return success/failure. */
6953 target_bool
= ops
[0].value
;
6954 target_oval
= ops
[1].value
;
6959 /* Otherwise fall back to the original __sync_val_compare_and_swap
6960 which is always seq-cst. */
6961 icode
= optab_handler (sync_compare_and_swap_optab
, mode
);
6962 if (icode
!= CODE_FOR_nothing
)
6966 create_output_operand (&ops
[0], target_oval
, mode
);
6967 create_fixed_operand (&ops
[1], mem
);
6968 create_input_operand (&ops
[2], expected
, mode
);
6969 create_input_operand (&ops
[3], desired
, mode
);
6970 if (!maybe_expand_insn (icode
, 4, ops
))
6973 target_oval
= ops
[0].value
;
6975 /* If the caller isn't interested in the boolean return value,
6976 skip the computation of it. */
6977 if (ptarget_bool
== NULL
)
6980 /* Otherwise, work out if the compare-and-swap succeeded. */
6982 if (have_insn_for (COMPARE
, CCmode
))
6983 note_stores (get_last_insn (), find_cc_set
, &cc_reg
);
6986 target_bool
= emit_store_flag_force (target_bool
, EQ
, cc_reg
,
6987 const0_rtx
, VOIDmode
, 0, 1);
6990 goto success_bool_from_val
;
6993 /* Also check for library support for __sync_val_compare_and_swap. */
6994 libfunc
= optab_libfunc (sync_compare_and_swap_optab
, mode
);
6995 if (libfunc
!= NULL
)
6997 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
6998 rtx target
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
6999 mode
, addr
, ptr_mode
,
7000 expected
, mode
, desired
, mode
);
7001 emit_move_insn (target_oval
, target
);
7003 /* Compute the boolean return value only if requested. */
7005 goto success_bool_from_val
;
7013 success_bool_from_val
:
7014 target_bool
= emit_store_flag_force (target_bool
, EQ
, target_oval
,
7015 expected
, VOIDmode
, 1, 1);
7017 /* Make sure that the oval output winds up where the caller asked. */
7019 *ptarget_oval
= target_oval
;
7021 *ptarget_bool
= target_bool
;
7025 /* Generate asm volatile("" : : : "memory") as the memory blockage. */
7028 expand_asm_memory_blockage (void)
7032 asm_op
= gen_rtx_ASM_OPERANDS (VOIDmode
, "", "", 0,
7033 rtvec_alloc (0), rtvec_alloc (0),
7034 rtvec_alloc (0), UNKNOWN_LOCATION
);
7035 MEM_VOLATILE_P (asm_op
) = 1;
7037 clob
= gen_rtx_SCRATCH (VOIDmode
);
7038 clob
= gen_rtx_MEM (BLKmode
, clob
);
7039 clob
= gen_rtx_CLOBBER (VOIDmode
, clob
);
7041 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, asm_op
, clob
)));
7044 /* Do not propagate memory accesses across this point. */
7047 expand_memory_blockage (void)
7049 if (targetm
.have_memory_blockage ())
7050 emit_insn (targetm
.gen_memory_blockage ());
7052 expand_asm_memory_blockage ();
7055 /* Generate asm volatile("" : : : "memory") as a memory blockage, at the
7056 same time clobbering the register set specified by REGS. */
7059 expand_asm_reg_clobber_mem_blockage (HARD_REG_SET regs
)
7061 rtx asm_op
, clob_mem
;
7063 unsigned int num_of_regs
= 0;
7064 for (unsigned int i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
7065 if (TEST_HARD_REG_BIT (regs
, i
))
7068 asm_op
= gen_rtx_ASM_OPERANDS (VOIDmode
, "", "", 0,
7069 rtvec_alloc (0), rtvec_alloc (0),
7070 rtvec_alloc (0), UNKNOWN_LOCATION
);
7071 MEM_VOLATILE_P (asm_op
) = 1;
7073 rtvec v
= rtvec_alloc (num_of_regs
+ 2);
7075 clob_mem
= gen_rtx_SCRATCH (VOIDmode
);
7076 clob_mem
= gen_rtx_MEM (BLKmode
, clob_mem
);
7077 clob_mem
= gen_rtx_CLOBBER (VOIDmode
, clob_mem
);
7079 RTVEC_ELT (v
, 0) = asm_op
;
7080 RTVEC_ELT (v
, 1) = clob_mem
;
7082 if (num_of_regs
> 0)
7085 for (unsigned int i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
7086 if (TEST_HARD_REG_BIT (regs
, i
))
7088 RTVEC_ELT (v
, j
) = gen_rtx_CLOBBER (VOIDmode
, regno_reg_rtx
[i
]);
7091 gcc_assert (j
== (num_of_regs
+ 2));
7094 emit_insn (gen_rtx_PARALLEL (VOIDmode
, v
));
7097 /* This routine will either emit the mem_thread_fence pattern or issue a
7098 sync_synchronize to generate a fence for memory model MEMMODEL. */
7101 expand_mem_thread_fence (enum memmodel model
)
7103 if (is_mm_relaxed (model
))
7105 if (targetm
.have_mem_thread_fence ())
7107 emit_insn (targetm
.gen_mem_thread_fence (GEN_INT (model
)));
7108 expand_memory_blockage ();
7110 else if (targetm
.have_memory_barrier ())
7111 emit_insn (targetm
.gen_memory_barrier ());
7112 else if (synchronize_libfunc
!= NULL_RTX
)
7113 emit_library_call (synchronize_libfunc
, LCT_NORMAL
, VOIDmode
);
7115 expand_memory_blockage ();
7118 /* Emit a signal fence with given memory model. */
7121 expand_mem_signal_fence (enum memmodel model
)
7123 /* No machine barrier is required to implement a signal fence, but
7124 a compiler memory barrier must be issued, except for relaxed MM. */
7125 if (!is_mm_relaxed (model
))
7126 expand_memory_blockage ();
7129 /* This function expands the atomic load operation:
7130 return the atomically loaded value in MEM.
7132 MEMMODEL is the memory model variant to use.
7133 TARGET is an option place to stick the return value. */
7136 expand_atomic_load (rtx target
, rtx mem
, enum memmodel model
)
7138 machine_mode mode
= GET_MODE (mem
);
7139 enum insn_code icode
;
7141 /* If the target supports the load directly, great. */
7142 icode
= direct_optab_handler (atomic_load_optab
, mode
);
7143 if (icode
!= CODE_FOR_nothing
)
7145 class expand_operand ops
[3];
7146 rtx_insn
*last
= get_last_insn ();
7147 if (is_mm_seq_cst (model
))
7148 expand_memory_blockage ();
7150 create_output_operand (&ops
[0], target
, mode
);
7151 create_fixed_operand (&ops
[1], mem
);
7152 create_integer_operand (&ops
[2], model
);
7153 if (maybe_expand_insn (icode
, 3, ops
))
7155 if (!is_mm_relaxed (model
))
7156 expand_memory_blockage ();
7157 return ops
[0].value
;
7159 delete_insns_since (last
);
7162 /* If the size of the object is greater than word size on this target,
7163 then we assume that a load will not be atomic. We could try to
7164 emulate a load with a compare-and-swap operation, but the store that
7165 doing this could result in would be incorrect if this is a volatile
7166 atomic load or targetting read-only-mapped memory. */
7167 if (maybe_gt (GET_MODE_PRECISION (mode
), BITS_PER_WORD
))
7168 /* If there is no atomic load, leave the library call. */
7171 /* Otherwise assume loads are atomic, and emit the proper barriers. */
7172 if (!target
|| target
== const0_rtx
)
7173 target
= gen_reg_rtx (mode
);
7175 /* For SEQ_CST, emit a barrier before the load. */
7176 if (is_mm_seq_cst (model
))
7177 expand_mem_thread_fence (model
);
7179 emit_move_insn (target
, mem
);
7181 /* Emit the appropriate barrier after the load. */
7182 expand_mem_thread_fence (model
);
7187 /* This function expands the atomic store operation:
7188 Atomically store VAL in MEM.
7189 MEMMODEL is the memory model variant to use.
7190 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
7191 function returns const0_rtx if a pattern was emitted. */
7194 expand_atomic_store (rtx mem
, rtx val
, enum memmodel model
, bool use_release
)
7196 machine_mode mode
= GET_MODE (mem
);
7197 enum insn_code icode
;
7198 class expand_operand ops
[3];
7200 /* If the target supports the store directly, great. */
7201 icode
= direct_optab_handler (atomic_store_optab
, mode
);
7202 if (icode
!= CODE_FOR_nothing
)
7204 rtx_insn
*last
= get_last_insn ();
7205 if (!is_mm_relaxed (model
))
7206 expand_memory_blockage ();
7207 create_fixed_operand (&ops
[0], mem
);
7208 create_input_operand (&ops
[1], val
, mode
);
7209 create_integer_operand (&ops
[2], model
);
7210 if (maybe_expand_insn (icode
, 3, ops
))
7212 if (is_mm_seq_cst (model
))
7213 expand_memory_blockage ();
7216 delete_insns_since (last
);
7219 /* If using __sync_lock_release is a viable alternative, try it.
7220 Note that this will not be set to true if we are expanding a generic
7221 __atomic_store_n. */
7224 icode
= direct_optab_handler (sync_lock_release_optab
, mode
);
7225 if (icode
!= CODE_FOR_nothing
)
7227 create_fixed_operand (&ops
[0], mem
);
7228 create_input_operand (&ops
[1], const0_rtx
, mode
);
7229 if (maybe_expand_insn (icode
, 2, ops
))
7231 /* lock_release is only a release barrier. */
7232 if (is_mm_seq_cst (model
))
7233 expand_mem_thread_fence (model
);
7239 /* If the size of the object is greater than word size on this target,
7240 a default store will not be atomic. */
7241 if (maybe_gt (GET_MODE_PRECISION (mode
), BITS_PER_WORD
))
7243 /* If loads are atomic or we are called to provide a __sync builtin,
7244 we can try a atomic_exchange and throw away the result. Otherwise,
7245 don't do anything so that we do not create an inconsistency between
7246 loads and stores. */
7247 if (can_atomic_load_p (mode
) || is_mm_sync (model
))
7249 rtx target
= maybe_emit_atomic_exchange (NULL_RTX
, mem
, val
, model
);
7251 target
= maybe_emit_compare_and_swap_exchange_loop (NULL_RTX
, mem
,
7259 /* Otherwise assume stores are atomic, and emit the proper barriers. */
7260 expand_mem_thread_fence (model
);
7262 emit_move_insn (mem
, val
);
7264 /* For SEQ_CST, also emit a barrier after the store. */
7265 if (is_mm_seq_cst (model
))
7266 expand_mem_thread_fence (model
);
7272 /* Structure containing the pointers and values required to process the
7273 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
7275 struct atomic_op_functions
7277 direct_optab mem_fetch_before
;
7278 direct_optab mem_fetch_after
;
7279 direct_optab mem_no_result
;
7282 direct_optab no_result
;
7283 enum rtx_code reverse_code
;
7287 /* Fill in structure pointed to by OP with the various optab entries for an
7288 operation of type CODE. */
7291 get_atomic_op_for_code (struct atomic_op_functions
*op
, enum rtx_code code
)
7293 gcc_assert (op
!= NULL
);
7295 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
7296 in the source code during compilation, and the optab entries are not
7297 computable until runtime. Fill in the values at runtime. */
7301 op
->mem_fetch_before
= atomic_fetch_add_optab
;
7302 op
->mem_fetch_after
= atomic_add_fetch_optab
;
7303 op
->mem_no_result
= atomic_add_optab
;
7304 op
->fetch_before
= sync_old_add_optab
;
7305 op
->fetch_after
= sync_new_add_optab
;
7306 op
->no_result
= sync_add_optab
;
7307 op
->reverse_code
= MINUS
;
7310 op
->mem_fetch_before
= atomic_fetch_sub_optab
;
7311 op
->mem_fetch_after
= atomic_sub_fetch_optab
;
7312 op
->mem_no_result
= atomic_sub_optab
;
7313 op
->fetch_before
= sync_old_sub_optab
;
7314 op
->fetch_after
= sync_new_sub_optab
;
7315 op
->no_result
= sync_sub_optab
;
7316 op
->reverse_code
= PLUS
;
7319 op
->mem_fetch_before
= atomic_fetch_xor_optab
;
7320 op
->mem_fetch_after
= atomic_xor_fetch_optab
;
7321 op
->mem_no_result
= atomic_xor_optab
;
7322 op
->fetch_before
= sync_old_xor_optab
;
7323 op
->fetch_after
= sync_new_xor_optab
;
7324 op
->no_result
= sync_xor_optab
;
7325 op
->reverse_code
= XOR
;
7328 op
->mem_fetch_before
= atomic_fetch_and_optab
;
7329 op
->mem_fetch_after
= atomic_and_fetch_optab
;
7330 op
->mem_no_result
= atomic_and_optab
;
7331 op
->fetch_before
= sync_old_and_optab
;
7332 op
->fetch_after
= sync_new_and_optab
;
7333 op
->no_result
= sync_and_optab
;
7334 op
->reverse_code
= UNKNOWN
;
7337 op
->mem_fetch_before
= atomic_fetch_or_optab
;
7338 op
->mem_fetch_after
= atomic_or_fetch_optab
;
7339 op
->mem_no_result
= atomic_or_optab
;
7340 op
->fetch_before
= sync_old_ior_optab
;
7341 op
->fetch_after
= sync_new_ior_optab
;
7342 op
->no_result
= sync_ior_optab
;
7343 op
->reverse_code
= UNKNOWN
;
7346 op
->mem_fetch_before
= atomic_fetch_nand_optab
;
7347 op
->mem_fetch_after
= atomic_nand_fetch_optab
;
7348 op
->mem_no_result
= atomic_nand_optab
;
7349 op
->fetch_before
= sync_old_nand_optab
;
7350 op
->fetch_after
= sync_new_nand_optab
;
7351 op
->no_result
= sync_nand_optab
;
7352 op
->reverse_code
= UNKNOWN
;
7359 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
7360 using memory order MODEL. If AFTER is true the operation needs to return
7361 the value of *MEM after the operation, otherwise the previous value.
7362 TARGET is an optional place to place the result. The result is unused if
7364 Return the result if there is a better sequence, otherwise NULL_RTX. */
7367 maybe_optimize_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
7368 enum memmodel model
, bool after
)
7370 /* If the value is prefetched, or not used, it may be possible to replace
7371 the sequence with a native exchange operation. */
7372 if (!after
|| target
== const0_rtx
)
7374 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
7375 if (code
== AND
&& val
== const0_rtx
)
7377 if (target
== const0_rtx
)
7378 target
= gen_reg_rtx (GET_MODE (mem
));
7379 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
7382 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
7383 if (code
== IOR
&& val
== constm1_rtx
)
7385 if (target
== const0_rtx
)
7386 target
= gen_reg_rtx (GET_MODE (mem
));
7387 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
7394 /* Try to emit an instruction for a specific operation varaition.
7395 OPTAB contains the OP functions.
7396 TARGET is an optional place to return the result. const0_rtx means unused.
7397 MEM is the memory location to operate on.
7398 VAL is the value to use in the operation.
7399 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
7400 MODEL is the memory model, if used.
7401 AFTER is true if the returned result is the value after the operation. */
7404 maybe_emit_op (const struct atomic_op_functions
*optab
, rtx target
, rtx mem
,
7405 rtx val
, bool use_memmodel
, enum memmodel model
, bool after
)
7407 machine_mode mode
= GET_MODE (mem
);
7408 class expand_operand ops
[4];
7409 enum insn_code icode
;
7413 /* Check to see if there is a result returned. */
7414 if (target
== const0_rtx
)
7418 icode
= direct_optab_handler (optab
->mem_no_result
, mode
);
7419 create_integer_operand (&ops
[2], model
);
7424 icode
= direct_optab_handler (optab
->no_result
, mode
);
7428 /* Otherwise, we need to generate a result. */
7433 icode
= direct_optab_handler (after
? optab
->mem_fetch_after
7434 : optab
->mem_fetch_before
, mode
);
7435 create_integer_operand (&ops
[3], model
);
7440 icode
= optab_handler (after
? optab
->fetch_after
7441 : optab
->fetch_before
, mode
);
7444 create_output_operand (&ops
[op_counter
++], target
, mode
);
7446 if (icode
== CODE_FOR_nothing
)
7449 create_fixed_operand (&ops
[op_counter
++], mem
);
7450 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7451 create_convert_operand_to (&ops
[op_counter
++], val
, mode
, true);
7453 if (maybe_expand_insn (icode
, num_ops
, ops
))
7454 return (target
== const0_rtx
? const0_rtx
: ops
[0].value
);
7460 /* This function expands an atomic fetch_OP or OP_fetch operation:
7461 TARGET is an option place to stick the return value. const0_rtx indicates
7462 the result is unused.
7463 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7464 CODE is the operation being performed (OP)
7465 MEMMODEL is the memory model variant to use.
7466 AFTER is true to return the result of the operation (OP_fetch).
7467 AFTER is false to return the value before the operation (fetch_OP).
7469 This function will *only* generate instructions if there is a direct
7470 optab. No compare and swap loops or libcalls will be generated. */
7473 expand_atomic_fetch_op_no_fallback (rtx target
, rtx mem
, rtx val
,
7474 enum rtx_code code
, enum memmodel model
,
7477 machine_mode mode
= GET_MODE (mem
);
7478 struct atomic_op_functions optab
;
7480 bool unused_result
= (target
== const0_rtx
);
7482 get_atomic_op_for_code (&optab
, code
);
7484 /* Check to see if there are any better instructions. */
7485 result
= maybe_optimize_fetch_op (target
, mem
, val
, code
, model
, after
);
7489 /* Check for the case where the result isn't used and try those patterns. */
7492 /* Try the memory model variant first. */
7493 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, true);
7497 /* Next try the old style withuot a memory model. */
7498 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, true);
7502 /* There is no no-result pattern, so try patterns with a result. */
7506 /* Try the __atomic version. */
7507 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, after
);
7511 /* Try the older __sync version. */
7512 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, after
);
7516 /* If the fetch value can be calculated from the other variation of fetch,
7517 try that operation. */
7518 if (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
)
7520 /* Try the __atomic version, then the older __sync version. */
7521 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, !after
);
7523 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, !after
);
7527 /* If the result isn't used, no need to do compensation code. */
7531 /* Issue compensation code. Fetch_after == fetch_before OP val.
7532 Fetch_before == after REVERSE_OP val. */
7534 code
= optab
.reverse_code
;
7537 result
= expand_simple_binop (mode
, AND
, result
, val
, NULL_RTX
,
7538 true, OPTAB_LIB_WIDEN
);
7539 result
= expand_simple_unop (mode
, NOT
, result
, target
, true);
7542 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
7543 true, OPTAB_LIB_WIDEN
);
7548 /* No direct opcode can be generated. */
7554 /* This function expands an atomic fetch_OP or OP_fetch operation:
7555 TARGET is an option place to stick the return value. const0_rtx indicates
7556 the result is unused.
7557 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7558 CODE is the operation being performed (OP)
7559 MEMMODEL is the memory model variant to use.
7560 AFTER is true to return the result of the operation (OP_fetch).
7561 AFTER is false to return the value before the operation (fetch_OP). */
7563 expand_atomic_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
7564 enum memmodel model
, bool after
)
7566 machine_mode mode
= GET_MODE (mem
);
7568 bool unused_result
= (target
== const0_rtx
);
7570 /* If loads are not atomic for the required size and we are not called to
7571 provide a __sync builtin, do not do anything so that we stay consistent
7572 with atomic loads of the same size. */
7573 if (!can_atomic_load_p (mode
) && !is_mm_sync (model
))
7576 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, val
, code
, model
,
7582 /* Add/sub can be implemented by doing the reverse operation with -(val). */
7583 if (code
== PLUS
|| code
== MINUS
)
7586 enum rtx_code reverse
= (code
== PLUS
? MINUS
: PLUS
);
7589 tmp
= expand_simple_unop (mode
, NEG
, val
, NULL_RTX
, true);
7590 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, tmp
, reverse
,
7594 /* PLUS worked so emit the insns and return. */
7601 /* PLUS did not work, so throw away the negation code and continue. */
7605 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
7606 if (!can_compare_and_swap_p (mode
, false))
7610 enum rtx_code orig_code
= code
;
7611 struct atomic_op_functions optab
;
7613 get_atomic_op_for_code (&optab
, code
);
7614 libfunc
= optab_libfunc (after
? optab
.fetch_after
7615 : optab
.fetch_before
, mode
);
7617 && (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
))
7621 code
= optab
.reverse_code
;
7622 libfunc
= optab_libfunc (after
? optab
.fetch_before
7623 : optab
.fetch_after
, mode
);
7625 if (libfunc
!= NULL
)
7627 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
7628 result
= emit_library_call_value (libfunc
, NULL
, LCT_NORMAL
, mode
,
7629 addr
, ptr_mode
, val
, mode
);
7631 if (!unused_result
&& fixup
)
7632 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
7633 true, OPTAB_LIB_WIDEN
);
7637 /* We need the original code for any further attempts. */
7641 /* If nothing else has succeeded, default to a compare and swap loop. */
7642 if (can_compare_and_swap_p (mode
, true))
7645 rtx t0
= gen_reg_rtx (mode
), t1
;
7649 /* If the result is used, get a register for it. */
7652 if (!target
|| !register_operand (target
, mode
))
7653 target
= gen_reg_rtx (mode
);
7654 /* If fetch_before, copy the value now. */
7656 emit_move_insn (target
, t0
);
7659 target
= const0_rtx
;
7664 t1
= expand_simple_binop (mode
, AND
, t1
, val
, NULL_RTX
,
7665 true, OPTAB_LIB_WIDEN
);
7666 t1
= expand_simple_unop (mode
, code
, t1
, NULL_RTX
, true);
7669 t1
= expand_simple_binop (mode
, code
, t1
, val
, NULL_RTX
, true,
7672 /* For after, copy the value now. */
7673 if (!unused_result
&& after
)
7674 emit_move_insn (target
, t1
);
7675 insn
= get_insns ();
7678 if (t1
!= NULL
&& expand_compare_and_swap_loop (mem
, t0
, t1
, insn
))
7685 /* Return true if OPERAND is suitable for operand number OPNO of
7686 instruction ICODE. */
7689 insn_operand_matches (enum insn_code icode
, unsigned int opno
, rtx operand
)
7691 return (!insn_data
[(int) icode
].operand
[opno
].predicate
7692 || (insn_data
[(int) icode
].operand
[opno
].predicate
7693 (operand
, insn_data
[(int) icode
].operand
[opno
].mode
)));
7696 /* TARGET is a target of a multiword operation that we are going to
7697 implement as a series of word-mode operations. Return true if
7698 TARGET is suitable for this purpose. */
7701 valid_multiword_target_p (rtx target
)
7706 mode
= GET_MODE (target
);
7707 if (!GET_MODE_SIZE (mode
).is_constant (&size
))
7709 for (i
= 0; i
< size
; i
+= UNITS_PER_WORD
)
7710 if (!validate_subreg (word_mode
, mode
, target
, i
))
7715 /* Make OP describe an input operand that has value INTVAL and that has
7716 no inherent mode. This function should only be used for operands that
7717 are always expand-time constants. The backend may request that INTVAL
7718 be copied into a different kind of rtx, but it must specify the mode
7719 of that rtx if so. */
7722 create_integer_operand (class expand_operand
*op
, poly_int64 intval
)
7724 create_expand_operand (op
, EXPAND_INTEGER
,
7725 gen_int_mode (intval
, MAX_MODE_INT
),
7726 VOIDmode
, false, intval
);
7729 /* Like maybe_legitimize_operand, but do not change the code of the
7730 current rtx value. */
7733 maybe_legitimize_operand_same_code (enum insn_code icode
, unsigned int opno
,
7734 class expand_operand
*op
)
7736 /* See if the operand matches in its current form. */
7737 if (insn_operand_matches (icode
, opno
, op
->value
))
7740 /* If the operand is a memory whose address has no side effects,
7741 try forcing the address into a non-virtual pseudo register.
7742 The check for side effects is important because copy_to_mode_reg
7743 cannot handle things like auto-modified addresses. */
7744 if (insn_data
[(int) icode
].operand
[opno
].allows_mem
&& MEM_P (op
->value
))
7749 addr
= XEXP (mem
, 0);
7750 if (!(REG_P (addr
) && REGNO (addr
) > LAST_VIRTUAL_REGISTER
)
7751 && !side_effects_p (addr
))
7756 last
= get_last_insn ();
7757 mode
= get_address_mode (mem
);
7758 mem
= replace_equiv_address (mem
, copy_to_mode_reg (mode
, addr
));
7759 if (insn_operand_matches (icode
, opno
, mem
))
7764 delete_insns_since (last
);
7771 /* Try to make OP match operand OPNO of instruction ICODE. Return true
7772 on success, storing the new operand value back in OP. */
7775 maybe_legitimize_operand (enum insn_code icode
, unsigned int opno
,
7776 class expand_operand
*op
)
7778 machine_mode mode
, imode
, tmode
;
7785 temporary_volatile_ok
v (true);
7786 return maybe_legitimize_operand_same_code (icode
, opno
, op
);
7790 gcc_assert (mode
!= VOIDmode
);
7792 && op
->value
!= const0_rtx
7793 && GET_MODE (op
->value
) == mode
7794 && maybe_legitimize_operand_same_code (icode
, opno
, op
))
7797 op
->value
= gen_reg_rtx (mode
);
7803 gcc_assert (mode
!= VOIDmode
);
7804 gcc_assert (GET_MODE (op
->value
) == VOIDmode
7805 || GET_MODE (op
->value
) == mode
);
7806 if (maybe_legitimize_operand_same_code (icode
, opno
, op
))
7809 op
->value
= copy_to_mode_reg (mode
, op
->value
);
7812 case EXPAND_CONVERT_TO
:
7813 gcc_assert (mode
!= VOIDmode
);
7814 op
->value
= convert_to_mode (mode
, op
->value
, op
->unsigned_p
);
7817 case EXPAND_CONVERT_FROM
:
7818 if (GET_MODE (op
->value
) != VOIDmode
)
7819 mode
= GET_MODE (op
->value
);
7821 /* The caller must tell us what mode this value has. */
7822 gcc_assert (mode
!= VOIDmode
);
7824 imode
= insn_data
[(int) icode
].operand
[opno
].mode
;
7825 tmode
= (VECTOR_MODE_P (imode
) && !VECTOR_MODE_P (mode
)
7826 ? GET_MODE_INNER (imode
) : imode
);
7827 if (tmode
!= VOIDmode
&& tmode
!= mode
)
7829 op
->value
= convert_modes (tmode
, mode
, op
->value
, op
->unsigned_p
);
7832 if (imode
!= VOIDmode
&& imode
!= mode
)
7834 gcc_assert (VECTOR_MODE_P (imode
) && !VECTOR_MODE_P (mode
));
7835 op
->value
= expand_vector_broadcast (imode
, op
->value
);
7840 case EXPAND_ADDRESS
:
7841 op
->value
= convert_memory_address (as_a
<scalar_int_mode
> (mode
),
7845 case EXPAND_INTEGER
:
7846 mode
= insn_data
[(int) icode
].operand
[opno
].mode
;
7847 if (mode
!= VOIDmode
7848 && known_eq (trunc_int_for_mode (op
->int_value
, mode
),
7851 op
->value
= gen_int_mode (op
->int_value
, mode
);
7856 return insn_operand_matches (icode
, opno
, op
->value
);
7859 /* Make OP describe an input operand that should have the same value
7860 as VALUE, after any mode conversion that the target might request.
7861 TYPE is the type of VALUE. */
7864 create_convert_operand_from_type (class expand_operand
*op
,
7865 rtx value
, tree type
)
7867 create_convert_operand_from (op
, value
, TYPE_MODE (type
),
7868 TYPE_UNSIGNED (type
));
7871 /* Return true if the requirements on operands OP1 and OP2 of instruction
7872 ICODE are similar enough for the result of legitimizing OP1 to be
7873 reusable for OP2. OPNO1 and OPNO2 are the operand numbers associated
7874 with OP1 and OP2 respectively. */
7877 can_reuse_operands_p (enum insn_code icode
,
7878 unsigned int opno1
, unsigned int opno2
,
7879 const class expand_operand
*op1
,
7880 const class expand_operand
*op2
)
7882 /* Check requirements that are common to all types. */
7883 if (op1
->type
!= op2
->type
7884 || op1
->mode
!= op2
->mode
7885 || (insn_data
[(int) icode
].operand
[opno1
].mode
7886 != insn_data
[(int) icode
].operand
[opno2
].mode
))
7889 /* Check the requirements for specific types. */
7893 /* Outputs must remain distinct. */
7898 case EXPAND_ADDRESS
:
7899 case EXPAND_INTEGER
:
7902 case EXPAND_CONVERT_TO
:
7903 case EXPAND_CONVERT_FROM
:
7904 return op1
->unsigned_p
== op2
->unsigned_p
;
7909 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
7910 of instruction ICODE. Return true on success, leaving the new operand
7911 values in the OPS themselves. Emit no code on failure. */
7914 maybe_legitimize_operands (enum insn_code icode
, unsigned int opno
,
7915 unsigned int nops
, class expand_operand
*ops
)
7917 rtx_insn
*last
= get_last_insn ();
7918 rtx
*orig_values
= XALLOCAVEC (rtx
, nops
);
7919 for (unsigned int i
= 0; i
< nops
; i
++)
7921 orig_values
[i
] = ops
[i
].value
;
7923 /* First try reusing the result of an earlier legitimization.
7924 This avoids duplicate rtl and ensures that tied operands
7927 This search is linear, but NOPS is bounded at compile time
7928 to a small number (current a single digit). */
7931 if (can_reuse_operands_p (icode
, opno
+ j
, opno
+ i
, &ops
[j
], &ops
[i
])
7932 && rtx_equal_p (orig_values
[j
], orig_values
[i
])
7934 && insn_operand_matches (icode
, opno
+ i
, ops
[j
].value
))
7936 ops
[i
].value
= copy_rtx (ops
[j
].value
);
7940 /* Otherwise try legitimizing the operand on its own. */
7941 if (j
== i
&& !maybe_legitimize_operand (icode
, opno
+ i
, &ops
[i
]))
7943 delete_insns_since (last
);
7950 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
7951 as its operands. Return the instruction pattern on success,
7952 and emit any necessary set-up code. Return null and emit no
7956 maybe_gen_insn (enum insn_code icode
, unsigned int nops
,
7957 class expand_operand
*ops
)
7959 gcc_assert (nops
== (unsigned int) insn_data
[(int) icode
].n_generator_args
);
7960 if (!maybe_legitimize_operands (icode
, 0, nops
, ops
))
7966 return GEN_FCN (icode
) ();
7968 return GEN_FCN (icode
) (ops
[0].value
);
7970 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
);
7972 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
);
7974 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7977 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7978 ops
[3].value
, ops
[4].value
);
7980 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7981 ops
[3].value
, ops
[4].value
, ops
[5].value
);
7983 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7984 ops
[3].value
, ops
[4].value
, ops
[5].value
,
7987 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7988 ops
[3].value
, ops
[4].value
, ops
[5].value
,
7989 ops
[6].value
, ops
[7].value
);
7991 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7992 ops
[3].value
, ops
[4].value
, ops
[5].value
,
7993 ops
[6].value
, ops
[7].value
, ops
[8].value
);
7998 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7999 as its operands. Return true on success and emit no code on failure. */
8002 maybe_expand_insn (enum insn_code icode
, unsigned int nops
,
8003 class expand_operand
*ops
)
8005 rtx_insn
*pat
= maybe_gen_insn (icode
, nops
, ops
);
8014 /* Like maybe_expand_insn, but for jumps. */
8017 maybe_expand_jump_insn (enum insn_code icode
, unsigned int nops
,
8018 class expand_operand
*ops
)
8020 rtx_insn
*pat
= maybe_gen_insn (icode
, nops
, ops
);
8023 emit_jump_insn (pat
);
8029 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
8033 expand_insn (enum insn_code icode
, unsigned int nops
,
8034 class expand_operand
*ops
)
8036 if (!maybe_expand_insn (icode
, nops
, ops
))
8040 /* Like expand_insn, but for jumps. */
8043 expand_jump_insn (enum insn_code icode
, unsigned int nops
,
8044 class expand_operand
*ops
)
8046 if (!maybe_expand_jump_insn (icode
, nops
, ops
))