1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2017 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"
37 /* Include insn-config.h before expr.h so that HAVE_conditional_move
38 is properly defined. */
39 #include "stor-layout.h"
44 #include "optabs-tree.h"
47 static void prepare_float_lib_cmp (rtx
, rtx
, enum rtx_code
, rtx
*,
49 static rtx
expand_unop_direct (machine_mode
, optab
, rtx
, rtx
, int);
50 static void emit_libcall_block_1 (rtx_insn
*, rtx
, rtx
, rtx
, bool);
52 /* Debug facility for use in GDB. */
53 void debug_optab_libfuncs (void);
55 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
56 the result of operation CODE applied to OP0 (and OP1 if it is a binary
59 If the last insn does not set TARGET, don't do anything, but return 1.
61 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
62 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
63 try again, ensuring that TARGET is not one of the operands. */
66 add_equal_note (rtx_insn
*insns
, rtx target
, enum rtx_code code
, rtx op0
, rtx op1
)
72 gcc_assert (insns
&& INSN_P (insns
) && NEXT_INSN (insns
));
74 if (GET_RTX_CLASS (code
) != RTX_COMM_ARITH
75 && GET_RTX_CLASS (code
) != RTX_BIN_ARITH
76 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
77 && GET_RTX_CLASS (code
) != RTX_COMPARE
78 && GET_RTX_CLASS (code
) != RTX_UNARY
)
81 if (GET_CODE (target
) == ZERO_EXTRACT
)
84 for (last_insn
= insns
;
85 NEXT_INSN (last_insn
) != NULL_RTX
;
86 last_insn
= NEXT_INSN (last_insn
))
89 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
90 a value changing in the insn, so the note would be invalid for CSE. */
91 if (reg_overlap_mentioned_p (target
, op0
)
92 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
95 && (rtx_equal_p (target
, op0
)
96 || (op1
&& rtx_equal_p (target
, op1
))))
98 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
99 over expanding it as temp = MEM op X, MEM = temp. If the target
100 supports MEM = MEM op X instructions, it is sometimes too hard
101 to reconstruct that form later, especially if X is also a memory,
102 and due to multiple occurrences of addresses the address might
103 be forced into register unnecessarily.
104 Note that not emitting the REG_EQUIV note might inhibit
105 CSE in some cases. */
106 set
= single_set (last_insn
);
108 && GET_CODE (SET_SRC (set
)) == code
109 && MEM_P (SET_DEST (set
))
110 && (rtx_equal_p (SET_DEST (set
), XEXP (SET_SRC (set
), 0))
111 || (op1
&& rtx_equal_p (SET_DEST (set
),
112 XEXP (SET_SRC (set
), 1)))))
118 set
= set_for_reg_notes (last_insn
);
122 if (! rtx_equal_p (SET_DEST (set
), target
)
123 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
124 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
125 || ! rtx_equal_p (XEXP (SET_DEST (set
), 0), target
)))
128 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
138 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (target
) != GET_MODE (op0
))
140 note
= gen_rtx_fmt_e (code
, GET_MODE (op0
), copy_rtx (op0
));
141 if (GET_MODE_UNIT_SIZE (GET_MODE (op0
))
142 > GET_MODE_UNIT_SIZE (GET_MODE (target
)))
143 note
= simplify_gen_unary (TRUNCATE
, GET_MODE (target
),
144 note
, GET_MODE (op0
));
146 note
= simplify_gen_unary (ZERO_EXTEND
, GET_MODE (target
),
147 note
, GET_MODE (op0
));
152 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
156 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
158 set_unique_reg_note (last_insn
, REG_EQUAL
, note
);
163 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
164 for a widening operation would be. In most cases this would be OP0, but if
165 that's a constant it'll be VOIDmode, which isn't useful. */
168 widened_mode (machine_mode to_mode
, rtx op0
, rtx op1
)
170 machine_mode m0
= GET_MODE (op0
);
171 machine_mode m1
= GET_MODE (op1
);
174 if (m0
== VOIDmode
&& m1
== VOIDmode
)
176 else if (m0
== VOIDmode
|| GET_MODE_UNIT_SIZE (m0
) < GET_MODE_UNIT_SIZE (m1
))
181 if (GET_MODE_UNIT_SIZE (result
) > GET_MODE_UNIT_SIZE (to_mode
))
187 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
188 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
189 not actually do a sign-extend or zero-extend, but can leave the
190 higher-order bits of the result rtx undefined, for example, in the case
191 of logical operations, but not right shifts. */
194 widen_operand (rtx op
, machine_mode mode
, machine_mode oldmode
,
195 int unsignedp
, int no_extend
)
198 scalar_int_mode int_mode
;
200 /* If we don't have to extend and this is a constant, return it. */
201 if (no_extend
&& GET_MODE (op
) == VOIDmode
)
204 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
205 extend since it will be more efficient to do so unless the signedness of
206 a promoted object differs from our extension. */
208 || !is_a
<scalar_int_mode
> (mode
, &int_mode
)
209 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)
210 && SUBREG_CHECK_PROMOTED_SIGN (op
, unsignedp
)))
211 return convert_modes (mode
, oldmode
, op
, unsignedp
);
213 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
215 if (GET_MODE_SIZE (int_mode
) <= UNITS_PER_WORD
)
216 return gen_lowpart (int_mode
, force_reg (GET_MODE (op
), op
));
218 /* Otherwise, get an object of MODE, clobber it, and set the low-order
221 result
= gen_reg_rtx (int_mode
);
222 emit_clobber (result
);
223 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
227 /* Expand vector widening operations.
229 There are two different classes of operations handled here:
230 1) Operations whose result is wider than all the arguments to the operation.
231 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
232 In this case OP0 and optionally OP1 would be initialized,
233 but WIDE_OP wouldn't (not relevant for this case).
234 2) Operations whose result is of the same size as the last argument to the
235 operation, but wider than all the other arguments to the operation.
236 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
237 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
239 E.g, when called to expand the following operations, this is how
240 the arguments will be initialized:
242 widening-sum 2 oprnd0 - oprnd1
243 widening-dot-product 3 oprnd0 oprnd1 oprnd2
244 widening-mult 2 oprnd0 oprnd1 -
245 type-promotion (vec-unpack) 1 oprnd0 - - */
248 expand_widen_pattern_expr (sepops ops
, rtx op0
, rtx op1
, rtx wide_op
,
249 rtx target
, int unsignedp
)
251 struct expand_operand eops
[4];
252 tree oprnd0
, oprnd1
, oprnd2
;
253 machine_mode wmode
= VOIDmode
, tmode0
, tmode1
= VOIDmode
;
254 optab widen_pattern_optab
;
255 enum insn_code icode
;
256 int nops
= TREE_CODE_LENGTH (ops
->code
);
260 tmode0
= TYPE_MODE (TREE_TYPE (oprnd0
));
261 widen_pattern_optab
=
262 optab_for_tree_code (ops
->code
, TREE_TYPE (oprnd0
), optab_default
);
263 if (ops
->code
== WIDEN_MULT_PLUS_EXPR
264 || ops
->code
== WIDEN_MULT_MINUS_EXPR
)
265 icode
= find_widening_optab_handler (widen_pattern_optab
,
266 TYPE_MODE (TREE_TYPE (ops
->op2
)),
269 icode
= optab_handler (widen_pattern_optab
, tmode0
);
270 gcc_assert (icode
!= CODE_FOR_nothing
);
275 tmode1
= TYPE_MODE (TREE_TYPE (oprnd1
));
278 /* The last operand is of a wider mode than the rest of the operands. */
283 gcc_assert (tmode1
== tmode0
);
286 wmode
= TYPE_MODE (TREE_TYPE (oprnd2
));
290 create_output_operand (&eops
[op
++], target
, TYPE_MODE (ops
->type
));
291 create_convert_operand_from (&eops
[op
++], op0
, tmode0
, unsignedp
);
293 create_convert_operand_from (&eops
[op
++], op1
, tmode1
, unsignedp
);
295 create_convert_operand_from (&eops
[op
++], wide_op
, wmode
, unsignedp
);
296 expand_insn (icode
, op
, eops
);
297 return eops
[0].value
;
300 /* Generate code to perform an operation specified by TERNARY_OPTAB
301 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
303 UNSIGNEDP is for the case where we have to widen the operands
304 to perform the operation. It says to use zero-extension.
306 If TARGET is nonzero, the value
307 is generated there, if it is convenient to do so.
308 In all cases an rtx is returned for the locus of the value;
309 this may or may not be TARGET. */
312 expand_ternary_op (machine_mode mode
, optab ternary_optab
, rtx op0
,
313 rtx op1
, rtx op2
, rtx target
, int unsignedp
)
315 struct expand_operand ops
[4];
316 enum insn_code icode
= optab_handler (ternary_optab
, mode
);
318 gcc_assert (optab_handler (ternary_optab
, mode
) != CODE_FOR_nothing
);
320 create_output_operand (&ops
[0], target
, mode
);
321 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
322 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
323 create_convert_operand_from (&ops
[3], op2
, mode
, unsignedp
);
324 expand_insn (icode
, 4, ops
);
329 /* Like expand_binop, but return a constant rtx if the result can be
330 calculated at compile time. The arguments and return value are
331 otherwise the same as for expand_binop. */
334 simplify_expand_binop (machine_mode mode
, optab binoptab
,
335 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
336 enum optab_methods methods
)
338 if (CONSTANT_P (op0
) && CONSTANT_P (op1
))
340 rtx x
= simplify_binary_operation (optab_to_code (binoptab
),
346 return expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
);
349 /* Like simplify_expand_binop, but always put the result in TARGET.
350 Return true if the expansion succeeded. */
353 force_expand_binop (machine_mode mode
, optab binoptab
,
354 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
355 enum optab_methods methods
)
357 rtx x
= simplify_expand_binop (mode
, binoptab
, op0
, op1
,
358 target
, unsignedp
, methods
);
362 emit_move_insn (target
, x
);
366 /* Create a new vector value in VMODE with all elements set to OP. The
367 mode of OP must be the element mode of VMODE. If OP is a constant,
368 then the return value will be a constant. */
371 expand_vector_broadcast (machine_mode vmode
, rtx op
)
373 enum insn_code icode
;
378 gcc_checking_assert (VECTOR_MODE_P (vmode
));
380 if (valid_for_const_vec_duplicate_p (vmode
, op
))
381 return gen_const_vec_duplicate (vmode
, op
);
383 /* ??? If the target doesn't have a vec_init, then we have no easy way
384 of performing this operation. Most of this sort of generic support
385 is hidden away in the vector lowering support in gimple. */
386 icode
= convert_optab_handler (vec_init_optab
, vmode
,
387 GET_MODE_INNER (vmode
));
388 if (icode
== CODE_FOR_nothing
)
391 n
= GET_MODE_NUNITS (vmode
);
392 vec
= rtvec_alloc (n
);
393 for (i
= 0; i
< n
; ++i
)
394 RTVEC_ELT (vec
, i
) = op
;
395 ret
= gen_reg_rtx (vmode
);
396 emit_insn (GEN_FCN (icode
) (ret
, gen_rtx_PARALLEL (vmode
, vec
)));
401 /* This subroutine of expand_doubleword_shift handles the cases in which
402 the effective shift value is >= BITS_PER_WORD. The arguments and return
403 value are the same as for the parent routine, except that SUPERWORD_OP1
404 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
405 INTO_TARGET may be null if the caller has decided to calculate it. */
408 expand_superword_shift (optab binoptab
, rtx outof_input
, rtx superword_op1
,
409 rtx outof_target
, rtx into_target
,
410 int unsignedp
, enum optab_methods methods
)
412 if (into_target
!= 0)
413 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, superword_op1
,
414 into_target
, unsignedp
, methods
))
417 if (outof_target
!= 0)
419 /* For a signed right shift, we must fill OUTOF_TARGET with copies
420 of the sign bit, otherwise we must fill it with zeros. */
421 if (binoptab
!= ashr_optab
)
422 emit_move_insn (outof_target
, CONST0_RTX (word_mode
));
424 if (!force_expand_binop (word_mode
, binoptab
,
425 outof_input
, GEN_INT (BITS_PER_WORD
- 1),
426 outof_target
, unsignedp
, methods
))
432 /* This subroutine of expand_doubleword_shift handles the cases in which
433 the effective shift value is < BITS_PER_WORD. The arguments and return
434 value are the same as for the parent routine. */
437 expand_subword_shift (scalar_int_mode op1_mode
, optab binoptab
,
438 rtx outof_input
, rtx into_input
, rtx op1
,
439 rtx outof_target
, rtx into_target
,
440 int unsignedp
, enum optab_methods methods
,
441 unsigned HOST_WIDE_INT shift_mask
)
443 optab reverse_unsigned_shift
, unsigned_shift
;
446 reverse_unsigned_shift
= (binoptab
== ashl_optab
? lshr_optab
: ashl_optab
);
447 unsigned_shift
= (binoptab
== ashl_optab
? ashl_optab
: lshr_optab
);
449 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
450 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
451 the opposite direction to BINOPTAB. */
452 if (CONSTANT_P (op1
) || shift_mask
>= BITS_PER_WORD
)
454 carries
= outof_input
;
455 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
,
456 op1_mode
), op1_mode
);
457 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
462 /* We must avoid shifting by BITS_PER_WORD bits since that is either
463 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
464 has unknown behavior. Do a single shift first, then shift by the
465 remainder. It's OK to use ~OP1 as the remainder if shift counts
466 are truncated to the mode size. */
467 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
468 outof_input
, const1_rtx
, 0, unsignedp
, methods
);
469 if (shift_mask
== BITS_PER_WORD
- 1)
471 tmp
= immed_wide_int_const
472 (wi::minus_one (GET_MODE_PRECISION (op1_mode
)), op1_mode
);
473 tmp
= simplify_expand_binop (op1_mode
, xor_optab
, op1
, tmp
,
478 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
- 1,
479 op1_mode
), op1_mode
);
480 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
484 if (tmp
== 0 || carries
== 0)
486 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
487 carries
, tmp
, 0, unsignedp
, methods
);
491 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
492 so the result can go directly into INTO_TARGET if convenient. */
493 tmp
= expand_binop (word_mode
, unsigned_shift
, into_input
, op1
,
494 into_target
, unsignedp
, methods
);
498 /* Now OR in the bits carried over from OUTOF_INPUT. */
499 if (!force_expand_binop (word_mode
, ior_optab
, tmp
, carries
,
500 into_target
, unsignedp
, methods
))
503 /* Use a standard word_mode shift for the out-of half. */
504 if (outof_target
!= 0)
505 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
506 outof_target
, unsignedp
, methods
))
513 /* Try implementing expand_doubleword_shift using conditional moves.
514 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
515 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
516 are the shift counts to use in the former and latter case. All other
517 arguments are the same as the parent routine. */
520 expand_doubleword_shift_condmove (scalar_int_mode op1_mode
, optab binoptab
,
521 enum rtx_code cmp_code
, rtx cmp1
, rtx cmp2
,
522 rtx outof_input
, rtx into_input
,
523 rtx subword_op1
, rtx superword_op1
,
524 rtx outof_target
, rtx into_target
,
525 int unsignedp
, enum optab_methods methods
,
526 unsigned HOST_WIDE_INT shift_mask
)
528 rtx outof_superword
, into_superword
;
530 /* Put the superword version of the output into OUTOF_SUPERWORD and
532 outof_superword
= outof_target
!= 0 ? gen_reg_rtx (word_mode
) : 0;
533 if (outof_target
!= 0 && subword_op1
== superword_op1
)
535 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
536 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
537 into_superword
= outof_target
;
538 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
539 outof_superword
, 0, unsignedp
, methods
))
544 into_superword
= gen_reg_rtx (word_mode
);
545 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
546 outof_superword
, into_superword
,
551 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
552 if (!expand_subword_shift (op1_mode
, binoptab
,
553 outof_input
, into_input
, subword_op1
,
554 outof_target
, into_target
,
555 unsignedp
, methods
, shift_mask
))
558 /* Select between them. Do the INTO half first because INTO_SUPERWORD
559 might be the current value of OUTOF_TARGET. */
560 if (!emit_conditional_move (into_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
561 into_target
, into_superword
, word_mode
, false))
564 if (outof_target
!= 0)
565 if (!emit_conditional_move (outof_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
566 outof_target
, outof_superword
,
573 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
574 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
575 input operand; the shift moves bits in the direction OUTOF_INPUT->
576 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
577 of the target. OP1 is the shift count and OP1_MODE is its mode.
578 If OP1 is constant, it will have been truncated as appropriate
579 and is known to be nonzero.
581 If SHIFT_MASK is zero, the result of word shifts is undefined when the
582 shift count is outside the range [0, BITS_PER_WORD). This routine must
583 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
585 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
586 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
587 fill with zeros or sign bits as appropriate.
589 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
590 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
591 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
592 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
595 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
596 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
597 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
598 function wants to calculate it itself.
600 Return true if the shift could be successfully synthesized. */
603 expand_doubleword_shift (scalar_int_mode op1_mode
, optab binoptab
,
604 rtx outof_input
, rtx into_input
, rtx op1
,
605 rtx outof_target
, rtx into_target
,
606 int unsignedp
, enum optab_methods methods
,
607 unsigned HOST_WIDE_INT shift_mask
)
609 rtx superword_op1
, tmp
, cmp1
, cmp2
;
610 enum rtx_code cmp_code
;
612 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
613 fill the result with sign or zero bits as appropriate. If so, the value
614 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
615 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
616 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
618 This isn't worthwhile for constant shifts since the optimizers will
619 cope better with in-range shift counts. */
620 if (shift_mask
>= BITS_PER_WORD
622 && !CONSTANT_P (op1
))
624 if (!expand_doubleword_shift (op1_mode
, binoptab
,
625 outof_input
, into_input
, op1
,
627 unsignedp
, methods
, shift_mask
))
629 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
630 outof_target
, unsignedp
, methods
))
635 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
636 is true when the effective shift value is less than BITS_PER_WORD.
637 Set SUPERWORD_OP1 to the shift count that should be used to shift
638 OUTOF_INPUT into INTO_TARGET when the condition is false. */
639 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
, op1_mode
), op1_mode
);
640 if (!CONSTANT_P (op1
) && shift_mask
== BITS_PER_WORD
- 1)
642 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
643 is a subword shift count. */
644 cmp1
= simplify_expand_binop (op1_mode
, and_optab
, op1
, tmp
,
646 cmp2
= CONST0_RTX (op1_mode
);
652 /* Set CMP1 to OP1 - BITS_PER_WORD. */
653 cmp1
= simplify_expand_binop (op1_mode
, sub_optab
, op1
, tmp
,
655 cmp2
= CONST0_RTX (op1_mode
);
657 superword_op1
= cmp1
;
662 /* If we can compute the condition at compile time, pick the
663 appropriate subroutine. */
664 tmp
= simplify_relational_operation (cmp_code
, SImode
, op1_mode
, cmp1
, cmp2
);
665 if (tmp
!= 0 && CONST_INT_P (tmp
))
667 if (tmp
== const0_rtx
)
668 return expand_superword_shift (binoptab
, outof_input
, superword_op1
,
669 outof_target
, into_target
,
672 return expand_subword_shift (op1_mode
, binoptab
,
673 outof_input
, into_input
, op1
,
674 outof_target
, into_target
,
675 unsignedp
, methods
, shift_mask
);
678 /* Try using conditional moves to generate straight-line code. */
679 if (HAVE_conditional_move
)
681 rtx_insn
*start
= get_last_insn ();
682 if (expand_doubleword_shift_condmove (op1_mode
, binoptab
,
683 cmp_code
, cmp1
, cmp2
,
684 outof_input
, into_input
,
686 outof_target
, into_target
,
687 unsignedp
, methods
, shift_mask
))
689 delete_insns_since (start
);
692 /* As a last resort, use branches to select the correct alternative. */
693 rtx_code_label
*subword_label
= gen_label_rtx ();
694 rtx_code_label
*done_label
= gen_label_rtx ();
697 do_compare_rtx_and_jump (cmp1
, cmp2
, cmp_code
, false, op1_mode
,
699 profile_probability::uninitialized ());
702 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
703 outof_target
, into_target
,
707 emit_jump_insn (targetm
.gen_jump (done_label
));
709 emit_label (subword_label
);
711 if (!expand_subword_shift (op1_mode
, binoptab
,
712 outof_input
, into_input
, op1
,
713 outof_target
, into_target
,
714 unsignedp
, methods
, shift_mask
))
717 emit_label (done_label
);
721 /* Subroutine of expand_binop. Perform a double word multiplication of
722 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
723 as the target's word_mode. This function return NULL_RTX if anything
724 goes wrong, in which case it may have already emitted instructions
725 which need to be deleted.
727 If we want to multiply two two-word values and have normal and widening
728 multiplies of single-word values, we can do this with three smaller
731 The multiplication proceeds as follows:
732 _______________________
733 [__op0_high_|__op0_low__]
734 _______________________
735 * [__op1_high_|__op1_low__]
736 _______________________________________________
737 _______________________
738 (1) [__op0_low__*__op1_low__]
739 _______________________
740 (2a) [__op0_low__*__op1_high_]
741 _______________________
742 (2b) [__op0_high_*__op1_low__]
743 _______________________
744 (3) [__op0_high_*__op1_high_]
747 This gives a 4-word result. Since we are only interested in the
748 lower 2 words, partial result (3) and the upper words of (2a) and
749 (2b) don't need to be calculated. Hence (2a) and (2b) can be
750 calculated using non-widening multiplication.
752 (1), however, needs to be calculated with an unsigned widening
753 multiplication. If this operation is not directly supported we
754 try using a signed widening multiplication and adjust the result.
755 This adjustment works as follows:
757 If both operands are positive then no adjustment is needed.
759 If the operands have different signs, for example op0_low < 0 and
760 op1_low >= 0, the instruction treats the most significant bit of
761 op0_low as a sign bit instead of a bit with significance
762 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
763 with 2**BITS_PER_WORD - op0_low, and two's complements the
764 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
767 Similarly, if both operands are negative, we need to add
768 (op0_low + op1_low) * 2**BITS_PER_WORD.
770 We use a trick to adjust quickly. We logically shift op0_low right
771 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
772 op0_high (op1_high) before it is used to calculate 2b (2a). If no
773 logical shift exists, we do an arithmetic right shift and subtract
777 expand_doubleword_mult (machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
778 bool umulp
, enum optab_methods methods
)
780 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
781 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
782 rtx wordm1
= umulp
? NULL_RTX
: GEN_INT (BITS_PER_WORD
- 1);
783 rtx product
, adjust
, product_high
, temp
;
785 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
786 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
787 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
788 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
790 /* If we're using an unsigned multiply to directly compute the product
791 of the low-order words of the operands and perform any required
792 adjustments of the operands, we begin by trying two more multiplications
793 and then computing the appropriate sum.
795 We have checked above that the required addition is provided.
796 Full-word addition will normally always succeed, especially if
797 it is provided at all, so we don't worry about its failure. The
798 multiplication may well fail, however, so we do handle that. */
802 /* ??? This could be done with emit_store_flag where available. */
803 temp
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
804 NULL_RTX
, 1, methods
);
806 op0_high
= expand_binop (word_mode
, add_optab
, op0_high
, temp
,
807 NULL_RTX
, 0, OPTAB_DIRECT
);
810 temp
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
811 NULL_RTX
, 0, methods
);
814 op0_high
= expand_binop (word_mode
, sub_optab
, op0_high
, temp
,
815 NULL_RTX
, 0, OPTAB_DIRECT
);
822 adjust
= expand_binop (word_mode
, smul_optab
, op0_high
, op1_low
,
823 NULL_RTX
, 0, OPTAB_DIRECT
);
827 /* OP0_HIGH should now be dead. */
831 /* ??? This could be done with emit_store_flag where available. */
832 temp
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
833 NULL_RTX
, 1, methods
);
835 op1_high
= expand_binop (word_mode
, add_optab
, op1_high
, temp
,
836 NULL_RTX
, 0, OPTAB_DIRECT
);
839 temp
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
840 NULL_RTX
, 0, methods
);
843 op1_high
= expand_binop (word_mode
, sub_optab
, op1_high
, temp
,
844 NULL_RTX
, 0, OPTAB_DIRECT
);
851 temp
= expand_binop (word_mode
, smul_optab
, op1_high
, op0_low
,
852 NULL_RTX
, 0, OPTAB_DIRECT
);
856 /* OP1_HIGH should now be dead. */
858 adjust
= expand_binop (word_mode
, add_optab
, adjust
, temp
,
859 NULL_RTX
, 0, OPTAB_DIRECT
);
861 if (target
&& !REG_P (target
))
864 /* *_widen_optab needs to determine operand mode, make sure at least
865 one operand has non-VOID mode. */
866 if (GET_MODE (op0_low
) == VOIDmode
&& GET_MODE (op1_low
) == VOIDmode
)
867 op0_low
= force_reg (word_mode
, op0_low
);
870 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
871 target
, 1, OPTAB_DIRECT
);
873 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
874 target
, 1, OPTAB_DIRECT
);
879 product_high
= operand_subword (product
, high
, 1, mode
);
880 adjust
= expand_binop (word_mode
, add_optab
, product_high
, adjust
,
881 NULL_RTX
, 0, OPTAB_DIRECT
);
882 emit_move_insn (product_high
, adjust
);
886 /* Wrapper around expand_binop which takes an rtx code to specify
887 the operation to perform, not an optab pointer. All other
888 arguments are the same. */
890 expand_simple_binop (machine_mode mode
, enum rtx_code code
, rtx op0
,
891 rtx op1
, rtx target
, int unsignedp
,
892 enum optab_methods methods
)
894 optab binop
= code_to_optab (code
);
897 return expand_binop (mode
, binop
, op0
, op1
, target
, unsignedp
, methods
);
900 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
901 binop. Order them according to commutative_operand_precedence and, if
902 possible, try to put TARGET or a pseudo first. */
904 swap_commutative_operands_with_target (rtx target
, rtx op0
, rtx op1
)
906 int op0_prec
= commutative_operand_precedence (op0
);
907 int op1_prec
= commutative_operand_precedence (op1
);
909 if (op0_prec
< op1_prec
)
912 if (op0_prec
> op1_prec
)
915 /* With equal precedence, both orders are ok, but it is better if the
916 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
917 if (target
== 0 || REG_P (target
))
918 return (REG_P (op1
) && !REG_P (op0
)) || target
== op1
;
920 return rtx_equal_p (op1
, target
);
923 /* Return true if BINOPTAB implements a shift operation. */
926 shift_optab_p (optab binoptab
)
928 switch (optab_to_code (binoptab
))
944 /* Return true if BINOPTAB implements a commutative binary operation. */
947 commutative_optab_p (optab binoptab
)
949 return (GET_RTX_CLASS (optab_to_code (binoptab
)) == RTX_COMM_ARITH
950 || binoptab
== smul_widen_optab
951 || binoptab
== umul_widen_optab
952 || binoptab
== smul_highpart_optab
953 || binoptab
== umul_highpart_optab
);
956 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
957 optimizing, and if the operand is a constant that costs more than
958 1 instruction, force the constant into a register and return that
959 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
962 avoid_expensive_constant (machine_mode mode
, optab binoptab
,
963 int opn
, rtx x
, bool unsignedp
)
965 bool speed
= optimize_insn_for_speed_p ();
970 && (rtx_cost (x
, mode
, optab_to_code (binoptab
), opn
, speed
)
971 > set_src_cost (x
, mode
, speed
)))
975 HOST_WIDE_INT intval
= trunc_int_for_mode (INTVAL (x
), mode
);
976 if (intval
!= INTVAL (x
))
977 x
= GEN_INT (intval
);
980 x
= convert_modes (mode
, VOIDmode
, x
, unsignedp
);
981 x
= force_reg (mode
, x
);
986 /* Helper function for expand_binop: handle the case where there
987 is an insn ICODE that directly implements the indicated operation.
988 Returns null if this is not possible. */
990 expand_binop_directly (enum insn_code icode
, machine_mode mode
, optab binoptab
,
992 rtx target
, int unsignedp
, enum optab_methods methods
,
995 machine_mode xmode0
= insn_data
[(int) icode
].operand
[1].mode
;
996 machine_mode xmode1
= insn_data
[(int) icode
].operand
[2].mode
;
997 machine_mode mode0
, mode1
, tmp_mode
;
998 struct expand_operand ops
[3];
1001 rtx xop0
= op0
, xop1
= op1
;
1002 bool canonicalize_op1
= false;
1004 /* If it is a commutative operator and the modes would match
1005 if we would swap the operands, we can save the conversions. */
1006 commutative_p
= commutative_optab_p (binoptab
);
1008 && GET_MODE (xop0
) != xmode0
&& GET_MODE (xop1
) != xmode1
1009 && GET_MODE (xop0
) == xmode1
&& GET_MODE (xop1
) == xmode1
)
1010 std::swap (xop0
, xop1
);
1012 /* If we are optimizing, force expensive constants into a register. */
1013 xop0
= avoid_expensive_constant (xmode0
, binoptab
, 0, xop0
, unsignedp
);
1014 if (!shift_optab_p (binoptab
))
1015 xop1
= avoid_expensive_constant (xmode1
, binoptab
, 1, xop1
, unsignedp
);
1017 /* Shifts and rotates often use a different mode for op1 from op0;
1018 for VOIDmode constants we don't know the mode, so force it
1019 to be canonicalized using convert_modes. */
1020 canonicalize_op1
= true;
1022 /* In case the insn wants input operands in modes different from
1023 those of the actual operands, convert the operands. It would
1024 seem that we don't need to convert CONST_INTs, but we do, so
1025 that they're properly zero-extended, sign-extended or truncated
1028 mode0
= GET_MODE (xop0
) != VOIDmode
? GET_MODE (xop0
) : mode
;
1029 if (xmode0
!= VOIDmode
&& xmode0
!= mode0
)
1031 xop0
= convert_modes (xmode0
, mode0
, xop0
, unsignedp
);
1035 mode1
= ((GET_MODE (xop1
) != VOIDmode
|| canonicalize_op1
)
1036 ? GET_MODE (xop1
) : mode
);
1037 if (xmode1
!= VOIDmode
&& xmode1
!= mode1
)
1039 xop1
= convert_modes (xmode1
, mode1
, xop1
, unsignedp
);
1043 /* If operation is commutative,
1044 try to make the first operand a register.
1045 Even better, try to make it the same as the target.
1046 Also try to make the last operand a constant. */
1048 && swap_commutative_operands_with_target (target
, xop0
, xop1
))
1049 std::swap (xop0
, xop1
);
1051 /* Now, if insn's predicates don't allow our operands, put them into
1054 if (binoptab
== vec_pack_trunc_optab
1055 || binoptab
== vec_pack_usat_optab
1056 || binoptab
== vec_pack_ssat_optab
1057 || binoptab
== vec_pack_ufix_trunc_optab
1058 || binoptab
== vec_pack_sfix_trunc_optab
)
1060 /* The mode of the result is different then the mode of the
1062 tmp_mode
= insn_data
[(int) icode
].operand
[0].mode
;
1063 if (VECTOR_MODE_P (mode
)
1064 && GET_MODE_NUNITS (tmp_mode
) != 2 * GET_MODE_NUNITS (mode
))
1066 delete_insns_since (last
);
1073 create_output_operand (&ops
[0], target
, tmp_mode
);
1074 create_input_operand (&ops
[1], xop0
, mode0
);
1075 create_input_operand (&ops
[2], xop1
, mode1
);
1076 pat
= maybe_gen_insn (icode
, 3, ops
);
1079 /* If PAT is composed of more than one insn, try to add an appropriate
1080 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1081 operand, call expand_binop again, this time without a target. */
1082 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
1083 && ! add_equal_note (pat
, ops
[0].value
,
1084 optab_to_code (binoptab
),
1085 ops
[1].value
, ops
[2].value
))
1087 delete_insns_since (last
);
1088 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
1089 unsignedp
, methods
);
1093 return ops
[0].value
;
1095 delete_insns_since (last
);
1099 /* Generate code to perform an operation specified by BINOPTAB
1100 on operands OP0 and OP1, with result having machine-mode MODE.
1102 UNSIGNEDP is for the case where we have to widen the operands
1103 to perform the operation. It says to use zero-extension.
1105 If TARGET is nonzero, the value
1106 is generated there, if it is convenient to do so.
1107 In all cases an rtx is returned for the locus of the value;
1108 this may or may not be TARGET. */
1111 expand_binop (machine_mode mode
, optab binoptab
, rtx op0
, rtx op1
,
1112 rtx target
, int unsignedp
, enum optab_methods methods
)
1114 enum optab_methods next_methods
1115 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
1116 ? OPTAB_WIDEN
: methods
);
1117 enum mode_class mclass
;
1118 enum insn_code icode
;
1119 machine_mode wider_mode
;
1120 scalar_int_mode int_mode
;
1123 rtx_insn
*entry_last
= get_last_insn ();
1126 mclass
= GET_MODE_CLASS (mode
);
1128 /* If subtracting an integer constant, convert this into an addition of
1129 the negated constant. */
1131 if (binoptab
== sub_optab
&& CONST_INT_P (op1
))
1133 op1
= negate_rtx (mode
, op1
);
1134 binoptab
= add_optab
;
1136 /* For shifts, constant invalid op1 might be expanded from different
1137 mode than MODE. As those are invalid, force them to a register
1138 to avoid further problems during expansion. */
1139 else if (CONST_INT_P (op1
)
1140 && shift_optab_p (binoptab
)
1141 && UINTVAL (op1
) >= GET_MODE_BITSIZE (GET_MODE_INNER (mode
)))
1143 op1
= gen_int_mode (INTVAL (op1
), GET_MODE_INNER (mode
));
1144 op1
= force_reg (GET_MODE_INNER (mode
), op1
);
1147 /* Record where to delete back to if we backtrack. */
1148 last
= get_last_insn ();
1150 /* If we can do it with a three-operand insn, do so. */
1152 if (methods
!= OPTAB_MUST_WIDEN
)
1154 if (convert_optab_p (binoptab
))
1156 machine_mode from_mode
= widened_mode (mode
, op0
, op1
);
1157 icode
= find_widening_optab_handler (binoptab
, mode
, from_mode
);
1160 icode
= optab_handler (binoptab
, mode
);
1161 if (icode
!= CODE_FOR_nothing
)
1163 temp
= expand_binop_directly (icode
, mode
, binoptab
, op0
, op1
,
1164 target
, unsignedp
, methods
, last
);
1170 /* If we were trying to rotate, and that didn't work, try rotating
1171 the other direction before falling back to shifts and bitwise-or. */
1172 if (((binoptab
== rotl_optab
1173 && (icode
= optab_handler (rotr_optab
, mode
)) != CODE_FOR_nothing
)
1174 || (binoptab
== rotr_optab
1175 && (icode
= optab_handler (rotl_optab
, mode
)) != CODE_FOR_nothing
))
1176 && is_int_mode (mode
, &int_mode
))
1178 optab otheroptab
= (binoptab
== rotl_optab
? rotr_optab
: rotl_optab
);
1180 unsigned int bits
= GET_MODE_PRECISION (int_mode
);
1182 if (CONST_INT_P (op1
))
1183 newop1
= GEN_INT (bits
- INTVAL (op1
));
1184 else if (targetm
.shift_truncation_mask (int_mode
) == bits
- 1)
1185 newop1
= negate_rtx (GET_MODE (op1
), op1
);
1187 newop1
= expand_binop (GET_MODE (op1
), sub_optab
,
1188 gen_int_mode (bits
, GET_MODE (op1
)), op1
,
1189 NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1191 temp
= expand_binop_directly (icode
, int_mode
, otheroptab
, op0
, newop1
,
1192 target
, unsignedp
, methods
, last
);
1197 /* If this is a multiply, see if we can do a widening operation that
1198 takes operands of this mode and makes a wider mode. */
1200 if (binoptab
== smul_optab
1201 && GET_MODE_2XWIDER_MODE (mode
).exists (&wider_mode
)
1202 && (convert_optab_handler ((unsignedp
1204 : smul_widen_optab
),
1205 wider_mode
, mode
) != CODE_FOR_nothing
))
1207 /* *_widen_optab needs to determine operand mode, make sure at least
1208 one operand has non-VOID mode. */
1209 if (GET_MODE (op0
) == VOIDmode
&& GET_MODE (op1
) == VOIDmode
)
1210 op0
= force_reg (mode
, op0
);
1211 temp
= expand_binop (wider_mode
,
1212 unsignedp
? umul_widen_optab
: smul_widen_optab
,
1213 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1217 if (GET_MODE_CLASS (mode
) == MODE_INT
1218 && TRULY_NOOP_TRUNCATION_MODES_P (mode
, GET_MODE (temp
)))
1219 return gen_lowpart (mode
, temp
);
1221 return convert_to_mode (mode
, temp
, unsignedp
);
1225 /* If this is a vector shift by a scalar, see if we can do a vector
1226 shift by a vector. If so, broadcast the scalar into a vector. */
1227 if (mclass
== MODE_VECTOR_INT
)
1229 optab otheroptab
= unknown_optab
;
1231 if (binoptab
== ashl_optab
)
1232 otheroptab
= vashl_optab
;
1233 else if (binoptab
== ashr_optab
)
1234 otheroptab
= vashr_optab
;
1235 else if (binoptab
== lshr_optab
)
1236 otheroptab
= vlshr_optab
;
1237 else if (binoptab
== rotl_optab
)
1238 otheroptab
= vrotl_optab
;
1239 else if (binoptab
== rotr_optab
)
1240 otheroptab
= vrotr_optab
;
1243 && (icode
= optab_handler (otheroptab
, mode
)) != CODE_FOR_nothing
)
1245 /* The scalar may have been extended to be too wide. Truncate
1246 it back to the proper size to fit in the broadcast vector. */
1247 scalar_mode inner_mode
= GET_MODE_INNER (mode
);
1248 if (!CONST_INT_P (op1
)
1249 && (GET_MODE_BITSIZE (as_a
<scalar_int_mode
> (GET_MODE (op1
)))
1250 > GET_MODE_BITSIZE (inner_mode
)))
1251 op1
= force_reg (inner_mode
,
1252 simplify_gen_unary (TRUNCATE
, inner_mode
, op1
,
1254 rtx vop1
= expand_vector_broadcast (mode
, op1
);
1257 temp
= expand_binop_directly (icode
, mode
, otheroptab
, op0
, vop1
,
1258 target
, unsignedp
, methods
, last
);
1265 /* Look for a wider mode of the same class for which we think we
1266 can open-code the operation. Check for a widening multiply at the
1267 wider mode as well. */
1269 if (CLASS_HAS_WIDER_MODES_P (mclass
)
1270 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
1271 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
1273 machine_mode next_mode
;
1274 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
1275 || (binoptab
== smul_optab
1276 && GET_MODE_WIDER_MODE (wider_mode
).exists (&next_mode
)
1277 && (find_widening_optab_handler ((unsignedp
1279 : smul_widen_optab
),
1281 != CODE_FOR_nothing
)))
1283 rtx xop0
= op0
, xop1
= op1
;
1286 /* For certain integer operations, we need not actually extend
1287 the narrow operands, as long as we will truncate
1288 the results to the same narrowness. */
1290 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1291 || binoptab
== xor_optab
1292 || binoptab
== add_optab
|| binoptab
== sub_optab
1293 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1294 && mclass
== MODE_INT
)
1297 xop0
= avoid_expensive_constant (mode
, binoptab
, 0,
1299 if (binoptab
!= ashl_optab
)
1300 xop1
= avoid_expensive_constant (mode
, binoptab
, 1,
1304 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
1306 /* The second operand of a shift must always be extended. */
1307 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1308 no_extend
&& binoptab
!= ashl_optab
);
1310 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1311 unsignedp
, OPTAB_DIRECT
);
1314 if (mclass
!= MODE_INT
1315 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
1318 target
= gen_reg_rtx (mode
);
1319 convert_move (target
, temp
, 0);
1323 return gen_lowpart (mode
, temp
);
1326 delete_insns_since (last
);
1330 /* If operation is commutative,
1331 try to make the first operand a register.
1332 Even better, try to make it the same as the target.
1333 Also try to make the last operand a constant. */
1334 if (commutative_optab_p (binoptab
)
1335 && swap_commutative_operands_with_target (target
, op0
, op1
))
1336 std::swap (op0
, op1
);
1338 /* These can be done a word at a time. */
1339 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
1340 && is_int_mode (mode
, &int_mode
)
1341 && GET_MODE_SIZE (int_mode
) > UNITS_PER_WORD
1342 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1347 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1348 won't be accurate, so use a new target. */
1352 || !valid_multiword_target_p (target
))
1353 target
= gen_reg_rtx (int_mode
);
1357 /* Do the actual arithmetic. */
1358 for (i
= 0; i
< GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
; i
++)
1360 rtx target_piece
= operand_subword (target
, i
, 1, int_mode
);
1361 rtx x
= expand_binop (word_mode
, binoptab
,
1362 operand_subword_force (op0
, i
, int_mode
),
1363 operand_subword_force (op1
, i
, int_mode
),
1364 target_piece
, unsignedp
, next_methods
);
1369 if (target_piece
!= x
)
1370 emit_move_insn (target_piece
, x
);
1373 insns
= get_insns ();
1376 if (i
== GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
)
1383 /* Synthesize double word shifts from single word shifts. */
1384 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
1385 || binoptab
== ashr_optab
)
1386 && is_int_mode (mode
, &int_mode
)
1387 && (CONST_INT_P (op1
) || optimize_insn_for_speed_p ())
1388 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
1389 && GET_MODE_PRECISION (int_mode
) == GET_MODE_BITSIZE (int_mode
)
1390 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
1391 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1392 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1394 unsigned HOST_WIDE_INT shift_mask
, double_shift_mask
;
1395 scalar_int_mode op1_mode
;
1397 double_shift_mask
= targetm
.shift_truncation_mask (int_mode
);
1398 shift_mask
= targetm
.shift_truncation_mask (word_mode
);
1399 op1_mode
= (GET_MODE (op1
) != VOIDmode
1400 ? as_a
<scalar_int_mode
> (GET_MODE (op1
))
1403 /* Apply the truncation to constant shifts. */
1404 if (double_shift_mask
> 0 && CONST_INT_P (op1
))
1405 op1
= GEN_INT (INTVAL (op1
) & double_shift_mask
);
1407 if (op1
== CONST0_RTX (op1_mode
))
1410 /* Make sure that this is a combination that expand_doubleword_shift
1411 can handle. See the comments there for details. */
1412 if (double_shift_mask
== 0
1413 || (shift_mask
== BITS_PER_WORD
- 1
1414 && double_shift_mask
== BITS_PER_WORD
* 2 - 1))
1417 rtx into_target
, outof_target
;
1418 rtx into_input
, outof_input
;
1419 int left_shift
, outof_word
;
1421 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1422 won't be accurate, so use a new target. */
1426 || !valid_multiword_target_p (target
))
1427 target
= gen_reg_rtx (int_mode
);
1431 /* OUTOF_* is the word we are shifting bits away from, and
1432 INTO_* is the word that we are shifting bits towards, thus
1433 they differ depending on the direction of the shift and
1434 WORDS_BIG_ENDIAN. */
1436 left_shift
= binoptab
== ashl_optab
;
1437 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1439 outof_target
= operand_subword (target
, outof_word
, 1, int_mode
);
1440 into_target
= operand_subword (target
, 1 - outof_word
, 1, int_mode
);
1442 outof_input
= operand_subword_force (op0
, outof_word
, int_mode
);
1443 into_input
= operand_subword_force (op0
, 1 - outof_word
, int_mode
);
1445 if (expand_doubleword_shift (op1_mode
, binoptab
,
1446 outof_input
, into_input
, op1
,
1447 outof_target
, into_target
,
1448 unsignedp
, next_methods
, shift_mask
))
1450 insns
= get_insns ();
1460 /* Synthesize double word rotates from single word shifts. */
1461 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
1462 && is_int_mode (mode
, &int_mode
)
1463 && CONST_INT_P (op1
)
1464 && GET_MODE_PRECISION (int_mode
) == 2 * BITS_PER_WORD
1465 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1466 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1469 rtx into_target
, outof_target
;
1470 rtx into_input
, outof_input
;
1472 int shift_count
, left_shift
, outof_word
;
1474 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1475 won't be accurate, so use a new target. Do this also if target is not
1476 a REG, first because having a register instead may open optimization
1477 opportunities, and second because if target and op0 happen to be MEMs
1478 designating the same location, we would risk clobbering it too early
1479 in the code sequence we generate below. */
1484 || !valid_multiword_target_p (target
))
1485 target
= gen_reg_rtx (int_mode
);
1489 shift_count
= INTVAL (op1
);
1491 /* OUTOF_* is the word we are shifting bits away from, and
1492 INTO_* is the word that we are shifting bits towards, thus
1493 they differ depending on the direction of the shift and
1494 WORDS_BIG_ENDIAN. */
1496 left_shift
= (binoptab
== rotl_optab
);
1497 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1499 outof_target
= operand_subword (target
, outof_word
, 1, int_mode
);
1500 into_target
= operand_subword (target
, 1 - outof_word
, 1, int_mode
);
1502 outof_input
= operand_subword_force (op0
, outof_word
, int_mode
);
1503 into_input
= operand_subword_force (op0
, 1 - outof_word
, int_mode
);
1505 if (shift_count
== BITS_PER_WORD
)
1507 /* This is just a word swap. */
1508 emit_move_insn (outof_target
, into_input
);
1509 emit_move_insn (into_target
, outof_input
);
1514 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1515 rtx first_shift_count
, second_shift_count
;
1516 optab reverse_unsigned_shift
, unsigned_shift
;
1518 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1519 ? lshr_optab
: ashl_optab
);
1521 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1522 ? ashl_optab
: lshr_optab
);
1524 if (shift_count
> BITS_PER_WORD
)
1526 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
1527 second_shift_count
= GEN_INT (2 * BITS_PER_WORD
- shift_count
);
1531 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
1532 second_shift_count
= GEN_INT (shift_count
);
1535 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1536 outof_input
, first_shift_count
,
1537 NULL_RTX
, unsignedp
, next_methods
);
1538 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1539 into_input
, second_shift_count
,
1540 NULL_RTX
, unsignedp
, next_methods
);
1542 if (into_temp1
!= 0 && into_temp2
!= 0)
1543 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1544 into_target
, unsignedp
, next_methods
);
1548 if (inter
!= 0 && inter
!= into_target
)
1549 emit_move_insn (into_target
, inter
);
1551 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1552 into_input
, first_shift_count
,
1553 NULL_RTX
, unsignedp
, next_methods
);
1554 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1555 outof_input
, second_shift_count
,
1556 NULL_RTX
, unsignedp
, next_methods
);
1558 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1559 inter
= expand_binop (word_mode
, ior_optab
,
1560 outof_temp1
, outof_temp2
,
1561 outof_target
, unsignedp
, next_methods
);
1563 if (inter
!= 0 && inter
!= outof_target
)
1564 emit_move_insn (outof_target
, inter
);
1567 insns
= get_insns ();
1577 /* These can be done a word at a time by propagating carries. */
1578 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1579 && is_int_mode (mode
, &int_mode
)
1580 && GET_MODE_SIZE (int_mode
) >= 2 * UNITS_PER_WORD
1581 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1584 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1585 const unsigned int nwords
= GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
;
1586 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1587 rtx xop0
, xop1
, xtarget
;
1589 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1590 value is one of those, use it. Otherwise, use 1 since it is the
1591 one easiest to get. */
1592 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1593 int normalizep
= STORE_FLAG_VALUE
;
1598 /* Prepare the operands. */
1599 xop0
= force_reg (int_mode
, op0
);
1600 xop1
= force_reg (int_mode
, op1
);
1602 xtarget
= gen_reg_rtx (int_mode
);
1604 if (target
== 0 || !REG_P (target
) || !valid_multiword_target_p (target
))
1607 /* Indicate for flow that the entire target reg is being set. */
1609 emit_clobber (xtarget
);
1611 /* Do the actual arithmetic. */
1612 for (i
= 0; i
< nwords
; i
++)
1614 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
1615 rtx target_piece
= operand_subword (xtarget
, index
, 1, int_mode
);
1616 rtx op0_piece
= operand_subword_force (xop0
, index
, int_mode
);
1617 rtx op1_piece
= operand_subword_force (xop1
, index
, int_mode
);
1620 /* Main add/subtract of the input operands. */
1621 x
= expand_binop (word_mode
, binoptab
,
1622 op0_piece
, op1_piece
,
1623 target_piece
, unsignedp
, next_methods
);
1629 /* Store carry from main add/subtract. */
1630 carry_out
= gen_reg_rtx (word_mode
);
1631 carry_out
= emit_store_flag_force (carry_out
,
1632 (binoptab
== add_optab
1635 word_mode
, 1, normalizep
);
1642 /* Add/subtract previous carry to main result. */
1643 newx
= expand_binop (word_mode
,
1644 normalizep
== 1 ? binoptab
: otheroptab
,
1646 NULL_RTX
, 1, next_methods
);
1650 /* Get out carry from adding/subtracting carry in. */
1651 rtx carry_tmp
= gen_reg_rtx (word_mode
);
1652 carry_tmp
= emit_store_flag_force (carry_tmp
,
1653 (binoptab
== add_optab
1656 word_mode
, 1, normalizep
);
1658 /* Logical-ior the two poss. carry together. */
1659 carry_out
= expand_binop (word_mode
, ior_optab
,
1660 carry_out
, carry_tmp
,
1661 carry_out
, 0, next_methods
);
1665 emit_move_insn (target_piece
, newx
);
1669 if (x
!= target_piece
)
1670 emit_move_insn (target_piece
, x
);
1673 carry_in
= carry_out
;
1676 if (i
== GET_MODE_BITSIZE (int_mode
) / (unsigned) BITS_PER_WORD
)
1678 if (optab_handler (mov_optab
, int_mode
) != CODE_FOR_nothing
1679 || ! rtx_equal_p (target
, xtarget
))
1681 rtx_insn
*temp
= emit_move_insn (target
, xtarget
);
1683 set_dst_reg_note (temp
, REG_EQUAL
,
1684 gen_rtx_fmt_ee (optab_to_code (binoptab
),
1685 int_mode
, copy_rtx (xop0
),
1696 delete_insns_since (last
);
1699 /* Attempt to synthesize double word multiplies using a sequence of word
1700 mode multiplications. We first attempt to generate a sequence using a
1701 more efficient unsigned widening multiply, and if that fails we then
1702 try using a signed widening multiply. */
1704 if (binoptab
== smul_optab
1705 && is_int_mode (mode
, &int_mode
)
1706 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
1707 && optab_handler (smul_optab
, word_mode
) != CODE_FOR_nothing
1708 && optab_handler (add_optab
, word_mode
) != CODE_FOR_nothing
)
1710 rtx product
= NULL_RTX
;
1711 if (convert_optab_handler (umul_widen_optab
, int_mode
, word_mode
)
1712 != CODE_FOR_nothing
)
1714 product
= expand_doubleword_mult (int_mode
, op0
, op1
, target
,
1717 delete_insns_since (last
);
1720 if (product
== NULL_RTX
1721 && (convert_optab_handler (smul_widen_optab
, int_mode
, word_mode
)
1722 != CODE_FOR_nothing
))
1724 product
= expand_doubleword_mult (int_mode
, op0
, op1
, target
,
1727 delete_insns_since (last
);
1730 if (product
!= NULL_RTX
)
1732 if (optab_handler (mov_optab
, int_mode
) != CODE_FOR_nothing
)
1734 rtx_insn
*move
= emit_move_insn (target
? target
: product
,
1736 set_dst_reg_note (move
,
1738 gen_rtx_fmt_ee (MULT
, int_mode
,
1741 target
? target
: product
);
1747 /* It can't be open-coded in this mode.
1748 Use a library call if one is available and caller says that's ok. */
1750 libfunc
= optab_libfunc (binoptab
, mode
);
1752 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1756 machine_mode op1_mode
= mode
;
1761 if (shift_optab_p (binoptab
))
1763 op1_mode
= targetm
.libgcc_shift_count_mode ();
1764 /* Specify unsigned here,
1765 since negative shift counts are meaningless. */
1766 op1x
= convert_to_mode (op1_mode
, op1
, 1);
1769 if (GET_MODE (op0
) != VOIDmode
1770 && GET_MODE (op0
) != mode
)
1771 op0
= convert_to_mode (mode
, op0
, unsignedp
);
1773 /* Pass 1 for NO_QUEUE so we don't lose any increments
1774 if the libcall is cse'd or moved. */
1775 value
= emit_library_call_value (libfunc
,
1776 NULL_RTX
, LCT_CONST
, mode
,
1777 op0
, mode
, op1x
, op1_mode
);
1779 insns
= get_insns ();
1782 bool trapv
= trapv_binoptab_p (binoptab
);
1783 target
= gen_reg_rtx (mode
);
1784 emit_libcall_block_1 (insns
, target
, value
,
1786 : gen_rtx_fmt_ee (optab_to_code (binoptab
),
1787 mode
, op0
, op1
), trapv
);
1792 delete_insns_since (last
);
1794 /* It can't be done in this mode. Can we do it in a wider mode? */
1796 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1797 || methods
== OPTAB_MUST_WIDEN
))
1799 /* Caller says, don't even try. */
1800 delete_insns_since (entry_last
);
1804 /* Compute the value of METHODS to pass to recursive calls.
1805 Don't allow widening to be tried recursively. */
1807 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1809 /* Look for a wider mode of the same class for which it appears we can do
1812 if (CLASS_HAS_WIDER_MODES_P (mclass
))
1814 /* This code doesn't make sense for conversion optabs, since we
1815 wouldn't then want to extend the operands to be the same size
1817 gcc_assert (!convert_optab_p (binoptab
));
1818 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
1820 if (optab_handler (binoptab
, wider_mode
)
1821 || (methods
== OPTAB_LIB
1822 && optab_libfunc (binoptab
, wider_mode
)))
1824 rtx xop0
= op0
, xop1
= op1
;
1827 /* For certain integer operations, we need not actually extend
1828 the narrow operands, as long as we will truncate
1829 the results to the same narrowness. */
1831 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1832 || binoptab
== xor_optab
1833 || binoptab
== add_optab
|| binoptab
== sub_optab
1834 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1835 && mclass
== MODE_INT
)
1838 xop0
= widen_operand (xop0
, wider_mode
, mode
,
1839 unsignedp
, no_extend
);
1841 /* The second operand of a shift must always be extended. */
1842 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1843 no_extend
&& binoptab
!= ashl_optab
);
1845 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1846 unsignedp
, methods
);
1849 if (mclass
!= MODE_INT
1850 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
1853 target
= gen_reg_rtx (mode
);
1854 convert_move (target
, temp
, 0);
1858 return gen_lowpart (mode
, temp
);
1861 delete_insns_since (last
);
1866 delete_insns_since (entry_last
);
1870 /* Expand a binary operator which has both signed and unsigned forms.
1871 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1874 If we widen unsigned operands, we may use a signed wider operation instead
1875 of an unsigned wider operation, since the result would be the same. */
1878 sign_expand_binop (machine_mode mode
, optab uoptab
, optab soptab
,
1879 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
1880 enum optab_methods methods
)
1883 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1886 /* Do it without widening, if possible. */
1887 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1888 unsignedp
, OPTAB_DIRECT
);
1889 if (temp
|| methods
== OPTAB_DIRECT
)
1892 /* Try widening to a signed int. Disable any direct use of any
1893 signed insn in the current mode. */
1894 save_enable
= swap_optab_enable (soptab
, mode
, false);
1896 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
1897 unsignedp
, OPTAB_WIDEN
);
1899 /* For unsigned operands, try widening to an unsigned int. */
1900 if (!temp
&& unsignedp
)
1901 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1902 unsignedp
, OPTAB_WIDEN
);
1903 if (temp
|| methods
== OPTAB_WIDEN
)
1906 /* Use the right width libcall if that exists. */
1907 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1908 unsignedp
, OPTAB_LIB
);
1909 if (temp
|| methods
== OPTAB_LIB
)
1912 /* Must widen and use a libcall, use either signed or unsigned. */
1913 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
1914 unsignedp
, methods
);
1915 if (!temp
&& unsignedp
)
1916 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1917 unsignedp
, methods
);
1920 /* Undo the fiddling above. */
1922 swap_optab_enable (soptab
, mode
, true);
1926 /* Generate code to perform an operation specified by UNOPPTAB
1927 on operand OP0, with two results to TARG0 and TARG1.
1928 We assume that the order of the operands for the instruction
1929 is TARG0, TARG1, OP0.
1931 Either TARG0 or TARG1 may be zero, but what that means is that
1932 the result is not actually wanted. We will generate it into
1933 a dummy pseudo-reg and discard it. They may not both be zero.
1935 Returns 1 if this operation can be performed; 0 if not. */
1938 expand_twoval_unop (optab unoptab
, rtx op0
, rtx targ0
, rtx targ1
,
1941 machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1942 enum mode_class mclass
;
1943 machine_mode wider_mode
;
1944 rtx_insn
*entry_last
= get_last_insn ();
1947 mclass
= GET_MODE_CLASS (mode
);
1950 targ0
= gen_reg_rtx (mode
);
1952 targ1
= gen_reg_rtx (mode
);
1954 /* Record where to go back to if we fail. */
1955 last
= get_last_insn ();
1957 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
1959 struct expand_operand ops
[3];
1960 enum insn_code icode
= optab_handler (unoptab
, mode
);
1962 create_fixed_operand (&ops
[0], targ0
);
1963 create_fixed_operand (&ops
[1], targ1
);
1964 create_convert_operand_from (&ops
[2], op0
, mode
, unsignedp
);
1965 if (maybe_expand_insn (icode
, 3, ops
))
1969 /* It can't be done in this mode. Can we do it in a wider mode? */
1971 if (CLASS_HAS_WIDER_MODES_P (mclass
))
1973 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
1975 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
1977 rtx t0
= gen_reg_rtx (wider_mode
);
1978 rtx t1
= gen_reg_rtx (wider_mode
);
1979 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
1981 if (expand_twoval_unop (unoptab
, cop0
, t0
, t1
, unsignedp
))
1983 convert_move (targ0
, t0
, unsignedp
);
1984 convert_move (targ1
, t1
, unsignedp
);
1988 delete_insns_since (last
);
1993 delete_insns_since (entry_last
);
1997 /* Generate code to perform an operation specified by BINOPTAB
1998 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1999 We assume that the order of the operands for the instruction
2000 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2001 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2003 Either TARG0 or TARG1 may be zero, but what that means is that
2004 the result is not actually wanted. We will generate it into
2005 a dummy pseudo-reg and discard it. They may not both be zero.
2007 Returns 1 if this operation can be performed; 0 if not. */
2010 expand_twoval_binop (optab binoptab
, rtx op0
, rtx op1
, rtx targ0
, rtx targ1
,
2013 machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2014 enum mode_class mclass
;
2015 machine_mode wider_mode
;
2016 rtx_insn
*entry_last
= get_last_insn ();
2019 mclass
= GET_MODE_CLASS (mode
);
2022 targ0
= gen_reg_rtx (mode
);
2024 targ1
= gen_reg_rtx (mode
);
2026 /* Record where to go back to if we fail. */
2027 last
= get_last_insn ();
2029 if (optab_handler (binoptab
, mode
) != CODE_FOR_nothing
)
2031 struct expand_operand ops
[4];
2032 enum insn_code icode
= optab_handler (binoptab
, mode
);
2033 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2034 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2035 rtx xop0
= op0
, xop1
= op1
;
2037 /* If we are optimizing, force expensive constants into a register. */
2038 xop0
= avoid_expensive_constant (mode0
, binoptab
, 0, xop0
, unsignedp
);
2039 xop1
= avoid_expensive_constant (mode1
, binoptab
, 1, xop1
, unsignedp
);
2041 create_fixed_operand (&ops
[0], targ0
);
2042 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
2043 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
2044 create_fixed_operand (&ops
[3], targ1
);
2045 if (maybe_expand_insn (icode
, 4, ops
))
2047 delete_insns_since (last
);
2050 /* It can't be done in this mode. Can we do it in a wider mode? */
2052 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2054 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
2056 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
)
2058 rtx t0
= gen_reg_rtx (wider_mode
);
2059 rtx t1
= gen_reg_rtx (wider_mode
);
2060 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2061 rtx cop1
= convert_modes (wider_mode
, mode
, op1
, unsignedp
);
2063 if (expand_twoval_binop (binoptab
, cop0
, cop1
,
2066 convert_move (targ0
, t0
, unsignedp
);
2067 convert_move (targ1
, t1
, unsignedp
);
2071 delete_insns_since (last
);
2076 delete_insns_since (entry_last
);
2080 /* Expand the two-valued library call indicated by BINOPTAB, but
2081 preserve only one of the values. If TARG0 is non-NULL, the first
2082 value is placed into TARG0; otherwise the second value is placed
2083 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2084 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2085 This routine assumes that the value returned by the library call is
2086 as if the return value was of an integral mode twice as wide as the
2087 mode of OP0. Returns 1 if the call was successful. */
2090 expand_twoval_binop_libfunc (optab binoptab
, rtx op0
, rtx op1
,
2091 rtx targ0
, rtx targ1
, enum rtx_code code
)
2094 machine_mode libval_mode
;
2099 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2100 gcc_assert (!targ0
!= !targ1
);
2102 mode
= GET_MODE (op0
);
2103 libfunc
= optab_libfunc (binoptab
, mode
);
2107 /* The value returned by the library function will have twice as
2108 many bits as the nominal MODE. */
2109 libval_mode
= smallest_int_mode_for_size (2 * GET_MODE_BITSIZE (mode
));
2111 libval
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
2115 /* Get the part of VAL containing the value that we want. */
2116 libval
= simplify_gen_subreg (mode
, libval
, libval_mode
,
2117 targ0
? 0 : GET_MODE_SIZE (mode
));
2118 insns
= get_insns ();
2120 /* Move the into the desired location. */
2121 emit_libcall_block (insns
, targ0
? targ0
: targ1
, libval
,
2122 gen_rtx_fmt_ee (code
, mode
, op0
, op1
));
2128 /* Wrapper around expand_unop which takes an rtx code to specify
2129 the operation to perform, not an optab pointer. All other
2130 arguments are the same. */
2132 expand_simple_unop (machine_mode mode
, enum rtx_code code
, rtx op0
,
2133 rtx target
, int unsignedp
)
2135 optab unop
= code_to_optab (code
);
2138 return expand_unop (mode
, unop
, op0
, target
, unsignedp
);
2144 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2146 A similar operation can be used for clrsb. UNOPTAB says which operation
2147 we are trying to expand. */
2149 widen_leading (scalar_int_mode mode
, rtx op0
, rtx target
, optab unoptab
)
2151 opt_scalar_int_mode wider_mode_iter
;
2152 FOR_EACH_WIDER_MODE (wider_mode_iter
, mode
)
2154 scalar_int_mode wider_mode
= wider_mode_iter
.require ();
2155 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2160 last
= get_last_insn ();
2163 target
= gen_reg_rtx (mode
);
2164 xop0
= widen_operand (op0
, wider_mode
, mode
,
2165 unoptab
!= clrsb_optab
, false);
2166 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2167 unoptab
!= clrsb_optab
);
2170 (wider_mode
, sub_optab
, temp
,
2171 gen_int_mode (GET_MODE_PRECISION (wider_mode
)
2172 - GET_MODE_PRECISION (mode
),
2174 target
, true, OPTAB_DIRECT
);
2176 delete_insns_since (last
);
2184 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2185 quantities, choosing which based on whether the high word is nonzero. */
2187 expand_doubleword_clz (scalar_int_mode mode
, rtx op0
, rtx target
)
2189 rtx xop0
= force_reg (mode
, op0
);
2190 rtx subhi
= gen_highpart (word_mode
, xop0
);
2191 rtx sublo
= gen_lowpart (word_mode
, xop0
);
2192 rtx_code_label
*hi0_label
= gen_label_rtx ();
2193 rtx_code_label
*after_label
= gen_label_rtx ();
2197 /* If we were not given a target, use a word_mode register, not a
2198 'mode' register. The result will fit, and nobody is expecting
2199 anything bigger (the return type of __builtin_clz* is int). */
2201 target
= gen_reg_rtx (word_mode
);
2203 /* In any case, write to a word_mode scratch in both branches of the
2204 conditional, so we can ensure there is a single move insn setting
2205 'target' to tag a REG_EQUAL note on. */
2206 result
= gen_reg_rtx (word_mode
);
2210 /* If the high word is not equal to zero,
2211 then clz of the full value is clz of the high word. */
2212 emit_cmp_and_jump_insns (subhi
, CONST0_RTX (word_mode
), EQ
, 0,
2213 word_mode
, true, hi0_label
);
2215 temp
= expand_unop_direct (word_mode
, clz_optab
, subhi
, result
, true);
2220 convert_move (result
, temp
, true);
2222 emit_jump_insn (targetm
.gen_jump (after_label
));
2225 /* Else clz of the full value is clz of the low word plus the number
2226 of bits in the high word. */
2227 emit_label (hi0_label
);
2229 temp
= expand_unop_direct (word_mode
, clz_optab
, sublo
, 0, true);
2232 temp
= expand_binop (word_mode
, add_optab
, temp
,
2233 gen_int_mode (GET_MODE_BITSIZE (word_mode
), word_mode
),
2234 result
, true, OPTAB_DIRECT
);
2238 convert_move (result
, temp
, true);
2240 emit_label (after_label
);
2241 convert_move (target
, result
, true);
2246 add_equal_note (seq
, target
, CLZ
, xop0
, 0);
2255 /* Try calculating popcount of a double-word quantity as two popcount's of
2256 word-sized quantities and summing up the results. */
2258 expand_doubleword_popcount (scalar_int_mode mode
, rtx op0
, rtx target
)
2265 t0
= expand_unop_direct (word_mode
, popcount_optab
,
2266 operand_subword_force (op0
, 0, mode
), NULL_RTX
,
2268 t1
= expand_unop_direct (word_mode
, popcount_optab
,
2269 operand_subword_force (op0
, 1, mode
), NULL_RTX
,
2277 /* If we were not given a target, use a word_mode register, not a
2278 'mode' register. The result will fit, and nobody is expecting
2279 anything bigger (the return type of __builtin_popcount* is int). */
2281 target
= gen_reg_rtx (word_mode
);
2283 t
= expand_binop (word_mode
, add_optab
, t0
, t1
, target
, 0, OPTAB_DIRECT
);
2288 add_equal_note (seq
, t
, POPCOUNT
, op0
, 0);
2296 (parity:narrow (low (x) ^ high (x))) */
2298 expand_doubleword_parity (scalar_int_mode mode
, rtx op0
, rtx target
)
2300 rtx t
= expand_binop (word_mode
, xor_optab
,
2301 operand_subword_force (op0
, 0, mode
),
2302 operand_subword_force (op0
, 1, mode
),
2303 NULL_RTX
, 0, OPTAB_DIRECT
);
2304 return expand_unop (word_mode
, parity_optab
, t
, target
, true);
2310 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2312 widen_bswap (scalar_int_mode mode
, rtx op0
, rtx target
)
2316 opt_scalar_int_mode wider_mode_iter
;
2318 FOR_EACH_WIDER_MODE (wider_mode_iter
, mode
)
2319 if (optab_handler (bswap_optab
, wider_mode_iter
.require ())
2320 != CODE_FOR_nothing
)
2323 if (!wider_mode_iter
.exists ())
2326 scalar_int_mode wider_mode
= wider_mode_iter
.require ();
2327 last
= get_last_insn ();
2329 x
= widen_operand (op0
, wider_mode
, mode
, true, true);
2330 x
= expand_unop (wider_mode
, bswap_optab
, x
, NULL_RTX
, true);
2332 gcc_assert (GET_MODE_PRECISION (wider_mode
) == GET_MODE_BITSIZE (wider_mode
)
2333 && GET_MODE_PRECISION (mode
) == GET_MODE_BITSIZE (mode
));
2335 x
= expand_shift (RSHIFT_EXPR
, wider_mode
, x
,
2336 GET_MODE_BITSIZE (wider_mode
)
2337 - GET_MODE_BITSIZE (mode
),
2343 target
= gen_reg_rtx (mode
);
2344 emit_move_insn (target
, gen_lowpart (mode
, x
));
2347 delete_insns_since (last
);
2352 /* Try calculating bswap as two bswaps of two word-sized operands. */
2355 expand_doubleword_bswap (machine_mode mode
, rtx op
, rtx target
)
2359 t1
= expand_unop (word_mode
, bswap_optab
,
2360 operand_subword_force (op
, 0, mode
), NULL_RTX
, true);
2361 t0
= expand_unop (word_mode
, bswap_optab
,
2362 operand_subword_force (op
, 1, mode
), NULL_RTX
, true);
2364 if (target
== 0 || !valid_multiword_target_p (target
))
2365 target
= gen_reg_rtx (mode
);
2367 emit_clobber (target
);
2368 emit_move_insn (operand_subword (target
, 0, 1, mode
), t0
);
2369 emit_move_insn (operand_subword (target
, 1, 1, mode
), t1
);
2374 /* Try calculating (parity x) as (and (popcount x) 1), where
2375 popcount can also be done in a wider mode. */
2377 expand_parity (scalar_int_mode mode
, rtx op0
, rtx target
)
2379 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2380 opt_scalar_int_mode wider_mode_iter
;
2381 FOR_EACH_MODE_FROM (wider_mode_iter
, mode
)
2383 scalar_int_mode wider_mode
= wider_mode_iter
.require ();
2384 if (optab_handler (popcount_optab
, wider_mode
) != CODE_FOR_nothing
)
2389 last
= get_last_insn ();
2391 if (target
== 0 || GET_MODE (target
) != wider_mode
)
2392 target
= gen_reg_rtx (wider_mode
);
2394 xop0
= widen_operand (op0
, wider_mode
, mode
, true, false);
2395 temp
= expand_unop (wider_mode
, popcount_optab
, xop0
, NULL_RTX
,
2398 temp
= expand_binop (wider_mode
, and_optab
, temp
, const1_rtx
,
2399 target
, true, OPTAB_DIRECT
);
2403 if (mclass
!= MODE_INT
2404 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
2405 return convert_to_mode (mode
, temp
, 0);
2407 return gen_lowpart (mode
, temp
);
2410 delete_insns_since (last
);
2416 /* Try calculating ctz(x) as K - clz(x & -x) ,
2417 where K is GET_MODE_PRECISION(mode) - 1.
2419 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2420 don't have to worry about what the hardware does in that case. (If
2421 the clz instruction produces the usual value at 0, which is K, the
2422 result of this code sequence will be -1; expand_ffs, below, relies
2423 on this. It might be nice to have it be K instead, for consistency
2424 with the (very few) processors that provide a ctz with a defined
2425 value, but that would take one more instruction, and it would be
2426 less convenient for expand_ffs anyway. */
2429 expand_ctz (scalar_int_mode mode
, rtx op0
, rtx target
)
2434 if (optab_handler (clz_optab
, mode
) == CODE_FOR_nothing
)
2439 temp
= expand_unop_direct (mode
, neg_optab
, op0
, NULL_RTX
, true);
2441 temp
= expand_binop (mode
, and_optab
, op0
, temp
, NULL_RTX
,
2442 true, OPTAB_DIRECT
);
2444 temp
= expand_unop_direct (mode
, clz_optab
, temp
, NULL_RTX
, true);
2446 temp
= expand_binop (mode
, sub_optab
,
2447 gen_int_mode (GET_MODE_PRECISION (mode
) - 1, mode
),
2449 true, OPTAB_DIRECT
);
2459 add_equal_note (seq
, temp
, CTZ
, op0
, 0);
2465 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2466 else with the sequence used by expand_clz.
2468 The ffs builtin promises to return zero for a zero value and ctz/clz
2469 may have an undefined value in that case. If they do not give us a
2470 convenient value, we have to generate a test and branch. */
2472 expand_ffs (scalar_int_mode mode
, rtx op0
, rtx target
)
2474 HOST_WIDE_INT val
= 0;
2475 bool defined_at_zero
= false;
2479 if (optab_handler (ctz_optab
, mode
) != CODE_FOR_nothing
)
2483 temp
= expand_unop_direct (mode
, ctz_optab
, op0
, 0, true);
2487 defined_at_zero
= (CTZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2);
2489 else if (optab_handler (clz_optab
, mode
) != CODE_FOR_nothing
)
2492 temp
= expand_ctz (mode
, op0
, 0);
2496 if (CLZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2)
2498 defined_at_zero
= true;
2499 val
= (GET_MODE_PRECISION (mode
) - 1) - val
;
2505 if (defined_at_zero
&& val
== -1)
2506 /* No correction needed at zero. */;
2509 /* We don't try to do anything clever with the situation found
2510 on some processors (eg Alpha) where ctz(0:mode) ==
2511 bitsize(mode). If someone can think of a way to send N to -1
2512 and leave alone all values in the range 0..N-1 (where N is a
2513 power of two), cheaper than this test-and-branch, please add it.
2515 The test-and-branch is done after the operation itself, in case
2516 the operation sets condition codes that can be recycled for this.
2517 (This is true on i386, for instance.) */
2519 rtx_code_label
*nonzero_label
= gen_label_rtx ();
2520 emit_cmp_and_jump_insns (op0
, CONST0_RTX (mode
), NE
, 0,
2521 mode
, true, nonzero_label
);
2523 convert_move (temp
, GEN_INT (-1), false);
2524 emit_label (nonzero_label
);
2527 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2528 to produce a value in the range 0..bitsize. */
2529 temp
= expand_binop (mode
, add_optab
, temp
, gen_int_mode (1, mode
),
2530 target
, false, OPTAB_DIRECT
);
2537 add_equal_note (seq
, temp
, FFS
, op0
, 0);
2546 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2547 conditions, VAL may already be a SUBREG against which we cannot generate
2548 a further SUBREG. In this case, we expect forcing the value into a
2549 register will work around the situation. */
2552 lowpart_subreg_maybe_copy (machine_mode omode
, rtx val
,
2556 ret
= lowpart_subreg (omode
, val
, imode
);
2559 val
= force_reg (imode
, val
);
2560 ret
= lowpart_subreg (omode
, val
, imode
);
2561 gcc_assert (ret
!= NULL
);
2566 /* Expand a floating point absolute value or negation operation via a
2567 logical operation on the sign bit. */
2570 expand_absneg_bit (enum rtx_code code
, scalar_float_mode mode
,
2571 rtx op0
, rtx target
)
2573 const struct real_format
*fmt
;
2574 int bitpos
, word
, nwords
, i
;
2575 scalar_int_mode imode
;
2579 /* The format has to have a simple sign bit. */
2580 fmt
= REAL_MODE_FORMAT (mode
);
2584 bitpos
= fmt
->signbit_rw
;
2588 /* Don't create negative zeros if the format doesn't support them. */
2589 if (code
== NEG
&& !fmt
->has_signed_zero
)
2592 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
2594 if (!int_mode_for_mode (mode
).exists (&imode
))
2603 if (FLOAT_WORDS_BIG_ENDIAN
)
2604 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
2606 word
= bitpos
/ BITS_PER_WORD
;
2607 bitpos
= bitpos
% BITS_PER_WORD
;
2608 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
2611 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
2617 || (nwords
> 1 && !valid_multiword_target_p (target
)))
2618 target
= gen_reg_rtx (mode
);
2624 for (i
= 0; i
< nwords
; ++i
)
2626 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
2627 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
2631 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2633 immed_wide_int_const (mask
, imode
),
2634 targ_piece
, 1, OPTAB_LIB_WIDEN
);
2635 if (temp
!= targ_piece
)
2636 emit_move_insn (targ_piece
, temp
);
2639 emit_move_insn (targ_piece
, op0_piece
);
2642 insns
= get_insns ();
2649 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2650 gen_lowpart (imode
, op0
),
2651 immed_wide_int_const (mask
, imode
),
2652 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
2653 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
2655 set_dst_reg_note (get_last_insn (), REG_EQUAL
,
2656 gen_rtx_fmt_e (code
, mode
, copy_rtx (op0
)),
2663 /* As expand_unop, but will fail rather than attempt the operation in a
2664 different mode or with a libcall. */
2666 expand_unop_direct (machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
2669 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
2671 struct expand_operand ops
[2];
2672 enum insn_code icode
= optab_handler (unoptab
, mode
);
2673 rtx_insn
*last
= get_last_insn ();
2676 create_output_operand (&ops
[0], target
, mode
);
2677 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
2678 pat
= maybe_gen_insn (icode
, 2, ops
);
2681 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
2682 && ! add_equal_note (pat
, ops
[0].value
,
2683 optab_to_code (unoptab
),
2684 ops
[1].value
, NULL_RTX
))
2686 delete_insns_since (last
);
2687 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
2692 return ops
[0].value
;
2698 /* Generate code to perform an operation specified by UNOPTAB
2699 on operand OP0, with result having machine-mode MODE.
2701 UNSIGNEDP is for the case where we have to widen the operands
2702 to perform the operation. It says to use zero-extension.
2704 If TARGET is nonzero, the value
2705 is generated there, if it is convenient to do so.
2706 In all cases an rtx is returned for the locus of the value;
2707 this may or may not be TARGET. */
2710 expand_unop (machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
2713 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2714 machine_mode wider_mode
;
2715 scalar_int_mode int_mode
;
2716 scalar_float_mode float_mode
;
2720 temp
= expand_unop_direct (mode
, unoptab
, op0
, target
, unsignedp
);
2724 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2726 /* Widening (or narrowing) clz needs special treatment. */
2727 if (unoptab
== clz_optab
)
2729 if (is_a
<scalar_int_mode
> (mode
, &int_mode
))
2731 temp
= widen_leading (int_mode
, op0
, target
, unoptab
);
2735 if (GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
2736 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
2738 temp
= expand_doubleword_clz (int_mode
, op0
, target
);
2747 if (unoptab
== clrsb_optab
)
2749 if (is_a
<scalar_int_mode
> (mode
, &int_mode
))
2751 temp
= widen_leading (int_mode
, op0
, target
, unoptab
);
2758 if (unoptab
== popcount_optab
2759 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
2760 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
2761 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
2762 && optimize_insn_for_speed_p ())
2764 temp
= expand_doubleword_popcount (int_mode
, op0
, target
);
2769 if (unoptab
== parity_optab
2770 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
2771 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
2772 && (optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
2773 || optab_handler (popcount_optab
, word_mode
) != CODE_FOR_nothing
)
2774 && optimize_insn_for_speed_p ())
2776 temp
= expand_doubleword_parity (int_mode
, op0
, target
);
2781 /* Widening (or narrowing) bswap needs special treatment. */
2782 if (unoptab
== bswap_optab
)
2784 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
2785 or ROTATERT. First try these directly; if this fails, then try the
2786 obvious pair of shifts with allowed widening, as this will probably
2787 be always more efficient than the other fallback methods. */
2793 if (optab_handler (rotl_optab
, mode
) != CODE_FOR_nothing
)
2795 temp
= expand_binop (mode
, rotl_optab
, op0
, GEN_INT (8), target
,
2796 unsignedp
, OPTAB_DIRECT
);
2801 if (optab_handler (rotr_optab
, mode
) != CODE_FOR_nothing
)
2803 temp
= expand_binop (mode
, rotr_optab
, op0
, GEN_INT (8), target
,
2804 unsignedp
, OPTAB_DIRECT
);
2809 last
= get_last_insn ();
2811 temp1
= expand_binop (mode
, ashl_optab
, op0
, GEN_INT (8), NULL_RTX
,
2812 unsignedp
, OPTAB_WIDEN
);
2813 temp2
= expand_binop (mode
, lshr_optab
, op0
, GEN_INT (8), NULL_RTX
,
2814 unsignedp
, OPTAB_WIDEN
);
2817 temp
= expand_binop (mode
, ior_optab
, temp1
, temp2
, target
,
2818 unsignedp
, OPTAB_WIDEN
);
2823 delete_insns_since (last
);
2826 if (is_a
<scalar_int_mode
> (mode
, &int_mode
))
2828 temp
= widen_bswap (int_mode
, op0
, target
);
2832 if (GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
2833 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
2835 temp
= expand_doubleword_bswap (mode
, op0
, target
);
2844 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2845 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
2847 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2850 rtx_insn
*last
= get_last_insn ();
2852 /* For certain operations, we need not actually extend
2853 the narrow operand, as long as we will truncate the
2854 results to the same narrowness. */
2856 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2857 (unoptab
== neg_optab
2858 || unoptab
== one_cmpl_optab
)
2859 && mclass
== MODE_INT
);
2861 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2866 if (mclass
!= MODE_INT
2867 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
2870 target
= gen_reg_rtx (mode
);
2871 convert_move (target
, temp
, 0);
2875 return gen_lowpart (mode
, temp
);
2878 delete_insns_since (last
);
2882 /* These can be done a word at a time. */
2883 if (unoptab
== one_cmpl_optab
2884 && is_int_mode (mode
, &int_mode
)
2885 && GET_MODE_SIZE (int_mode
) > UNITS_PER_WORD
2886 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
2891 if (target
== 0 || target
== op0
|| !valid_multiword_target_p (target
))
2892 target
= gen_reg_rtx (int_mode
);
2896 /* Do the actual arithmetic. */
2897 for (i
= 0; i
< GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
; i
++)
2899 rtx target_piece
= operand_subword (target
, i
, 1, int_mode
);
2900 rtx x
= expand_unop (word_mode
, unoptab
,
2901 operand_subword_force (op0
, i
, int_mode
),
2902 target_piece
, unsignedp
);
2904 if (target_piece
!= x
)
2905 emit_move_insn (target_piece
, x
);
2908 insns
= get_insns ();
2915 if (optab_to_code (unoptab
) == NEG
)
2917 /* Try negating floating point values by flipping the sign bit. */
2918 if (is_a
<scalar_float_mode
> (mode
, &float_mode
))
2920 temp
= expand_absneg_bit (NEG
, float_mode
, op0
, target
);
2925 /* If there is no negation pattern, and we have no negative zero,
2926 try subtracting from zero. */
2927 if (!HONOR_SIGNED_ZEROS (mode
))
2929 temp
= expand_binop (mode
, (unoptab
== negv_optab
2930 ? subv_optab
: sub_optab
),
2931 CONST0_RTX (mode
), op0
, target
,
2932 unsignedp
, OPTAB_DIRECT
);
2938 /* Try calculating parity (x) as popcount (x) % 2. */
2939 if (unoptab
== parity_optab
&& is_a
<scalar_int_mode
> (mode
, &int_mode
))
2941 temp
= expand_parity (int_mode
, op0
, target
);
2946 /* Try implementing ffs (x) in terms of clz (x). */
2947 if (unoptab
== ffs_optab
&& is_a
<scalar_int_mode
> (mode
, &int_mode
))
2949 temp
= expand_ffs (int_mode
, op0
, target
);
2954 /* Try implementing ctz (x) in terms of clz (x). */
2955 if (unoptab
== ctz_optab
&& is_a
<scalar_int_mode
> (mode
, &int_mode
))
2957 temp
= expand_ctz (int_mode
, op0
, target
);
2963 /* Now try a library call in this mode. */
2964 libfunc
= optab_libfunc (unoptab
, mode
);
2970 machine_mode outmode
= mode
;
2972 /* All of these functions return small values. Thus we choose to
2973 have them return something that isn't a double-word. */
2974 if (unoptab
== ffs_optab
|| unoptab
== clz_optab
|| unoptab
== ctz_optab
2975 || unoptab
== clrsb_optab
|| unoptab
== popcount_optab
2976 || unoptab
== parity_optab
)
2978 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node
),
2979 optab_libfunc (unoptab
, mode
)));
2983 /* Pass 1 for NO_QUEUE so we don't lose any increments
2984 if the libcall is cse'd or moved. */
2985 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, outmode
,
2987 insns
= get_insns ();
2990 target
= gen_reg_rtx (outmode
);
2991 bool trapv
= trapv_unoptab_p (unoptab
);
2993 eq_value
= NULL_RTX
;
2996 eq_value
= gen_rtx_fmt_e (optab_to_code (unoptab
), mode
, op0
);
2997 if (GET_MODE_UNIT_SIZE (outmode
) < GET_MODE_UNIT_SIZE (mode
))
2998 eq_value
= simplify_gen_unary (TRUNCATE
, outmode
, eq_value
, mode
);
2999 else if (GET_MODE_UNIT_SIZE (outmode
) > GET_MODE_UNIT_SIZE (mode
))
3000 eq_value
= simplify_gen_unary (ZERO_EXTEND
,
3001 outmode
, eq_value
, mode
);
3003 emit_libcall_block_1 (insns
, target
, value
, eq_value
, trapv
);
3008 /* It can't be done in this mode. Can we do it in a wider mode? */
3010 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3012 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
3014 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
3015 || optab_libfunc (unoptab
, wider_mode
))
3018 rtx_insn
*last
= get_last_insn ();
3020 /* For certain operations, we need not actually extend
3021 the narrow operand, as long as we will truncate the
3022 results to the same narrowness. */
3023 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3024 (unoptab
== neg_optab
3025 || unoptab
== one_cmpl_optab
3026 || unoptab
== bswap_optab
)
3027 && mclass
== MODE_INT
);
3029 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3032 /* If we are generating clz using wider mode, adjust the
3033 result. Similarly for clrsb. */
3034 if ((unoptab
== clz_optab
|| unoptab
== clrsb_optab
)
3037 scalar_int_mode wider_int_mode
3038 = as_a
<scalar_int_mode
> (wider_mode
);
3039 int_mode
= as_a
<scalar_int_mode
> (mode
);
3041 (wider_mode
, sub_optab
, temp
,
3042 gen_int_mode (GET_MODE_PRECISION (wider_int_mode
)
3043 - GET_MODE_PRECISION (int_mode
),
3045 target
, true, OPTAB_DIRECT
);
3048 /* Likewise for bswap. */
3049 if (unoptab
== bswap_optab
&& temp
!= 0)
3051 scalar_int_mode wider_int_mode
3052 = as_a
<scalar_int_mode
> (wider_mode
);
3053 int_mode
= as_a
<scalar_int_mode
> (mode
);
3054 gcc_assert (GET_MODE_PRECISION (wider_int_mode
)
3055 == GET_MODE_BITSIZE (wider_int_mode
)
3056 && GET_MODE_PRECISION (int_mode
)
3057 == GET_MODE_BITSIZE (int_mode
));
3059 temp
= expand_shift (RSHIFT_EXPR
, wider_int_mode
, temp
,
3060 GET_MODE_BITSIZE (wider_int_mode
)
3061 - GET_MODE_BITSIZE (int_mode
),
3067 if (mclass
!= MODE_INT
)
3070 target
= gen_reg_rtx (mode
);
3071 convert_move (target
, temp
, 0);
3075 return gen_lowpart (mode
, temp
);
3078 delete_insns_since (last
);
3083 /* One final attempt at implementing negation via subtraction,
3084 this time allowing widening of the operand. */
3085 if (optab_to_code (unoptab
) == NEG
&& !HONOR_SIGNED_ZEROS (mode
))
3088 temp
= expand_binop (mode
,
3089 unoptab
== negv_optab
? subv_optab
: sub_optab
,
3090 CONST0_RTX (mode
), op0
,
3091 target
, unsignedp
, OPTAB_LIB_WIDEN
);
3099 /* Emit code to compute the absolute value of OP0, with result to
3100 TARGET if convenient. (TARGET may be 0.) The return value says
3101 where the result actually is to be found.
3103 MODE is the mode of the operand; the mode of the result is
3104 different but can be deduced from MODE.
3109 expand_abs_nojump (machine_mode mode
, rtx op0
, rtx target
,
3110 int result_unsignedp
)
3114 if (GET_MODE_CLASS (mode
) != MODE_INT
3116 result_unsignedp
= 1;
3118 /* First try to do it with a special abs instruction. */
3119 temp
= expand_unop (mode
, result_unsignedp
? abs_optab
: absv_optab
,
3124 /* For floating point modes, try clearing the sign bit. */
3125 scalar_float_mode float_mode
;
3126 if (is_a
<scalar_float_mode
> (mode
, &float_mode
))
3128 temp
= expand_absneg_bit (ABS
, float_mode
, op0
, target
);
3133 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3134 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
3135 && !HONOR_SIGNED_ZEROS (mode
))
3137 rtx_insn
*last
= get_last_insn ();
3139 temp
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3142 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3148 delete_insns_since (last
);
3151 /* If this machine has expensive jumps, we can do integer absolute
3152 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3153 where W is the width of MODE. */
3155 scalar_int_mode int_mode
;
3156 if (is_int_mode (mode
, &int_mode
)
3157 && BRANCH_COST (optimize_insn_for_speed_p (),
3160 rtx extended
= expand_shift (RSHIFT_EXPR
, int_mode
, op0
,
3161 GET_MODE_PRECISION (int_mode
) - 1,
3164 temp
= expand_binop (int_mode
, xor_optab
, extended
, op0
, target
, 0,
3167 temp
= expand_binop (int_mode
,
3168 result_unsignedp
? sub_optab
: subv_optab
,
3169 temp
, extended
, target
, 0, OPTAB_LIB_WIDEN
);
3179 expand_abs (machine_mode mode
, rtx op0
, rtx target
,
3180 int result_unsignedp
, int safe
)
3183 rtx_code_label
*op1
;
3185 if (GET_MODE_CLASS (mode
) != MODE_INT
3187 result_unsignedp
= 1;
3189 temp
= expand_abs_nojump (mode
, op0
, target
, result_unsignedp
);
3193 /* If that does not win, use conditional jump and negate. */
3195 /* It is safe to use the target if it is the same
3196 as the source if this is also a pseudo register */
3197 if (op0
== target
&& REG_P (op0
)
3198 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
3201 op1
= gen_label_rtx ();
3202 if (target
== 0 || ! safe
3203 || GET_MODE (target
) != mode
3204 || (MEM_P (target
) && MEM_VOLATILE_P (target
))
3206 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
3207 target
= gen_reg_rtx (mode
);
3209 emit_move_insn (target
, op0
);
3212 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
3213 NULL_RTX
, NULL
, op1
,
3214 profile_probability::uninitialized ());
3216 op0
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3219 emit_move_insn (target
, op0
);
3225 /* Emit code to compute the one's complement absolute value of OP0
3226 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3227 (TARGET may be NULL_RTX.) The return value says where the result
3228 actually is to be found.
3230 MODE is the mode of the operand; the mode of the result is
3231 different but can be deduced from MODE. */
3234 expand_one_cmpl_abs_nojump (machine_mode mode
, rtx op0
, rtx target
)
3238 /* Not applicable for floating point modes. */
3239 if (FLOAT_MODE_P (mode
))
3242 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3243 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
)
3245 rtx_insn
*last
= get_last_insn ();
3247 temp
= expand_unop (mode
, one_cmpl_optab
, op0
, NULL_RTX
, 0);
3249 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3255 delete_insns_since (last
);
3258 /* If this machine has expensive jumps, we can do one's complement
3259 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3261 scalar_int_mode int_mode
;
3262 if (is_int_mode (mode
, &int_mode
)
3263 && BRANCH_COST (optimize_insn_for_speed_p (),
3266 rtx extended
= expand_shift (RSHIFT_EXPR
, int_mode
, op0
,
3267 GET_MODE_PRECISION (int_mode
) - 1,
3270 temp
= expand_binop (int_mode
, xor_optab
, extended
, op0
, target
, 0,
3280 /* A subroutine of expand_copysign, perform the copysign operation using the
3281 abs and neg primitives advertised to exist on the target. The assumption
3282 is that we have a split register file, and leaving op0 in fp registers,
3283 and not playing with subregs so much, will help the register allocator. */
3286 expand_copysign_absneg (scalar_float_mode mode
, rtx op0
, rtx op1
, rtx target
,
3287 int bitpos
, bool op0_is_abs
)
3289 scalar_int_mode imode
;
3290 enum insn_code icode
;
3292 rtx_code_label
*label
;
3297 /* Check if the back end provides an insn that handles signbit for the
3299 icode
= optab_handler (signbit_optab
, mode
);
3300 if (icode
!= CODE_FOR_nothing
)
3302 imode
= as_a
<scalar_int_mode
> (insn_data
[(int) icode
].operand
[0].mode
);
3303 sign
= gen_reg_rtx (imode
);
3304 emit_unop_insn (icode
, sign
, op1
, UNKNOWN
);
3308 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3310 if (!int_mode_for_mode (mode
).exists (&imode
))
3312 op1
= gen_lowpart (imode
, op1
);
3319 if (FLOAT_WORDS_BIG_ENDIAN
)
3320 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3322 word
= bitpos
/ BITS_PER_WORD
;
3323 bitpos
= bitpos
% BITS_PER_WORD
;
3324 op1
= operand_subword_force (op1
, word
, mode
);
3327 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3328 sign
= expand_binop (imode
, and_optab
, op1
,
3329 immed_wide_int_const (mask
, imode
),
3330 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3335 op0
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
3342 if (target
== NULL_RTX
)
3343 target
= copy_to_reg (op0
);
3345 emit_move_insn (target
, op0
);
3348 label
= gen_label_rtx ();
3349 emit_cmp_and_jump_insns (sign
, const0_rtx
, EQ
, NULL_RTX
, imode
, 1, label
);
3351 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3352 op0
= simplify_unary_operation (NEG
, mode
, op0
, mode
);
3354 op0
= expand_unop (mode
, neg_optab
, op0
, target
, 0);
3356 emit_move_insn (target
, op0
);
3364 /* A subroutine of expand_copysign, perform the entire copysign operation
3365 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3366 is true if op0 is known to have its sign bit clear. */
3369 expand_copysign_bit (scalar_float_mode mode
, rtx op0
, rtx op1
, rtx target
,
3370 int bitpos
, bool op0_is_abs
)
3372 scalar_int_mode imode
;
3373 int word
, nwords
, i
;
3377 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3379 if (!int_mode_for_mode (mode
).exists (&imode
))
3388 if (FLOAT_WORDS_BIG_ENDIAN
)
3389 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3391 word
= bitpos
/ BITS_PER_WORD
;
3392 bitpos
= bitpos
% BITS_PER_WORD
;
3393 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
3396 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3401 || (nwords
> 1 && !valid_multiword_target_p (target
)))
3402 target
= gen_reg_rtx (mode
);
3408 for (i
= 0; i
< nwords
; ++i
)
3410 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
3411 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
3417 = expand_binop (imode
, and_optab
, op0_piece
,
3418 immed_wide_int_const (~mask
, imode
),
3419 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3420 op1
= expand_binop (imode
, and_optab
,
3421 operand_subword_force (op1
, i
, mode
),
3422 immed_wide_int_const (mask
, imode
),
3423 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3425 temp
= expand_binop (imode
, ior_optab
, op0_piece
, op1
,
3426 targ_piece
, 1, OPTAB_LIB_WIDEN
);
3427 if (temp
!= targ_piece
)
3428 emit_move_insn (targ_piece
, temp
);
3431 emit_move_insn (targ_piece
, op0_piece
);
3434 insns
= get_insns ();
3441 op1
= expand_binop (imode
, and_optab
, gen_lowpart (imode
, op1
),
3442 immed_wide_int_const (mask
, imode
),
3443 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3445 op0
= gen_lowpart (imode
, op0
);
3447 op0
= expand_binop (imode
, and_optab
, op0
,
3448 immed_wide_int_const (~mask
, imode
),
3449 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3451 temp
= expand_binop (imode
, ior_optab
, op0
, op1
,
3452 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3453 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3459 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3460 scalar floating point mode. Return NULL if we do not know how to
3461 expand the operation inline. */
3464 expand_copysign (rtx op0
, rtx op1
, rtx target
)
3466 scalar_float_mode mode
;
3467 const struct real_format
*fmt
;
3471 mode
= as_a
<scalar_float_mode
> (GET_MODE (op0
));
3472 gcc_assert (GET_MODE (op1
) == mode
);
3474 /* First try to do it with a special instruction. */
3475 temp
= expand_binop (mode
, copysign_optab
, op0
, op1
,
3476 target
, 0, OPTAB_DIRECT
);
3480 fmt
= REAL_MODE_FORMAT (mode
);
3481 if (fmt
== NULL
|| !fmt
->has_signed_zero
)
3485 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3487 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0
)))
3488 op0
= simplify_unary_operation (ABS
, mode
, op0
, mode
);
3492 if (fmt
->signbit_ro
>= 0
3493 && (CONST_DOUBLE_AS_FLOAT_P (op0
)
3494 || (optab_handler (neg_optab
, mode
) != CODE_FOR_nothing
3495 && optab_handler (abs_optab
, mode
) != CODE_FOR_nothing
)))
3497 temp
= expand_copysign_absneg (mode
, op0
, op1
, target
,
3498 fmt
->signbit_ro
, op0_is_abs
);
3503 if (fmt
->signbit_rw
< 0)
3505 return expand_copysign_bit (mode
, op0
, op1
, target
,
3506 fmt
->signbit_rw
, op0_is_abs
);
3509 /* Generate an instruction whose insn-code is INSN_CODE,
3510 with two operands: an output TARGET and an input OP0.
3511 TARGET *must* be nonzero, and the output is always stored there.
3512 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3513 the value that is stored into TARGET.
3515 Return false if expansion failed. */
3518 maybe_emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
,
3521 struct expand_operand ops
[2];
3524 create_output_operand (&ops
[0], target
, GET_MODE (target
));
3525 create_input_operand (&ops
[1], op0
, GET_MODE (op0
));
3526 pat
= maybe_gen_insn (icode
, 2, ops
);
3530 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
3532 add_equal_note (pat
, ops
[0].value
, code
, ops
[1].value
, NULL_RTX
);
3536 if (ops
[0].value
!= target
)
3537 emit_move_insn (target
, ops
[0].value
);
3540 /* Generate an instruction whose insn-code is INSN_CODE,
3541 with two operands: an output TARGET and an input OP0.
3542 TARGET *must* be nonzero, and the output is always stored there.
3543 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3544 the value that is stored into TARGET. */
3547 emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
, enum rtx_code code
)
3549 bool ok
= maybe_emit_unop_insn (icode
, target
, op0
, code
);
3553 struct no_conflict_data
3556 rtx_insn
*first
, *insn
;
3560 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3561 the currently examined clobber / store has to stay in the list of
3562 insns that constitute the actual libcall block. */
3564 no_conflict_move_test (rtx dest
, const_rtx set
, void *p0
)
3566 struct no_conflict_data
*p
= (struct no_conflict_data
*) p0
;
3568 /* If this inns directly contributes to setting the target, it must stay. */
3569 if (reg_overlap_mentioned_p (p
->target
, dest
))
3570 p
->must_stay
= true;
3571 /* If we haven't committed to keeping any other insns in the list yet,
3572 there is nothing more to check. */
3573 else if (p
->insn
== p
->first
)
3575 /* If this insn sets / clobbers a register that feeds one of the insns
3576 already in the list, this insn has to stay too. */
3577 else if (reg_overlap_mentioned_p (dest
, PATTERN (p
->first
))
3578 || (CALL_P (p
->first
) && (find_reg_fusage (p
->first
, USE
, dest
)))
3579 || reg_used_between_p (dest
, p
->first
, p
->insn
)
3580 /* Likewise if this insn depends on a register set by a previous
3581 insn in the list, or if it sets a result (presumably a hard
3582 register) that is set or clobbered by a previous insn.
3583 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3584 SET_DEST perform the former check on the address, and the latter
3585 check on the MEM. */
3586 || (GET_CODE (set
) == SET
3587 && (modified_in_p (SET_SRC (set
), p
->first
)
3588 || modified_in_p (SET_DEST (set
), p
->first
)
3589 || modified_between_p (SET_SRC (set
), p
->first
, p
->insn
)
3590 || modified_between_p (SET_DEST (set
), p
->first
, p
->insn
))))
3591 p
->must_stay
= true;
3595 /* Emit code to make a call to a constant function or a library call.
3597 INSNS is a list containing all insns emitted in the call.
3598 These insns leave the result in RESULT. Our block is to copy RESULT
3599 to TARGET, which is logically equivalent to EQUIV.
3601 We first emit any insns that set a pseudo on the assumption that these are
3602 loading constants into registers; doing so allows them to be safely cse'ed
3603 between blocks. Then we emit all the other insns in the block, followed by
3604 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3605 note with an operand of EQUIV. */
3608 emit_libcall_block_1 (rtx_insn
*insns
, rtx target
, rtx result
, rtx equiv
,
3609 bool equiv_may_trap
)
3611 rtx final_dest
= target
;
3612 rtx_insn
*next
, *last
, *insn
;
3614 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3615 into a MEM later. Protect the libcall block from this change. */
3616 if (! REG_P (target
) || REG_USERVAR_P (target
))
3617 target
= gen_reg_rtx (GET_MODE (target
));
3619 /* If we're using non-call exceptions, a libcall corresponding to an
3620 operation that may trap may also trap. */
3621 /* ??? See the comment in front of make_reg_eh_region_note. */
3622 if (cfun
->can_throw_non_call_exceptions
3623 && (equiv_may_trap
|| may_trap_p (equiv
)))
3625 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3628 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
3631 int lp_nr
= INTVAL (XEXP (note
, 0));
3632 if (lp_nr
== 0 || lp_nr
== INT_MIN
)
3633 remove_note (insn
, note
);
3639 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3640 reg note to indicate that this call cannot throw or execute a nonlocal
3641 goto (unless there is already a REG_EH_REGION note, in which case
3643 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3645 make_reg_eh_region_note_nothrow_nononlocal (insn
);
3648 /* First emit all insns that set pseudos. Remove them from the list as
3649 we go. Avoid insns that set pseudos which were referenced in previous
3650 insns. These can be generated by move_by_pieces, for example,
3651 to update an address. Similarly, avoid insns that reference things
3652 set in previous insns. */
3654 for (insn
= insns
; insn
; insn
= next
)
3656 rtx set
= single_set (insn
);
3658 next
= NEXT_INSN (insn
);
3660 if (set
!= 0 && REG_P (SET_DEST (set
))
3661 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
)
3663 struct no_conflict_data data
;
3665 data
.target
= const0_rtx
;
3669 note_stores (PATTERN (insn
), no_conflict_move_test
, &data
);
3670 if (! data
.must_stay
)
3672 if (PREV_INSN (insn
))
3673 SET_NEXT_INSN (PREV_INSN (insn
)) = next
;
3678 SET_PREV_INSN (next
) = PREV_INSN (insn
);
3684 /* Some ports use a loop to copy large arguments onto the stack.
3685 Don't move anything outside such a loop. */
3690 /* Write the remaining insns followed by the final copy. */
3691 for (insn
= insns
; insn
; insn
= next
)
3693 next
= NEXT_INSN (insn
);
3698 last
= emit_move_insn (target
, result
);
3700 set_dst_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
), target
);
3702 if (final_dest
!= target
)
3703 emit_move_insn (final_dest
, target
);
3707 emit_libcall_block (rtx_insn
*insns
, rtx target
, rtx result
, rtx equiv
)
3709 emit_libcall_block_1 (insns
, target
, result
, equiv
, false);
3712 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3713 PURPOSE describes how this comparison will be used. CODE is the rtx
3714 comparison code we will be using.
3716 ??? Actually, CODE is slightly weaker than that. A target is still
3717 required to implement all of the normal bcc operations, but not
3718 required to implement all (or any) of the unordered bcc operations. */
3721 can_compare_p (enum rtx_code code
, machine_mode mode
,
3722 enum can_compare_purpose purpose
)
3725 test
= gen_rtx_fmt_ee (code
, mode
, const0_rtx
, const0_rtx
);
3728 enum insn_code icode
;
3730 if (purpose
== ccp_jump
3731 && (icode
= optab_handler (cbranch_optab
, mode
)) != CODE_FOR_nothing
3732 && insn_operand_matches (icode
, 0, test
))
3734 if (purpose
== ccp_store_flag
3735 && (icode
= optab_handler (cstore_optab
, mode
)) != CODE_FOR_nothing
3736 && insn_operand_matches (icode
, 1, test
))
3738 if (purpose
== ccp_cmov
3739 && optab_handler (cmov_optab
, mode
) != CODE_FOR_nothing
)
3742 mode
= GET_MODE_WIDER_MODE (mode
).else_void ();
3743 PUT_MODE (test
, mode
);
3745 while (mode
!= VOIDmode
);
3750 /* This function is called when we are going to emit a compare instruction that
3751 compares the values found in X and Y, using the rtl operator COMPARISON.
3753 If they have mode BLKmode, then SIZE specifies the size of both operands.
3755 UNSIGNEDP nonzero says that the operands are unsigned;
3756 this matters if they need to be widened (as given by METHODS).
3758 *PTEST is where the resulting comparison RTX is returned or NULL_RTX
3759 if we failed to produce one.
3761 *PMODE is the mode of the inputs (in case they are const_int).
3763 This function performs all the setup necessary so that the caller only has
3764 to emit a single comparison insn. This setup can involve doing a BLKmode
3765 comparison or emitting a library call to perform the comparison if no insn
3766 is available to handle it.
3767 The values which are passed in through pointers can be modified; the caller
3768 should perform the comparison on the modified values. Constant
3769 comparisons must have already been folded. */
3772 prepare_cmp_insn (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
3773 int unsignedp
, enum optab_methods methods
,
3774 rtx
*ptest
, machine_mode
*pmode
)
3776 machine_mode mode
= *pmode
;
3778 machine_mode cmp_mode
;
3779 enum mode_class mclass
;
3781 /* The other methods are not needed. */
3782 gcc_assert (methods
== OPTAB_DIRECT
|| methods
== OPTAB_WIDEN
3783 || methods
== OPTAB_LIB_WIDEN
);
3785 /* If we are optimizing, force expensive constants into a register. */
3786 if (CONSTANT_P (x
) && optimize
3787 && (rtx_cost (x
, mode
, COMPARE
, 0, optimize_insn_for_speed_p ())
3788 > COSTS_N_INSNS (1)))
3789 x
= force_reg (mode
, x
);
3791 if (CONSTANT_P (y
) && optimize
3792 && (rtx_cost (y
, mode
, COMPARE
, 1, optimize_insn_for_speed_p ())
3793 > COSTS_N_INSNS (1)))
3794 y
= force_reg (mode
, y
);
3797 /* Make sure if we have a canonical comparison. The RTL
3798 documentation states that canonical comparisons are required only
3799 for targets which have cc0. */
3800 gcc_assert (!CONSTANT_P (x
) || CONSTANT_P (y
));
3803 /* Don't let both operands fail to indicate the mode. */
3804 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
3805 x
= force_reg (mode
, x
);
3806 if (mode
== VOIDmode
)
3807 mode
= GET_MODE (x
) != VOIDmode
? GET_MODE (x
) : GET_MODE (y
);
3809 /* Handle all BLKmode compares. */
3811 if (mode
== BLKmode
)
3813 machine_mode result_mode
;
3814 enum insn_code cmp_code
;
3817 = GEN_INT (MIN (MEM_ALIGN (x
), MEM_ALIGN (y
)) / BITS_PER_UNIT
);
3821 /* Try to use a memory block compare insn - either cmpstr
3822 or cmpmem will do. */
3823 opt_scalar_int_mode cmp_mode_iter
;
3824 FOR_EACH_MODE_IN_CLASS (cmp_mode_iter
, MODE_INT
)
3826 scalar_int_mode cmp_mode
= cmp_mode_iter
.require ();
3827 cmp_code
= direct_optab_handler (cmpmem_optab
, cmp_mode
);
3828 if (cmp_code
== CODE_FOR_nothing
)
3829 cmp_code
= direct_optab_handler (cmpstr_optab
, cmp_mode
);
3830 if (cmp_code
== CODE_FOR_nothing
)
3831 cmp_code
= direct_optab_handler (cmpstrn_optab
, cmp_mode
);
3832 if (cmp_code
== CODE_FOR_nothing
)
3835 /* Must make sure the size fits the insn's mode. */
3836 if (CONST_INT_P (size
)
3837 ? INTVAL (size
) >= (1 << GET_MODE_BITSIZE (cmp_mode
))
3838 : (GET_MODE_BITSIZE (as_a
<scalar_int_mode
> (GET_MODE (size
)))
3839 > GET_MODE_BITSIZE (cmp_mode
)))
3842 result_mode
= insn_data
[cmp_code
].operand
[0].mode
;
3843 result
= gen_reg_rtx (result_mode
);
3844 size
= convert_to_mode (cmp_mode
, size
, 1);
3845 emit_insn (GEN_FCN (cmp_code
) (result
, x
, y
, size
, opalign
));
3847 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, result
, const0_rtx
);
3848 *pmode
= result_mode
;
3852 if (methods
!= OPTAB_LIB
&& methods
!= OPTAB_LIB_WIDEN
)
3855 /* Otherwise call a library function. */
3856 result
= emit_block_comp_via_libcall (XEXP (x
, 0), XEXP (y
, 0), size
);
3860 mode
= TYPE_MODE (integer_type_node
);
3861 methods
= OPTAB_LIB_WIDEN
;
3865 /* Don't allow operands to the compare to trap, as that can put the
3866 compare and branch in different basic blocks. */
3867 if (cfun
->can_throw_non_call_exceptions
)
3870 x
= copy_to_reg (x
);
3872 y
= copy_to_reg (y
);
3875 if (GET_MODE_CLASS (mode
) == MODE_CC
)
3877 enum insn_code icode
= optab_handler (cbranch_optab
, CCmode
);
3878 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
3879 gcc_assert (icode
!= CODE_FOR_nothing
3880 && insn_operand_matches (icode
, 0, test
));
3885 mclass
= GET_MODE_CLASS (mode
);
3886 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
3887 FOR_EACH_MODE_FROM (cmp_mode
, mode
)
3889 enum insn_code icode
;
3890 icode
= optab_handler (cbranch_optab
, cmp_mode
);
3891 if (icode
!= CODE_FOR_nothing
3892 && insn_operand_matches (icode
, 0, test
))
3894 rtx_insn
*last
= get_last_insn ();
3895 rtx op0
= prepare_operand (icode
, x
, 1, mode
, cmp_mode
, unsignedp
);
3896 rtx op1
= prepare_operand (icode
, y
, 2, mode
, cmp_mode
, unsignedp
);
3898 && insn_operand_matches (icode
, 1, op0
)
3899 && insn_operand_matches (icode
, 2, op1
))
3901 XEXP (test
, 0) = op0
;
3902 XEXP (test
, 1) = op1
;
3907 delete_insns_since (last
);
3910 if (methods
== OPTAB_DIRECT
|| !CLASS_HAS_WIDER_MODES_P (mclass
))
3914 if (methods
!= OPTAB_LIB_WIDEN
)
3917 if (!SCALAR_FLOAT_MODE_P (mode
))
3920 machine_mode ret_mode
;
3922 /* Handle a libcall just for the mode we are using. */
3923 libfunc
= optab_libfunc (cmp_optab
, mode
);
3924 gcc_assert (libfunc
);
3926 /* If we want unsigned, and this mode has a distinct unsigned
3927 comparison routine, use that. */
3930 rtx ulibfunc
= optab_libfunc (ucmp_optab
, mode
);
3935 ret_mode
= targetm
.libgcc_cmp_return_mode ();
3936 result
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
3937 ret_mode
, x
, mode
, y
, mode
);
3939 /* There are two kinds of comparison routines. Biased routines
3940 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3941 of gcc expect that the comparison operation is equivalent
3942 to the modified comparison. For signed comparisons compare the
3943 result against 1 in the biased case, and zero in the unbiased
3944 case. For unsigned comparisons always compare against 1 after
3945 biasing the unbiased result by adding 1. This gives us a way to
3947 The comparisons in the fixed-point helper library are always
3952 if (!TARGET_LIB_INT_CMP_BIASED
&& !ALL_FIXED_POINT_MODE_P (mode
))
3955 x
= plus_constant (ret_mode
, result
, 1);
3961 prepare_cmp_insn (x
, y
, comparison
, NULL_RTX
, unsignedp
, methods
,
3965 prepare_float_lib_cmp (x
, y
, comparison
, ptest
, pmode
);
3973 /* Before emitting an insn with code ICODE, make sure that X, which is going
3974 to be used for operand OPNUM of the insn, is converted from mode MODE to
3975 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3976 that it is accepted by the operand predicate. Return the new value. */
3979 prepare_operand (enum insn_code icode
, rtx x
, int opnum
, machine_mode mode
,
3980 machine_mode wider_mode
, int unsignedp
)
3982 if (mode
!= wider_mode
)
3983 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
3985 if (!insn_operand_matches (icode
, opnum
, x
))
3987 machine_mode op_mode
= insn_data
[(int) icode
].operand
[opnum
].mode
;
3988 if (reload_completed
)
3990 if (GET_MODE (x
) != op_mode
&& GET_MODE (x
) != VOIDmode
)
3992 x
= copy_to_mode_reg (op_mode
, x
);
3998 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3999 we can do the branch. */
4002 emit_cmp_and_jump_insn_1 (rtx test
, machine_mode mode
, rtx label
,
4003 profile_probability prob
)
4005 machine_mode optab_mode
;
4006 enum mode_class mclass
;
4007 enum insn_code icode
;
4010 mclass
= GET_MODE_CLASS (mode
);
4011 optab_mode
= (mclass
== MODE_CC
) ? CCmode
: mode
;
4012 icode
= optab_handler (cbranch_optab
, optab_mode
);
4014 gcc_assert (icode
!= CODE_FOR_nothing
);
4015 gcc_assert (insn_operand_matches (icode
, 0, test
));
4016 insn
= emit_jump_insn (GEN_FCN (icode
) (test
, XEXP (test
, 0),
4017 XEXP (test
, 1), label
));
4018 if (prob
.initialized_p ()
4019 && profile_status_for_fn (cfun
) != PROFILE_ABSENT
4022 && any_condjump_p (insn
)
4023 && !find_reg_note (insn
, REG_BR_PROB
, 0))
4024 add_reg_br_prob_note (insn
, prob
);
4027 /* Generate code to compare X with Y so that the condition codes are
4028 set and to jump to LABEL if the condition is true. If X is a
4029 constant and Y is not a constant, then the comparison is swapped to
4030 ensure that the comparison RTL has the canonical form.
4032 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4033 need to be widened. UNSIGNEDP is also used to select the proper
4034 branch condition code.
4036 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4038 MODE is the mode of the inputs (in case they are const_int).
4040 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4041 It will be potentially converted into an unsigned variant based on
4042 UNSIGNEDP to select a proper jump instruction.
4044 PROB is the probability of jumping to LABEL. */
4047 emit_cmp_and_jump_insns (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4048 machine_mode mode
, int unsignedp
, rtx label
,
4049 profile_probability prob
)
4051 rtx op0
= x
, op1
= y
;
4054 /* Swap operands and condition to ensure canonical RTL. */
4055 if (swap_commutative_operands_p (x
, y
)
4056 && can_compare_p (swap_condition (comparison
), mode
, ccp_jump
))
4059 comparison
= swap_condition (comparison
);
4062 /* If OP0 is still a constant, then both X and Y must be constants
4063 or the opposite comparison is not supported. Force X into a register
4064 to create canonical RTL. */
4065 if (CONSTANT_P (op0
))
4066 op0
= force_reg (mode
, op0
);
4069 comparison
= unsigned_condition (comparison
);
4071 prepare_cmp_insn (op0
, op1
, comparison
, size
, unsignedp
, OPTAB_LIB_WIDEN
,
4073 emit_cmp_and_jump_insn_1 (test
, mode
, label
, prob
);
4077 /* Emit a library call comparison between floating point X and Y.
4078 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4081 prepare_float_lib_cmp (rtx x
, rtx y
, enum rtx_code comparison
,
4082 rtx
*ptest
, machine_mode
*pmode
)
4084 enum rtx_code swapped
= swap_condition (comparison
);
4085 enum rtx_code reversed
= reverse_condition_maybe_unordered (comparison
);
4086 machine_mode orig_mode
= GET_MODE (x
);
4088 rtx true_rtx
, false_rtx
;
4089 rtx value
, target
, equiv
;
4092 bool reversed_p
= false;
4093 scalar_int_mode cmp_mode
= targetm
.libgcc_cmp_return_mode ();
4095 FOR_EACH_MODE_FROM (mode
, orig_mode
)
4097 if (code_to_optab (comparison
)
4098 && (libfunc
= optab_libfunc (code_to_optab (comparison
), mode
)))
4101 if (code_to_optab (swapped
)
4102 && (libfunc
= optab_libfunc (code_to_optab (swapped
), mode
)))
4105 comparison
= swapped
;
4109 if (code_to_optab (reversed
)
4110 && (libfunc
= optab_libfunc (code_to_optab (reversed
), mode
)))
4112 comparison
= reversed
;
4118 gcc_assert (mode
!= VOIDmode
);
4120 if (mode
!= orig_mode
)
4122 x
= convert_to_mode (mode
, x
, 0);
4123 y
= convert_to_mode (mode
, y
, 0);
4126 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4127 the RTL. The allows the RTL optimizers to delete the libcall if the
4128 condition can be determined at compile-time. */
4129 if (comparison
== UNORDERED
4130 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4132 true_rtx
= const_true_rtx
;
4133 false_rtx
= const0_rtx
;
4140 true_rtx
= const0_rtx
;
4141 false_rtx
= const_true_rtx
;
4145 true_rtx
= const_true_rtx
;
4146 false_rtx
= const0_rtx
;
4150 true_rtx
= const1_rtx
;
4151 false_rtx
= const0_rtx
;
4155 true_rtx
= const0_rtx
;
4156 false_rtx
= constm1_rtx
;
4160 true_rtx
= constm1_rtx
;
4161 false_rtx
= const0_rtx
;
4165 true_rtx
= const0_rtx
;
4166 false_rtx
= const1_rtx
;
4174 if (comparison
== UNORDERED
)
4176 rtx temp
= simplify_gen_relational (NE
, cmp_mode
, mode
, x
, x
);
4177 equiv
= simplify_gen_relational (NE
, cmp_mode
, mode
, y
, y
);
4178 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4179 temp
, const_true_rtx
, equiv
);
4183 equiv
= simplify_gen_relational (comparison
, cmp_mode
, mode
, x
, y
);
4184 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4185 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4186 equiv
, true_rtx
, false_rtx
);
4190 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4191 cmp_mode
, x
, mode
, y
, mode
);
4192 insns
= get_insns ();
4195 target
= gen_reg_rtx (cmp_mode
);
4196 emit_libcall_block (insns
, target
, value
, equiv
);
4198 if (comparison
== UNORDERED
4199 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
)
4201 *ptest
= gen_rtx_fmt_ee (reversed_p
? EQ
: NE
, VOIDmode
, target
, false_rtx
);
4203 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, target
, const0_rtx
);
4208 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4211 emit_indirect_jump (rtx loc
)
4213 if (!targetm
.have_indirect_jump ())
4214 sorry ("indirect jumps are not available on this target");
4217 struct expand_operand ops
[1];
4218 create_address_operand (&ops
[0], loc
);
4219 expand_jump_insn (targetm
.code_for_indirect_jump
, 1, ops
);
4225 /* Emit a conditional move instruction if the machine supports one for that
4226 condition and machine mode.
4228 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4229 the mode to use should they be constants. If it is VOIDmode, they cannot
4232 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4233 should be stored there. MODE is the mode to use should they be constants.
4234 If it is VOIDmode, they cannot both be constants.
4236 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4237 is not supported. */
4240 emit_conditional_move (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4241 machine_mode cmode
, rtx op2
, rtx op3
,
4242 machine_mode mode
, int unsignedp
)
4246 enum insn_code icode
;
4247 enum rtx_code reversed
;
4249 /* If the two source operands are identical, that's just a move. */
4251 if (rtx_equal_p (op2
, op3
))
4254 target
= gen_reg_rtx (mode
);
4256 emit_move_insn (target
, op3
);
4260 /* If one operand is constant, make it the second one. Only do this
4261 if the other operand is not constant as well. */
4263 if (swap_commutative_operands_p (op0
, op1
))
4265 std::swap (op0
, op1
);
4266 code
= swap_condition (code
);
4269 /* get_condition will prefer to generate LT and GT even if the old
4270 comparison was against zero, so undo that canonicalization here since
4271 comparisons against zero are cheaper. */
4272 if (code
== LT
&& op1
== const1_rtx
)
4273 code
= LE
, op1
= const0_rtx
;
4274 else if (code
== GT
&& op1
== constm1_rtx
)
4275 code
= GE
, op1
= const0_rtx
;
4277 if (cmode
== VOIDmode
)
4278 cmode
= GET_MODE (op0
);
4280 enum rtx_code orig_code
= code
;
4281 bool swapped
= false;
4282 if (swap_commutative_operands_p (op2
, op3
)
4283 && ((reversed
= reversed_comparison_code_parts (code
, op0
, op1
, NULL
))
4286 std::swap (op2
, op3
);
4291 if (mode
== VOIDmode
)
4292 mode
= GET_MODE (op2
);
4294 icode
= direct_optab_handler (movcc_optab
, mode
);
4296 if (icode
== CODE_FOR_nothing
)
4300 target
= gen_reg_rtx (mode
);
4302 for (int pass
= 0; ; pass
++)
4304 code
= unsignedp
? unsigned_condition (code
) : code
;
4305 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4307 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4308 punt and let the caller figure out how best to deal with this
4310 if (COMPARISON_P (comparison
))
4312 saved_pending_stack_adjust save
;
4313 save_pending_stack_adjust (&save
);
4314 last
= get_last_insn ();
4315 do_pending_stack_adjust ();
4316 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4317 GET_CODE (comparison
), NULL_RTX
, unsignedp
,
4318 OPTAB_WIDEN
, &comparison
, &cmode
);
4321 struct expand_operand ops
[4];
4323 create_output_operand (&ops
[0], target
, mode
);
4324 create_fixed_operand (&ops
[1], comparison
);
4325 create_input_operand (&ops
[2], op2
, mode
);
4326 create_input_operand (&ops
[3], op3
, mode
);
4327 if (maybe_expand_insn (icode
, 4, ops
))
4329 if (ops
[0].value
!= target
)
4330 convert_move (target
, ops
[0].value
, false);
4334 delete_insns_since (last
);
4335 restore_pending_stack_adjust (&save
);
4341 /* If the preferred op2/op3 order is not usable, retry with other
4342 operand order, perhaps it will expand successfully. */
4345 else if ((reversed
= reversed_comparison_code_parts (orig_code
, op0
, op1
,
4351 std::swap (op2
, op3
);
4356 /* Emit a conditional negate or bitwise complement using the
4357 negcc or notcc optabs if available. Return NULL_RTX if such operations
4358 are not available. Otherwise return the RTX holding the result.
4359 TARGET is the desired destination of the result. COMP is the comparison
4360 on which to negate. If COND is true move into TARGET the negation
4361 or bitwise complement of OP1. Otherwise move OP2 into TARGET.
4362 CODE is either NEG or NOT. MODE is the machine mode in which the
4363 operation is performed. */
4366 emit_conditional_neg_or_complement (rtx target
, rtx_code code
,
4367 machine_mode mode
, rtx cond
, rtx op1
,
4370 optab op
= unknown_optab
;
4373 else if (code
== NOT
)
4378 insn_code icode
= direct_optab_handler (op
, mode
);
4380 if (icode
== CODE_FOR_nothing
)
4384 target
= gen_reg_rtx (mode
);
4386 rtx_insn
*last
= get_last_insn ();
4387 struct expand_operand ops
[4];
4389 create_output_operand (&ops
[0], target
, mode
);
4390 create_fixed_operand (&ops
[1], cond
);
4391 create_input_operand (&ops
[2], op1
, mode
);
4392 create_input_operand (&ops
[3], op2
, mode
);
4394 if (maybe_expand_insn (icode
, 4, ops
))
4396 if (ops
[0].value
!= target
)
4397 convert_move (target
, ops
[0].value
, false);
4401 delete_insns_since (last
);
4405 /* Emit a conditional addition instruction if the machine supports one for that
4406 condition and machine mode.
4408 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4409 the mode to use should they be constants. If it is VOIDmode, they cannot
4412 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4413 should be stored there. MODE is the mode to use should they be constants.
4414 If it is VOIDmode, they cannot both be constants.
4416 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4417 is not supported. */
4420 emit_conditional_add (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4421 machine_mode cmode
, rtx op2
, rtx op3
,
4422 machine_mode mode
, int unsignedp
)
4426 enum insn_code icode
;
4428 /* If one operand is constant, make it the second one. Only do this
4429 if the other operand is not constant as well. */
4431 if (swap_commutative_operands_p (op0
, op1
))
4433 std::swap (op0
, op1
);
4434 code
= swap_condition (code
);
4437 /* get_condition will prefer to generate LT and GT even if the old
4438 comparison was against zero, so undo that canonicalization here since
4439 comparisons against zero are cheaper. */
4440 if (code
== LT
&& op1
== const1_rtx
)
4441 code
= LE
, op1
= const0_rtx
;
4442 else if (code
== GT
&& op1
== constm1_rtx
)
4443 code
= GE
, op1
= const0_rtx
;
4445 if (cmode
== VOIDmode
)
4446 cmode
= GET_MODE (op0
);
4448 if (mode
== VOIDmode
)
4449 mode
= GET_MODE (op2
);
4451 icode
= optab_handler (addcc_optab
, mode
);
4453 if (icode
== CODE_FOR_nothing
)
4457 target
= gen_reg_rtx (mode
);
4459 code
= unsignedp
? unsigned_condition (code
) : code
;
4460 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4462 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4463 return NULL and let the caller figure out how best to deal with this
4465 if (!COMPARISON_P (comparison
))
4468 do_pending_stack_adjust ();
4469 last
= get_last_insn ();
4470 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4471 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4472 &comparison
, &cmode
);
4475 struct expand_operand ops
[4];
4477 create_output_operand (&ops
[0], target
, mode
);
4478 create_fixed_operand (&ops
[1], comparison
);
4479 create_input_operand (&ops
[2], op2
, mode
);
4480 create_input_operand (&ops
[3], op3
, mode
);
4481 if (maybe_expand_insn (icode
, 4, ops
))
4483 if (ops
[0].value
!= target
)
4484 convert_move (target
, ops
[0].value
, false);
4488 delete_insns_since (last
);
4492 /* These functions attempt to generate an insn body, rather than
4493 emitting the insn, but if the gen function already emits them, we
4494 make no attempt to turn them back into naked patterns. */
4496 /* Generate and return an insn body to add Y to X. */
4499 gen_add2_insn (rtx x
, rtx y
)
4501 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (x
));
4503 gcc_assert (insn_operand_matches (icode
, 0, x
));
4504 gcc_assert (insn_operand_matches (icode
, 1, x
));
4505 gcc_assert (insn_operand_matches (icode
, 2, y
));
4507 return GEN_FCN (icode
) (x
, x
, y
);
4510 /* Generate and return an insn body to add r1 and c,
4511 storing the result in r0. */
4514 gen_add3_insn (rtx r0
, rtx r1
, rtx c
)
4516 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (r0
));
4518 if (icode
== CODE_FOR_nothing
4519 || !insn_operand_matches (icode
, 0, r0
)
4520 || !insn_operand_matches (icode
, 1, r1
)
4521 || !insn_operand_matches (icode
, 2, c
))
4524 return GEN_FCN (icode
) (r0
, r1
, c
);
4528 have_add2_insn (rtx x
, rtx y
)
4530 enum insn_code icode
;
4532 gcc_assert (GET_MODE (x
) != VOIDmode
);
4534 icode
= optab_handler (add_optab
, GET_MODE (x
));
4536 if (icode
== CODE_FOR_nothing
)
4539 if (!insn_operand_matches (icode
, 0, x
)
4540 || !insn_operand_matches (icode
, 1, x
)
4541 || !insn_operand_matches (icode
, 2, y
))
4547 /* Generate and return an insn body to add Y to X. */
4550 gen_addptr3_insn (rtx x
, rtx y
, rtx z
)
4552 enum insn_code icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
4554 gcc_assert (insn_operand_matches (icode
, 0, x
));
4555 gcc_assert (insn_operand_matches (icode
, 1, y
));
4556 gcc_assert (insn_operand_matches (icode
, 2, z
));
4558 return GEN_FCN (icode
) (x
, y
, z
);
4561 /* Return true if the target implements an addptr pattern and X, Y,
4562 and Z are valid for the pattern predicates. */
4565 have_addptr3_insn (rtx x
, rtx y
, rtx z
)
4567 enum insn_code icode
;
4569 gcc_assert (GET_MODE (x
) != VOIDmode
);
4571 icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
4573 if (icode
== CODE_FOR_nothing
)
4576 if (!insn_operand_matches (icode
, 0, x
)
4577 || !insn_operand_matches (icode
, 1, y
)
4578 || !insn_operand_matches (icode
, 2, z
))
4584 /* Generate and return an insn body to subtract Y from X. */
4587 gen_sub2_insn (rtx x
, rtx y
)
4589 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (x
));
4591 gcc_assert (insn_operand_matches (icode
, 0, x
));
4592 gcc_assert (insn_operand_matches (icode
, 1, x
));
4593 gcc_assert (insn_operand_matches (icode
, 2, y
));
4595 return GEN_FCN (icode
) (x
, x
, y
);
4598 /* Generate and return an insn body to subtract r1 and c,
4599 storing the result in r0. */
4602 gen_sub3_insn (rtx r0
, rtx r1
, rtx c
)
4604 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (r0
));
4606 if (icode
== CODE_FOR_nothing
4607 || !insn_operand_matches (icode
, 0, r0
)
4608 || !insn_operand_matches (icode
, 1, r1
)
4609 || !insn_operand_matches (icode
, 2, c
))
4612 return GEN_FCN (icode
) (r0
, r1
, c
);
4616 have_sub2_insn (rtx x
, rtx y
)
4618 enum insn_code icode
;
4620 gcc_assert (GET_MODE (x
) != VOIDmode
);
4622 icode
= optab_handler (sub_optab
, GET_MODE (x
));
4624 if (icode
== CODE_FOR_nothing
)
4627 if (!insn_operand_matches (icode
, 0, x
)
4628 || !insn_operand_matches (icode
, 1, x
)
4629 || !insn_operand_matches (icode
, 2, y
))
4635 /* Generate the body of an insn to extend Y (with mode MFROM)
4636 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4639 gen_extend_insn (rtx x
, rtx y
, machine_mode mto
,
4640 machine_mode mfrom
, int unsignedp
)
4642 enum insn_code icode
= can_extend_p (mto
, mfrom
, unsignedp
);
4643 return GEN_FCN (icode
) (x
, y
);
4646 /* Generate code to convert FROM to floating point
4647 and store in TO. FROM must be fixed point and not VOIDmode.
4648 UNSIGNEDP nonzero means regard FROM as unsigned.
4649 Normally this is done by correcting the final value
4650 if it is negative. */
4653 expand_float (rtx to
, rtx from
, int unsignedp
)
4655 enum insn_code icode
;
4657 scalar_mode from_mode
, to_mode
;
4658 machine_mode fmode
, imode
;
4659 bool can_do_signed
= false;
4661 /* Crash now, because we won't be able to decide which mode to use. */
4662 gcc_assert (GET_MODE (from
) != VOIDmode
);
4664 /* Look for an insn to do the conversion. Do it in the specified
4665 modes if possible; otherwise convert either input, output or both to
4666 wider mode. If the integer mode is wider than the mode of FROM,
4667 we can do the conversion signed even if the input is unsigned. */
4669 FOR_EACH_MODE_FROM (fmode
, GET_MODE (to
))
4670 FOR_EACH_MODE_FROM (imode
, GET_MODE (from
))
4672 int doing_unsigned
= unsignedp
;
4674 if (fmode
!= GET_MODE (to
)
4675 && (significand_size (fmode
)
4676 < GET_MODE_UNIT_PRECISION (GET_MODE (from
))))
4679 icode
= can_float_p (fmode
, imode
, unsignedp
);
4680 if (icode
== CODE_FOR_nothing
&& unsignedp
)
4682 enum insn_code scode
= can_float_p (fmode
, imode
, 0);
4683 if (scode
!= CODE_FOR_nothing
)
4684 can_do_signed
= true;
4685 if (imode
!= GET_MODE (from
))
4686 icode
= scode
, doing_unsigned
= 0;
4689 if (icode
!= CODE_FOR_nothing
)
4691 if (imode
!= GET_MODE (from
))
4692 from
= convert_to_mode (imode
, from
, unsignedp
);
4694 if (fmode
!= GET_MODE (to
))
4695 target
= gen_reg_rtx (fmode
);
4697 emit_unop_insn (icode
, target
, from
,
4698 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
4701 convert_move (to
, target
, 0);
4706 /* Unsigned integer, and no way to convert directly. Convert as signed,
4707 then unconditionally adjust the result. */
4710 && is_a
<scalar_mode
> (GET_MODE (to
), &to_mode
)
4711 && is_a
<scalar_mode
> (GET_MODE (from
), &from_mode
))
4713 opt_scalar_mode fmode_iter
;
4714 rtx_code_label
*label
= gen_label_rtx ();
4716 REAL_VALUE_TYPE offset
;
4718 /* Look for a usable floating mode FMODE wider than the source and at
4719 least as wide as the target. Using FMODE will avoid rounding woes
4720 with unsigned values greater than the signed maximum value. */
4722 FOR_EACH_MODE_FROM (fmode_iter
, to_mode
)
4724 scalar_mode fmode
= fmode_iter
.require ();
4725 if (GET_MODE_PRECISION (from_mode
) < GET_MODE_BITSIZE (fmode
)
4726 && can_float_p (fmode
, from_mode
, 0) != CODE_FOR_nothing
)
4730 if (!fmode_iter
.exists (&fmode
))
4732 /* There is no such mode. Pretend the target is wide enough. */
4735 /* Avoid double-rounding when TO is narrower than FROM. */
4736 if ((significand_size (fmode
) + 1)
4737 < GET_MODE_PRECISION (from_mode
))
4740 rtx_code_label
*neglabel
= gen_label_rtx ();
4742 /* Don't use TARGET if it isn't a register, is a hard register,
4743 or is the wrong mode. */
4745 || REGNO (target
) < FIRST_PSEUDO_REGISTER
4746 || GET_MODE (target
) != fmode
)
4747 target
= gen_reg_rtx (fmode
);
4750 do_pending_stack_adjust ();
4752 /* Test whether the sign bit is set. */
4753 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
4756 /* The sign bit is not set. Convert as signed. */
4757 expand_float (target
, from
, 0);
4758 emit_jump_insn (targetm
.gen_jump (label
));
4761 /* The sign bit is set.
4762 Convert to a usable (positive signed) value by shifting right
4763 one bit, while remembering if a nonzero bit was shifted
4764 out; i.e., compute (from & 1) | (from >> 1). */
4766 emit_label (neglabel
);
4767 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
4768 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
4769 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, 1, NULL_RTX
, 1);
4770 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
4772 expand_float (target
, temp
, 0);
4774 /* Multiply by 2 to undo the shift above. */
4775 temp
= expand_binop (fmode
, add_optab
, target
, target
,
4776 target
, 0, OPTAB_LIB_WIDEN
);
4778 emit_move_insn (target
, temp
);
4780 do_pending_stack_adjust ();
4786 /* If we are about to do some arithmetic to correct for an
4787 unsigned operand, do it in a pseudo-register. */
4789 if (to_mode
!= fmode
4790 || !REG_P (to
) || REGNO (to
) < FIRST_PSEUDO_REGISTER
)
4791 target
= gen_reg_rtx (fmode
);
4793 /* Convert as signed integer to floating. */
4794 expand_float (target
, from
, 0);
4796 /* If FROM is negative (and therefore TO is negative),
4797 correct its value by 2**bitwidth. */
4799 do_pending_stack_adjust ();
4800 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, from_mode
,
4804 real_2expN (&offset
, GET_MODE_PRECISION (from_mode
), fmode
);
4805 temp
= expand_binop (fmode
, add_optab
, target
,
4806 const_double_from_real_value (offset
, fmode
),
4807 target
, 0, OPTAB_LIB_WIDEN
);
4809 emit_move_insn (target
, temp
);
4811 do_pending_stack_adjust ();
4816 /* No hardware instruction available; call a library routine. */
4821 convert_optab tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
4823 if (is_narrower_int_mode (GET_MODE (from
), SImode
))
4824 from
= convert_to_mode (SImode
, from
, unsignedp
);
4826 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
4827 gcc_assert (libfunc
);
4831 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4832 GET_MODE (to
), from
, GET_MODE (from
));
4833 insns
= get_insns ();
4836 emit_libcall_block (insns
, target
, value
,
4837 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FLOAT
: FLOAT
,
4838 GET_MODE (to
), from
));
4843 /* Copy result to requested destination
4844 if we have been computing in a temp location. */
4848 if (GET_MODE (target
) == GET_MODE (to
))
4849 emit_move_insn (to
, target
);
4851 convert_move (to
, target
, 0);
4855 /* Generate code to convert FROM to fixed point and store in TO. FROM
4856 must be floating point. */
4859 expand_fix (rtx to
, rtx from
, int unsignedp
)
4861 enum insn_code icode
;
4863 machine_mode fmode
, imode
;
4864 opt_scalar_mode fmode_iter
;
4865 bool must_trunc
= false;
4867 /* We first try to find a pair of modes, one real and one integer, at
4868 least as wide as FROM and TO, respectively, in which we can open-code
4869 this conversion. If the integer mode is wider than the mode of TO,
4870 we can do the conversion either signed or unsigned. */
4872 FOR_EACH_MODE_FROM (fmode
, GET_MODE (from
))
4873 FOR_EACH_MODE_FROM (imode
, GET_MODE (to
))
4875 int doing_unsigned
= unsignedp
;
4877 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
4878 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
4879 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
4881 if (icode
!= CODE_FOR_nothing
)
4883 rtx_insn
*last
= get_last_insn ();
4884 if (fmode
!= GET_MODE (from
))
4885 from
= convert_to_mode (fmode
, from
, 0);
4889 rtx temp
= gen_reg_rtx (GET_MODE (from
));
4890 from
= expand_unop (GET_MODE (from
), ftrunc_optab
, from
,
4894 if (imode
!= GET_MODE (to
))
4895 target
= gen_reg_rtx (imode
);
4897 if (maybe_emit_unop_insn (icode
, target
, from
,
4898 doing_unsigned
? UNSIGNED_FIX
: FIX
))
4901 convert_move (to
, target
, unsignedp
);
4904 delete_insns_since (last
);
4908 /* For an unsigned conversion, there is one more way to do it.
4909 If we have a signed conversion, we generate code that compares
4910 the real value to the largest representable positive number. If if
4911 is smaller, the conversion is done normally. Otherwise, subtract
4912 one plus the highest signed number, convert, and add it back.
4914 We only need to check all real modes, since we know we didn't find
4915 anything with a wider integer mode.
4917 This code used to extend FP value into mode wider than the destination.
4918 This is needed for decimal float modes which cannot accurately
4919 represent one plus the highest signed number of the same size, but
4920 not for binary modes. Consider, for instance conversion from SFmode
4923 The hot path through the code is dealing with inputs smaller than 2^63
4924 and doing just the conversion, so there is no bits to lose.
4926 In the other path we know the value is positive in the range 2^63..2^64-1
4927 inclusive. (as for other input overflow happens and result is undefined)
4928 So we know that the most important bit set in mantissa corresponds to
4929 2^63. The subtraction of 2^63 should not generate any rounding as it
4930 simply clears out that bit. The rest is trivial. */
4932 scalar_int_mode to_mode
;
4934 && is_a
<scalar_int_mode
> (GET_MODE (to
), &to_mode
)
4935 && HWI_COMPUTABLE_MODE_P (to_mode
))
4936 FOR_EACH_MODE_FROM (fmode_iter
, as_a
<scalar_mode
> (GET_MODE (from
)))
4938 scalar_mode fmode
= fmode_iter
.require ();
4939 if (CODE_FOR_nothing
!= can_fix_p (to_mode
, fmode
,
4941 && (!DECIMAL_FLOAT_MODE_P (fmode
)
4942 || (GET_MODE_BITSIZE (fmode
) > GET_MODE_PRECISION (to_mode
))))
4945 REAL_VALUE_TYPE offset
;
4947 rtx_code_label
*lab1
, *lab2
;
4950 bitsize
= GET_MODE_PRECISION (to_mode
);
4951 real_2expN (&offset
, bitsize
- 1, fmode
);
4952 limit
= const_double_from_real_value (offset
, fmode
);
4953 lab1
= gen_label_rtx ();
4954 lab2
= gen_label_rtx ();
4956 if (fmode
!= GET_MODE (from
))
4957 from
= convert_to_mode (fmode
, from
, 0);
4959 /* See if we need to do the subtraction. */
4960 do_pending_stack_adjust ();
4961 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
,
4962 GET_MODE (from
), 0, lab1
);
4964 /* If not, do the signed "fix" and branch around fixup code. */
4965 expand_fix (to
, from
, 0);
4966 emit_jump_insn (targetm
.gen_jump (lab2
));
4969 /* Otherwise, subtract 2**(N-1), convert to signed number,
4970 then add 2**(N-1). Do the addition using XOR since this
4971 will often generate better code. */
4973 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
4974 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4975 expand_fix (to
, target
, 0);
4976 target
= expand_binop (to_mode
, xor_optab
, to
,
4978 (HOST_WIDE_INT_1
<< (bitsize
- 1),
4980 to
, 1, OPTAB_LIB_WIDEN
);
4983 emit_move_insn (to
, target
);
4987 if (optab_handler (mov_optab
, to_mode
) != CODE_FOR_nothing
)
4989 /* Make a place for a REG_NOTE and add it. */
4990 insn
= emit_move_insn (to
, to
);
4991 set_dst_reg_note (insn
, REG_EQUAL
,
4992 gen_rtx_fmt_e (UNSIGNED_FIX
, to_mode
,
5001 /* We can't do it with an insn, so use a library call. But first ensure
5002 that the mode of TO is at least as wide as SImode, since those are the
5003 only library calls we know about. */
5005 if (is_narrower_int_mode (GET_MODE (to
), SImode
))
5007 target
= gen_reg_rtx (SImode
);
5009 expand_fix (target
, from
, unsignedp
);
5017 convert_optab tab
= unsignedp
? ufix_optab
: sfix_optab
;
5018 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5019 gcc_assert (libfunc
);
5023 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5024 GET_MODE (to
), from
, GET_MODE (from
));
5025 insns
= get_insns ();
5028 emit_libcall_block (insns
, target
, value
,
5029 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
5030 GET_MODE (to
), from
));
5035 if (GET_MODE (to
) == GET_MODE (target
))
5036 emit_move_insn (to
, target
);
5038 convert_move (to
, target
, 0);
5043 /* Promote integer arguments for a libcall if necessary.
5044 emit_library_call_value cannot do the promotion because it does not
5045 know if it should do a signed or unsigned promotion. This is because
5046 there are no tree types defined for libcalls. */
5049 prepare_libcall_arg (rtx arg
, int uintp
)
5051 scalar_int_mode mode
;
5052 machine_mode arg_mode
;
5053 if (is_a
<scalar_int_mode
> (GET_MODE (arg
), &mode
))
5055 /* If we need to promote the integer function argument we need to do
5056 it here instead of inside emit_library_call_value because in
5057 emit_library_call_value we don't know if we should do a signed or
5058 unsigned promotion. */
5061 arg_mode
= promote_function_mode (NULL_TREE
, mode
,
5062 &unsigned_p
, NULL_TREE
, 0);
5063 if (arg_mode
!= mode
)
5064 return convert_to_mode (arg_mode
, arg
, uintp
);
5069 /* Generate code to convert FROM or TO a fixed-point.
5070 If UINTP is true, either TO or FROM is an unsigned integer.
5071 If SATP is true, we need to saturate the result. */
5074 expand_fixed_convert (rtx to
, rtx from
, int uintp
, int satp
)
5076 machine_mode to_mode
= GET_MODE (to
);
5077 machine_mode from_mode
= GET_MODE (from
);
5079 enum rtx_code this_code
;
5080 enum insn_code code
;
5085 if (to_mode
== from_mode
)
5087 emit_move_insn (to
, from
);
5093 tab
= satp
? satfractuns_optab
: fractuns_optab
;
5094 this_code
= satp
? UNSIGNED_SAT_FRACT
: UNSIGNED_FRACT_CONVERT
;
5098 tab
= satp
? satfract_optab
: fract_optab
;
5099 this_code
= satp
? SAT_FRACT
: FRACT_CONVERT
;
5101 code
= convert_optab_handler (tab
, to_mode
, from_mode
);
5102 if (code
!= CODE_FOR_nothing
)
5104 emit_unop_insn (code
, to
, from
, this_code
);
5108 libfunc
= convert_optab_libfunc (tab
, to_mode
, from_mode
);
5109 gcc_assert (libfunc
);
5111 from
= prepare_libcall_arg (from
, uintp
);
5112 from_mode
= GET_MODE (from
);
5115 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, to_mode
,
5117 insns
= get_insns ();
5120 emit_libcall_block (insns
, to
, value
,
5121 gen_rtx_fmt_e (optab_to_code (tab
), to_mode
, from
));
5124 /* Generate code to convert FROM to fixed point and store in TO. FROM
5125 must be floating point, TO must be signed. Use the conversion optab
5126 TAB to do the conversion. */
5129 expand_sfix_optab (rtx to
, rtx from
, convert_optab tab
)
5131 enum insn_code icode
;
5133 machine_mode fmode
, imode
;
5135 /* We first try to find a pair of modes, one real and one integer, at
5136 least as wide as FROM and TO, respectively, in which we can open-code
5137 this conversion. If the integer mode is wider than the mode of TO,
5138 we can do the conversion either signed or unsigned. */
5140 FOR_EACH_MODE_FROM (fmode
, GET_MODE (from
))
5141 FOR_EACH_MODE_FROM (imode
, GET_MODE (to
))
5143 icode
= convert_optab_handler (tab
, imode
, fmode
);
5144 if (icode
!= CODE_FOR_nothing
)
5146 rtx_insn
*last
= get_last_insn ();
5147 if (fmode
!= GET_MODE (from
))
5148 from
= convert_to_mode (fmode
, from
, 0);
5150 if (imode
!= GET_MODE (to
))
5151 target
= gen_reg_rtx (imode
);
5153 if (!maybe_emit_unop_insn (icode
, target
, from
, UNKNOWN
))
5155 delete_insns_since (last
);
5159 convert_move (to
, target
, 0);
5167 /* Report whether we have an instruction to perform the operation
5168 specified by CODE on operands of mode MODE. */
5170 have_insn_for (enum rtx_code code
, machine_mode mode
)
5172 return (code_to_optab (code
)
5173 && (optab_handler (code_to_optab (code
), mode
)
5174 != CODE_FOR_nothing
));
5177 /* Print information about the current contents of the optabs on
5181 debug_optab_libfuncs (void)
5185 /* Dump the arithmetic optabs. */
5186 for (i
= FIRST_NORM_OPTAB
; i
<= LAST_NORMLIB_OPTAB
; ++i
)
5187 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
5189 rtx l
= optab_libfunc ((optab
) i
, (machine_mode
) j
);
5192 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
5193 fprintf (stderr
, "%s\t%s:\t%s\n",
5194 GET_RTX_NAME (optab_to_code ((optab
) i
)),
5200 /* Dump the conversion optabs. */
5201 for (i
= FIRST_CONV_OPTAB
; i
<= LAST_CONVLIB_OPTAB
; ++i
)
5202 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
5203 for (k
= 0; k
< NUM_MACHINE_MODES
; ++k
)
5205 rtx l
= convert_optab_libfunc ((optab
) i
, (machine_mode
) j
,
5209 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
5210 fprintf (stderr
, "%s\t%s\t%s:\t%s\n",
5211 GET_RTX_NAME (optab_to_code ((optab
) i
)),
5219 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5220 CODE. Return 0 on failure. */
5223 gen_cond_trap (enum rtx_code code
, rtx op1
, rtx op2
, rtx tcode
)
5225 machine_mode mode
= GET_MODE (op1
);
5226 enum insn_code icode
;
5230 if (mode
== VOIDmode
)
5233 icode
= optab_handler (ctrap_optab
, mode
);
5234 if (icode
== CODE_FOR_nothing
)
5237 /* Some targets only accept a zero trap code. */
5238 if (!insn_operand_matches (icode
, 3, tcode
))
5241 do_pending_stack_adjust ();
5243 prepare_cmp_insn (op1
, op2
, code
, NULL_RTX
, false, OPTAB_DIRECT
,
5248 insn
= GEN_FCN (icode
) (trap_rtx
, XEXP (trap_rtx
, 0), XEXP (trap_rtx
, 1),
5251 /* If that failed, then give up. */
5259 insn
= get_insns ();
5264 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5265 or unsigned operation code. */
5268 get_rtx_code (enum tree_code tcode
, bool unsignedp
)
5280 code
= unsignedp
? LTU
: LT
;
5283 code
= unsignedp
? LEU
: LE
;
5286 code
= unsignedp
? GTU
: GT
;
5289 code
= unsignedp
? GEU
: GE
;
5292 case UNORDERED_EXPR
:
5331 /* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to
5332 select signed or unsigned operators. OPNO holds the index of the
5333 first comparison operand for insn ICODE. Do not generate the
5334 compare instruction itself. */
5337 vector_compare_rtx (machine_mode cmp_mode
, enum tree_code tcode
,
5338 tree t_op0
, tree t_op1
, bool unsignedp
,
5339 enum insn_code icode
, unsigned int opno
)
5341 struct expand_operand ops
[2];
5342 rtx rtx_op0
, rtx_op1
;
5343 machine_mode m0
, m1
;
5344 enum rtx_code rcode
= get_rtx_code (tcode
, unsignedp
);
5346 gcc_assert (TREE_CODE_CLASS (tcode
) == tcc_comparison
);
5348 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
5349 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
5350 cases, use the original mode. */
5351 rtx_op0
= expand_expr (t_op0
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op0
)),
5353 m0
= GET_MODE (rtx_op0
);
5355 m0
= TYPE_MODE (TREE_TYPE (t_op0
));
5357 rtx_op1
= expand_expr (t_op1
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op1
)),
5359 m1
= GET_MODE (rtx_op1
);
5361 m1
= TYPE_MODE (TREE_TYPE (t_op1
));
5363 create_input_operand (&ops
[0], rtx_op0
, m0
);
5364 create_input_operand (&ops
[1], rtx_op1
, m1
);
5365 if (!maybe_legitimize_operands (icode
, opno
, 2, ops
))
5367 return gen_rtx_fmt_ee (rcode
, cmp_mode
, ops
[0].value
, ops
[1].value
);
5370 /* Checks if vec_perm mask SEL is a constant equivalent to a shift of the first
5371 vec_perm operand, assuming the second operand is a constant vector of zeroes.
5372 Return the shift distance in bits if so, or NULL_RTX if the vec_perm is not a
5375 shift_amt_for_vec_perm_mask (rtx sel
)
5377 unsigned int i
, first
, nelt
= GET_MODE_NUNITS (GET_MODE (sel
));
5378 unsigned int bitsize
= GET_MODE_UNIT_BITSIZE (GET_MODE (sel
));
5380 if (GET_CODE (sel
) != CONST_VECTOR
)
5383 first
= INTVAL (CONST_VECTOR_ELT (sel
, 0));
5386 for (i
= 1; i
< nelt
; i
++)
5388 int idx
= INTVAL (CONST_VECTOR_ELT (sel
, i
));
5389 unsigned int expected
= i
+ first
;
5390 /* Indices into the second vector are all equivalent. */
5391 if (idx
< 0 || (MIN (nelt
, (unsigned) idx
) != MIN (nelt
, expected
)))
5395 return GEN_INT (first
* bitsize
);
5398 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
5401 expand_vec_perm_1 (enum insn_code icode
, rtx target
,
5402 rtx v0
, rtx v1
, rtx sel
)
5404 machine_mode tmode
= GET_MODE (target
);
5405 machine_mode smode
= GET_MODE (sel
);
5406 struct expand_operand ops
[4];
5408 create_output_operand (&ops
[0], target
, tmode
);
5409 create_input_operand (&ops
[3], sel
, smode
);
5411 /* Make an effort to preserve v0 == v1. The target expander is able to
5412 rely on this to determine if we're permuting a single input operand. */
5413 if (rtx_equal_p (v0
, v1
))
5415 if (!insn_operand_matches (icode
, 1, v0
))
5416 v0
= force_reg (tmode
, v0
);
5417 gcc_checking_assert (insn_operand_matches (icode
, 1, v0
));
5418 gcc_checking_assert (insn_operand_matches (icode
, 2, v0
));
5420 create_fixed_operand (&ops
[1], v0
);
5421 create_fixed_operand (&ops
[2], v0
);
5425 create_input_operand (&ops
[1], v0
, tmode
);
5426 create_input_operand (&ops
[2], v1
, tmode
);
5429 if (maybe_expand_insn (icode
, 4, ops
))
5430 return ops
[0].value
;
5434 /* Generate instructions for vec_perm optab given its mode
5435 and three operands. */
5438 expand_vec_perm (machine_mode mode
, rtx v0
, rtx v1
, rtx sel
, rtx target
)
5440 enum insn_code icode
;
5441 machine_mode qimode
;
5442 unsigned int i
, w
, e
, u
;
5443 rtx tmp
, sel_qi
= NULL
;
5446 if (!target
|| GET_MODE (target
) != mode
)
5447 target
= gen_reg_rtx (mode
);
5449 w
= GET_MODE_SIZE (mode
);
5450 e
= GET_MODE_NUNITS (mode
);
5451 u
= GET_MODE_UNIT_SIZE (mode
);
5453 /* Set QIMODE to a different vector mode with byte elements.
5454 If no such mode, or if MODE already has byte elements, use VOIDmode. */
5455 if (GET_MODE_INNER (mode
) == QImode
5456 || !mode_for_vector (QImode
, w
).exists (&qimode
)
5457 || !VECTOR_MODE_P (qimode
))
5460 /* If the input is a constant, expand it specially. */
5461 gcc_assert (GET_MODE_CLASS (GET_MODE (sel
)) == MODE_VECTOR_INT
);
5462 if (GET_CODE (sel
) == CONST_VECTOR
)
5464 /* See if this can be handled with a vec_shr. We only do this if the
5465 second vector is all zeroes. */
5466 enum insn_code shift_code
= optab_handler (vec_shr_optab
, mode
);
5467 enum insn_code shift_code_qi
= ((qimode
!= VOIDmode
&& qimode
!= mode
)
5468 ? optab_handler (vec_shr_optab
, qimode
)
5469 : CODE_FOR_nothing
);
5470 rtx shift_amt
= NULL_RTX
;
5471 if (v1
== CONST0_RTX (GET_MODE (v1
))
5472 && (shift_code
!= CODE_FOR_nothing
5473 || shift_code_qi
!= CODE_FOR_nothing
))
5475 shift_amt
= shift_amt_for_vec_perm_mask (sel
);
5478 struct expand_operand ops
[3];
5479 if (shift_code
!= CODE_FOR_nothing
)
5481 create_output_operand (&ops
[0], target
, mode
);
5482 create_input_operand (&ops
[1], v0
, mode
);
5483 create_convert_operand_from_type (&ops
[2], shift_amt
,
5485 if (maybe_expand_insn (shift_code
, 3, ops
))
5486 return ops
[0].value
;
5488 if (shift_code_qi
!= CODE_FOR_nothing
)
5490 tmp
= gen_reg_rtx (qimode
);
5491 create_output_operand (&ops
[0], tmp
, qimode
);
5492 create_input_operand (&ops
[1], gen_lowpart (qimode
, v0
),
5494 create_convert_operand_from_type (&ops
[2], shift_amt
,
5496 if (maybe_expand_insn (shift_code_qi
, 3, ops
))
5497 return gen_lowpart (mode
, ops
[0].value
);
5502 icode
= direct_optab_handler (vec_perm_const_optab
, mode
);
5503 if (icode
!= CODE_FOR_nothing
)
5505 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
5510 /* Fall back to a constant byte-based permutation. */
5511 if (qimode
!= VOIDmode
)
5513 vec
= rtvec_alloc (w
);
5514 for (i
= 0; i
< e
; ++i
)
5516 unsigned int j
, this_e
;
5518 this_e
= INTVAL (CONST_VECTOR_ELT (sel
, i
));
5519 this_e
&= 2 * e
- 1;
5522 for (j
= 0; j
< u
; ++j
)
5523 RTVEC_ELT (vec
, i
* u
+ j
) = GEN_INT (this_e
+ j
);
5525 sel_qi
= gen_rtx_CONST_VECTOR (qimode
, vec
);
5527 icode
= direct_optab_handler (vec_perm_const_optab
, qimode
);
5528 if (icode
!= CODE_FOR_nothing
)
5530 tmp
= mode
!= qimode
? gen_reg_rtx (qimode
) : target
;
5531 tmp
= expand_vec_perm_1 (icode
, tmp
, gen_lowpart (qimode
, v0
),
5532 gen_lowpart (qimode
, v1
), sel_qi
);
5534 return gen_lowpart (mode
, tmp
);
5539 /* Otherwise expand as a fully variable permuation. */
5540 icode
= direct_optab_handler (vec_perm_optab
, mode
);
5541 if (icode
!= CODE_FOR_nothing
)
5543 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
5548 /* As a special case to aid several targets, lower the element-based
5549 permutation to a byte-based permutation and try again. */
5550 if (qimode
== VOIDmode
)
5552 icode
= direct_optab_handler (vec_perm_optab
, qimode
);
5553 if (icode
== CODE_FOR_nothing
)
5558 /* Multiply each element by its byte size. */
5559 machine_mode selmode
= GET_MODE (sel
);
5561 sel
= expand_simple_binop (selmode
, PLUS
, sel
, sel
,
5562 NULL
, 0, OPTAB_DIRECT
);
5564 sel
= expand_simple_binop (selmode
, ASHIFT
, sel
,
5565 GEN_INT (exact_log2 (u
)),
5566 NULL
, 0, OPTAB_DIRECT
);
5567 gcc_assert (sel
!= NULL
);
5569 /* Broadcast the low byte each element into each of its bytes. */
5570 vec
= rtvec_alloc (w
);
5571 for (i
= 0; i
< w
; ++i
)
5573 int this_e
= i
/ u
* u
;
5574 if (BYTES_BIG_ENDIAN
)
5576 RTVEC_ELT (vec
, i
) = GEN_INT (this_e
);
5578 tmp
= gen_rtx_CONST_VECTOR (qimode
, vec
);
5579 sel
= gen_lowpart (qimode
, sel
);
5580 sel
= expand_vec_perm (qimode
, sel
, sel
, tmp
, NULL
);
5581 gcc_assert (sel
!= NULL
);
5583 /* Add the byte offset to each byte element. */
5584 /* Note that the definition of the indicies here is memory ordering,
5585 so there should be no difference between big and little endian. */
5586 vec
= rtvec_alloc (w
);
5587 for (i
= 0; i
< w
; ++i
)
5588 RTVEC_ELT (vec
, i
) = GEN_INT (i
% u
);
5589 tmp
= gen_rtx_CONST_VECTOR (qimode
, vec
);
5590 sel_qi
= expand_simple_binop (qimode
, PLUS
, sel
, tmp
,
5591 sel
, 0, OPTAB_DIRECT
);
5592 gcc_assert (sel_qi
!= NULL
);
5595 tmp
= mode
!= qimode
? gen_reg_rtx (qimode
) : target
;
5596 tmp
= expand_vec_perm_1 (icode
, tmp
, gen_lowpart (qimode
, v0
),
5597 gen_lowpart (qimode
, v1
), sel_qi
);
5599 tmp
= gen_lowpart (mode
, tmp
);
5603 /* Generate insns for a VEC_COND_EXPR with mask, given its TYPE and its
5607 expand_vec_cond_mask_expr (tree vec_cond_type
, tree op0
, tree op1
, tree op2
,
5610 struct expand_operand ops
[4];
5611 machine_mode mode
= TYPE_MODE (vec_cond_type
);
5612 machine_mode mask_mode
= TYPE_MODE (TREE_TYPE (op0
));
5613 enum insn_code icode
= get_vcond_mask_icode (mode
, mask_mode
);
5614 rtx mask
, rtx_op1
, rtx_op2
;
5616 if (icode
== CODE_FOR_nothing
)
5619 mask
= expand_normal (op0
);
5620 rtx_op1
= expand_normal (op1
);
5621 rtx_op2
= expand_normal (op2
);
5623 mask
= force_reg (mask_mode
, mask
);
5624 rtx_op1
= force_reg (GET_MODE (rtx_op1
), rtx_op1
);
5626 create_output_operand (&ops
[0], target
, mode
);
5627 create_input_operand (&ops
[1], rtx_op1
, mode
);
5628 create_input_operand (&ops
[2], rtx_op2
, mode
);
5629 create_input_operand (&ops
[3], mask
, mask_mode
);
5630 expand_insn (icode
, 4, ops
);
5632 return ops
[0].value
;
5635 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
5639 expand_vec_cond_expr (tree vec_cond_type
, tree op0
, tree op1
, tree op2
,
5642 struct expand_operand ops
[6];
5643 enum insn_code icode
;
5644 rtx comparison
, rtx_op1
, rtx_op2
;
5645 machine_mode mode
= TYPE_MODE (vec_cond_type
);
5646 machine_mode cmp_op_mode
;
5649 enum tree_code tcode
;
5651 if (COMPARISON_CLASS_P (op0
))
5653 op0a
= TREE_OPERAND (op0
, 0);
5654 op0b
= TREE_OPERAND (op0
, 1);
5655 tcode
= TREE_CODE (op0
);
5659 gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0
)));
5660 if (get_vcond_mask_icode (mode
, TYPE_MODE (TREE_TYPE (op0
)))
5661 != CODE_FOR_nothing
)
5662 return expand_vec_cond_mask_expr (vec_cond_type
, op0
, op1
,
5667 gcc_assert (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (op0
)))
5668 == MODE_VECTOR_INT
);
5670 op0b
= build_zero_cst (TREE_TYPE (op0
));
5674 cmp_op_mode
= TYPE_MODE (TREE_TYPE (op0a
));
5675 unsignedp
= TYPE_UNSIGNED (TREE_TYPE (op0a
));
5678 gcc_assert (GET_MODE_SIZE (mode
) == GET_MODE_SIZE (cmp_op_mode
)
5679 && GET_MODE_NUNITS (mode
) == GET_MODE_NUNITS (cmp_op_mode
));
5681 icode
= get_vcond_icode (mode
, cmp_op_mode
, unsignedp
);
5682 if (icode
== CODE_FOR_nothing
)
5684 if (tcode
== EQ_EXPR
|| tcode
== NE_EXPR
)
5685 icode
= get_vcond_eq_icode (mode
, cmp_op_mode
);
5686 if (icode
== CODE_FOR_nothing
)
5690 comparison
= vector_compare_rtx (VOIDmode
, tcode
, op0a
, op0b
, unsignedp
,
5692 rtx_op1
= expand_normal (op1
);
5693 rtx_op2
= expand_normal (op2
);
5695 create_output_operand (&ops
[0], target
, mode
);
5696 create_input_operand (&ops
[1], rtx_op1
, mode
);
5697 create_input_operand (&ops
[2], rtx_op2
, mode
);
5698 create_fixed_operand (&ops
[3], comparison
);
5699 create_fixed_operand (&ops
[4], XEXP (comparison
, 0));
5700 create_fixed_operand (&ops
[5], XEXP (comparison
, 1));
5701 expand_insn (icode
, 6, ops
);
5702 return ops
[0].value
;
5705 /* Generate insns for a vector comparison into a mask. */
5708 expand_vec_cmp_expr (tree type
, tree exp
, rtx target
)
5710 struct expand_operand ops
[4];
5711 enum insn_code icode
;
5713 machine_mode mask_mode
= TYPE_MODE (type
);
5717 enum tree_code tcode
;
5719 op0a
= TREE_OPERAND (exp
, 0);
5720 op0b
= TREE_OPERAND (exp
, 1);
5721 tcode
= TREE_CODE (exp
);
5723 unsignedp
= TYPE_UNSIGNED (TREE_TYPE (op0a
));
5724 vmode
= TYPE_MODE (TREE_TYPE (op0a
));
5726 icode
= get_vec_cmp_icode (vmode
, mask_mode
, unsignedp
);
5727 if (icode
== CODE_FOR_nothing
)
5729 if (tcode
== EQ_EXPR
|| tcode
== NE_EXPR
)
5730 icode
= get_vec_cmp_eq_icode (vmode
, mask_mode
);
5731 if (icode
== CODE_FOR_nothing
)
5735 comparison
= vector_compare_rtx (mask_mode
, tcode
, op0a
, op0b
,
5736 unsignedp
, icode
, 2);
5737 create_output_operand (&ops
[0], target
, mask_mode
);
5738 create_fixed_operand (&ops
[1], comparison
);
5739 create_fixed_operand (&ops
[2], XEXP (comparison
, 0));
5740 create_fixed_operand (&ops
[3], XEXP (comparison
, 1));
5741 expand_insn (icode
, 4, ops
);
5742 return ops
[0].value
;
5745 /* Expand a highpart multiply. */
5748 expand_mult_highpart (machine_mode mode
, rtx op0
, rtx op1
,
5749 rtx target
, bool uns_p
)
5751 struct expand_operand eops
[3];
5752 enum insn_code icode
;
5753 int method
, i
, nunits
;
5759 method
= can_mult_highpart_p (mode
, uns_p
);
5765 tab1
= uns_p
? umul_highpart_optab
: smul_highpart_optab
;
5766 return expand_binop (mode
, tab1
, op0
, op1
, target
, uns_p
,
5769 tab1
= uns_p
? vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
5770 tab2
= uns_p
? vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
5773 tab1
= uns_p
? vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
5774 tab2
= uns_p
? vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
5775 if (BYTES_BIG_ENDIAN
)
5776 std::swap (tab1
, tab2
);
5782 icode
= optab_handler (tab1
, mode
);
5783 nunits
= GET_MODE_NUNITS (mode
);
5784 wmode
= insn_data
[icode
].operand
[0].mode
;
5785 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode
) == nunits
);
5786 gcc_checking_assert (GET_MODE_SIZE (wmode
) == GET_MODE_SIZE (mode
));
5788 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
5789 create_input_operand (&eops
[1], op0
, mode
);
5790 create_input_operand (&eops
[2], op1
, mode
);
5791 expand_insn (icode
, 3, eops
);
5792 m1
= gen_lowpart (mode
, eops
[0].value
);
5794 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
5795 create_input_operand (&eops
[1], op0
, mode
);
5796 create_input_operand (&eops
[2], op1
, mode
);
5797 expand_insn (optab_handler (tab2
, mode
), 3, eops
);
5798 m2
= gen_lowpart (mode
, eops
[0].value
);
5800 v
= rtvec_alloc (nunits
);
5803 for (i
= 0; i
< nunits
; ++i
)
5804 RTVEC_ELT (v
, i
) = GEN_INT (!BYTES_BIG_ENDIAN
+ (i
& ~1)
5805 + ((i
& 1) ? nunits
: 0));
5806 perm
= gen_rtx_CONST_VECTOR (mode
, v
);
5810 int base
= BYTES_BIG_ENDIAN
? 0 : 1;
5811 perm
= gen_const_vec_series (mode
, GEN_INT (base
), GEN_INT (2));
5814 return expand_vec_perm (mode
, m1
, m2
, perm
, target
);
5817 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
5821 find_cc_set (rtx x
, const_rtx pat
, void *data
)
5823 if (REG_P (x
) && GET_MODE_CLASS (GET_MODE (x
)) == MODE_CC
5824 && GET_CODE (pat
) == SET
)
5826 rtx
*p_cc_reg
= (rtx
*) data
;
5827 gcc_assert (!*p_cc_reg
);
5832 /* This is a helper function for the other atomic operations. This function
5833 emits a loop that contains SEQ that iterates until a compare-and-swap
5834 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5835 a set of instructions that takes a value from OLD_REG as an input and
5836 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5837 set to the current contents of MEM. After SEQ, a compare-and-swap will
5838 attempt to update MEM with NEW_REG. The function returns true when the
5839 loop was generated successfully. */
5842 expand_compare_and_swap_loop (rtx mem
, rtx old_reg
, rtx new_reg
, rtx seq
)
5844 machine_mode mode
= GET_MODE (mem
);
5845 rtx_code_label
*label
;
5846 rtx cmp_reg
, success
, oldval
;
5848 /* The loop we want to generate looks like
5854 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
5858 Note that we only do the plain load from memory once. Subsequent
5859 iterations use the value loaded by the compare-and-swap pattern. */
5861 label
= gen_label_rtx ();
5862 cmp_reg
= gen_reg_rtx (mode
);
5864 emit_move_insn (cmp_reg
, mem
);
5866 emit_move_insn (old_reg
, cmp_reg
);
5872 if (!expand_atomic_compare_and_swap (&success
, &oldval
, mem
, old_reg
,
5873 new_reg
, false, MEMMODEL_SYNC_SEQ_CST
,
5877 if (oldval
!= cmp_reg
)
5878 emit_move_insn (cmp_reg
, oldval
);
5880 /* Mark this jump predicted not taken. */
5881 emit_cmp_and_jump_insns (success
, const0_rtx
, EQ
, const0_rtx
,
5882 GET_MODE (success
), 1, label
,
5883 profile_probability::guessed_never ());
5888 /* This function tries to emit an atomic_exchange intruction. VAL is written
5889 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
5890 using TARGET if possible. */
5893 maybe_emit_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
5895 machine_mode mode
= GET_MODE (mem
);
5896 enum insn_code icode
;
5898 /* If the target supports the exchange directly, great. */
5899 icode
= direct_optab_handler (atomic_exchange_optab
, mode
);
5900 if (icode
!= CODE_FOR_nothing
)
5902 struct expand_operand ops
[4];
5904 create_output_operand (&ops
[0], target
, mode
);
5905 create_fixed_operand (&ops
[1], mem
);
5906 create_input_operand (&ops
[2], val
, mode
);
5907 create_integer_operand (&ops
[3], model
);
5908 if (maybe_expand_insn (icode
, 4, ops
))
5909 return ops
[0].value
;
5915 /* This function tries to implement an atomic exchange operation using
5916 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
5917 The previous contents of *MEM are returned, using TARGET if possible.
5918 Since this instructionn is an acquire barrier only, stronger memory
5919 models may require additional barriers to be emitted. */
5922 maybe_emit_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
,
5923 enum memmodel model
)
5925 machine_mode mode
= GET_MODE (mem
);
5926 enum insn_code icode
;
5927 rtx_insn
*last_insn
= get_last_insn ();
5929 icode
= optab_handler (sync_lock_test_and_set_optab
, mode
);
5931 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
5932 exists, and the memory model is stronger than acquire, add a release
5933 barrier before the instruction. */
5935 if (is_mm_seq_cst (model
) || is_mm_release (model
) || is_mm_acq_rel (model
))
5936 expand_mem_thread_fence (model
);
5938 if (icode
!= CODE_FOR_nothing
)
5940 struct expand_operand ops
[3];
5941 create_output_operand (&ops
[0], target
, mode
);
5942 create_fixed_operand (&ops
[1], mem
);
5943 create_input_operand (&ops
[2], val
, mode
);
5944 if (maybe_expand_insn (icode
, 3, ops
))
5945 return ops
[0].value
;
5948 /* If an external test-and-set libcall is provided, use that instead of
5949 any external compare-and-swap that we might get from the compare-and-
5950 swap-loop expansion later. */
5951 if (!can_compare_and_swap_p (mode
, false))
5953 rtx libfunc
= optab_libfunc (sync_lock_test_and_set_optab
, mode
);
5954 if (libfunc
!= NULL
)
5958 addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
5959 return emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
5960 mode
, addr
, ptr_mode
,
5965 /* If the test_and_set can't be emitted, eliminate any barrier that might
5966 have been emitted. */
5967 delete_insns_since (last_insn
);
5971 /* This function tries to implement an atomic exchange operation using a
5972 compare_and_swap loop. VAL is written to *MEM. The previous contents of
5973 *MEM are returned, using TARGET if possible. No memory model is required
5974 since a compare_and_swap loop is seq-cst. */
5977 maybe_emit_compare_and_swap_exchange_loop (rtx target
, rtx mem
, rtx val
)
5979 machine_mode mode
= GET_MODE (mem
);
5981 if (can_compare_and_swap_p (mode
, true))
5983 if (!target
|| !register_operand (target
, mode
))
5984 target
= gen_reg_rtx (mode
);
5985 if (expand_compare_and_swap_loop (mem
, target
, val
, NULL_RTX
))
5992 /* This function tries to implement an atomic test-and-set operation
5993 using the atomic_test_and_set instruction pattern. A boolean value
5994 is returned from the operation, using TARGET if possible. */
5997 maybe_emit_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
5999 machine_mode pat_bool_mode
;
6000 struct expand_operand ops
[3];
6002 if (!targetm
.have_atomic_test_and_set ())
6005 /* While we always get QImode from __atomic_test_and_set, we get
6006 other memory modes from __sync_lock_test_and_set. Note that we
6007 use no endian adjustment here. This matches the 4.6 behavior
6008 in the Sparc backend. */
6009 enum insn_code icode
= targetm
.code_for_atomic_test_and_set
;
6010 gcc_checking_assert (insn_data
[icode
].operand
[1].mode
== QImode
);
6011 if (GET_MODE (mem
) != QImode
)
6012 mem
= adjust_address_nv (mem
, QImode
, 0);
6014 pat_bool_mode
= insn_data
[icode
].operand
[0].mode
;
6015 create_output_operand (&ops
[0], target
, pat_bool_mode
);
6016 create_fixed_operand (&ops
[1], mem
);
6017 create_integer_operand (&ops
[2], model
);
6019 if (maybe_expand_insn (icode
, 3, ops
))
6020 return ops
[0].value
;
6024 /* This function expands the legacy _sync_lock test_and_set operation which is
6025 generally an atomic exchange. Some limited targets only allow the
6026 constant 1 to be stored. This is an ACQUIRE operation.
6028 TARGET is an optional place to stick the return value.
6029 MEM is where VAL is stored. */
6032 expand_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
)
6036 /* Try an atomic_exchange first. */
6037 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, MEMMODEL_SYNC_ACQUIRE
);
6041 ret
= maybe_emit_sync_lock_test_and_set (target
, mem
, val
,
6042 MEMMODEL_SYNC_ACQUIRE
);
6046 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
6050 /* If there are no other options, try atomic_test_and_set if the value
6051 being stored is 1. */
6052 if (val
== const1_rtx
)
6053 ret
= maybe_emit_atomic_test_and_set (target
, mem
, MEMMODEL_SYNC_ACQUIRE
);
6058 /* This function expands the atomic test_and_set operation:
6059 atomically store a boolean TRUE into MEM and return the previous value.
6061 MEMMODEL is the memory model variant to use.
6062 TARGET is an optional place to stick the return value. */
6065 expand_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
6067 machine_mode mode
= GET_MODE (mem
);
6068 rtx ret
, trueval
, subtarget
;
6070 ret
= maybe_emit_atomic_test_and_set (target
, mem
, model
);
6074 /* Be binary compatible with non-default settings of trueval, and different
6075 cpu revisions. E.g. one revision may have atomic-test-and-set, but
6076 another only has atomic-exchange. */
6077 if (targetm
.atomic_test_and_set_trueval
== 1)
6079 trueval
= const1_rtx
;
6080 subtarget
= target
? target
: gen_reg_rtx (mode
);
6084 trueval
= gen_int_mode (targetm
.atomic_test_and_set_trueval
, mode
);
6085 subtarget
= gen_reg_rtx (mode
);
6088 /* Try the atomic-exchange optab... */
6089 ret
= maybe_emit_atomic_exchange (subtarget
, mem
, trueval
, model
);
6091 /* ... then an atomic-compare-and-swap loop ... */
6093 ret
= maybe_emit_compare_and_swap_exchange_loop (subtarget
, mem
, trueval
);
6095 /* ... before trying the vaguely defined legacy lock_test_and_set. */
6097 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, trueval
, model
);
6099 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
6100 things with the value 1. Thus we try again without trueval. */
6101 if (!ret
&& targetm
.atomic_test_and_set_trueval
!= 1)
6102 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, const1_rtx
, model
);
6104 /* Failing all else, assume a single threaded environment and simply
6105 perform the operation. */
6108 /* If the result is ignored skip the move to target. */
6109 if (subtarget
!= const0_rtx
)
6110 emit_move_insn (subtarget
, mem
);
6112 emit_move_insn (mem
, trueval
);
6116 /* Recall that have to return a boolean value; rectify if trueval
6117 is not exactly one. */
6118 if (targetm
.atomic_test_and_set_trueval
!= 1)
6119 ret
= emit_store_flag_force (target
, NE
, ret
, const0_rtx
, mode
, 0, 1);
6124 /* This function expands the atomic exchange operation:
6125 atomically store VAL in MEM and return the previous value in MEM.
6127 MEMMODEL is the memory model variant to use.
6128 TARGET is an optional place to stick the return value. */
6131 expand_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
6133 machine_mode mode
= GET_MODE (mem
);
6136 /* If loads are not atomic for the required size and we are not called to
6137 provide a __sync builtin, do not do anything so that we stay consistent
6138 with atomic loads of the same size. */
6139 if (!can_atomic_load_p (mode
) && !is_mm_sync (model
))
6142 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, model
);
6144 /* Next try a compare-and-swap loop for the exchange. */
6146 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
6151 /* This function expands the atomic compare exchange operation:
6153 *PTARGET_BOOL is an optional place to store the boolean success/failure.
6154 *PTARGET_OVAL is an optional place to store the old value from memory.
6155 Both target parameters may be NULL or const0_rtx to indicate that we do
6156 not care about that return value. Both target parameters are updated on
6157 success to the actual location of the corresponding result.
6159 MEMMODEL is the memory model variant to use.
6161 The return value of the function is true for success. */
6164 expand_atomic_compare_and_swap (rtx
*ptarget_bool
, rtx
*ptarget_oval
,
6165 rtx mem
, rtx expected
, rtx desired
,
6166 bool is_weak
, enum memmodel succ_model
,
6167 enum memmodel fail_model
)
6169 machine_mode mode
= GET_MODE (mem
);
6170 struct expand_operand ops
[8];
6171 enum insn_code icode
;
6172 rtx target_oval
, target_bool
= NULL_RTX
;
6175 /* If loads are not atomic for the required size and we are not called to
6176 provide a __sync builtin, do not do anything so that we stay consistent
6177 with atomic loads of the same size. */
6178 if (!can_atomic_load_p (mode
) && !is_mm_sync (succ_model
))
6181 /* Load expected into a register for the compare and swap. */
6182 if (MEM_P (expected
))
6183 expected
= copy_to_reg (expected
);
6185 /* Make sure we always have some place to put the return oldval.
6186 Further, make sure that place is distinct from the input expected,
6187 just in case we need that path down below. */
6188 if (ptarget_oval
&& *ptarget_oval
== const0_rtx
)
6189 ptarget_oval
= NULL
;
6191 if (ptarget_oval
== NULL
6192 || (target_oval
= *ptarget_oval
) == NULL
6193 || reg_overlap_mentioned_p (expected
, target_oval
))
6194 target_oval
= gen_reg_rtx (mode
);
6196 icode
= direct_optab_handler (atomic_compare_and_swap_optab
, mode
);
6197 if (icode
!= CODE_FOR_nothing
)
6199 machine_mode bool_mode
= insn_data
[icode
].operand
[0].mode
;
6201 if (ptarget_bool
&& *ptarget_bool
== const0_rtx
)
6202 ptarget_bool
= NULL
;
6204 /* Make sure we always have a place for the bool operand. */
6205 if (ptarget_bool
== NULL
6206 || (target_bool
= *ptarget_bool
) == NULL
6207 || GET_MODE (target_bool
) != bool_mode
)
6208 target_bool
= gen_reg_rtx (bool_mode
);
6210 /* Emit the compare_and_swap. */
6211 create_output_operand (&ops
[0], target_bool
, bool_mode
);
6212 create_output_operand (&ops
[1], target_oval
, mode
);
6213 create_fixed_operand (&ops
[2], mem
);
6214 create_input_operand (&ops
[3], expected
, mode
);
6215 create_input_operand (&ops
[4], desired
, mode
);
6216 create_integer_operand (&ops
[5], is_weak
);
6217 create_integer_operand (&ops
[6], succ_model
);
6218 create_integer_operand (&ops
[7], fail_model
);
6219 if (maybe_expand_insn (icode
, 8, ops
))
6221 /* Return success/failure. */
6222 target_bool
= ops
[0].value
;
6223 target_oval
= ops
[1].value
;
6228 /* Otherwise fall back to the original __sync_val_compare_and_swap
6229 which is always seq-cst. */
6230 icode
= optab_handler (sync_compare_and_swap_optab
, mode
);
6231 if (icode
!= CODE_FOR_nothing
)
6235 create_output_operand (&ops
[0], target_oval
, mode
);
6236 create_fixed_operand (&ops
[1], mem
);
6237 create_input_operand (&ops
[2], expected
, mode
);
6238 create_input_operand (&ops
[3], desired
, mode
);
6239 if (!maybe_expand_insn (icode
, 4, ops
))
6242 target_oval
= ops
[0].value
;
6244 /* If the caller isn't interested in the boolean return value,
6245 skip the computation of it. */
6246 if (ptarget_bool
== NULL
)
6249 /* Otherwise, work out if the compare-and-swap succeeded. */
6251 if (have_insn_for (COMPARE
, CCmode
))
6252 note_stores (PATTERN (get_last_insn ()), find_cc_set
, &cc_reg
);
6255 target_bool
= emit_store_flag_force (target_bool
, EQ
, cc_reg
,
6256 const0_rtx
, VOIDmode
, 0, 1);
6259 goto success_bool_from_val
;
6262 /* Also check for library support for __sync_val_compare_and_swap. */
6263 libfunc
= optab_libfunc (sync_compare_and_swap_optab
, mode
);
6264 if (libfunc
!= NULL
)
6266 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
6267 rtx target
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
6268 mode
, addr
, ptr_mode
,
6269 expected
, mode
, desired
, mode
);
6270 emit_move_insn (target_oval
, target
);
6272 /* Compute the boolean return value only if requested. */
6274 goto success_bool_from_val
;
6282 success_bool_from_val
:
6283 target_bool
= emit_store_flag_force (target_bool
, EQ
, target_oval
,
6284 expected
, VOIDmode
, 1, 1);
6286 /* Make sure that the oval output winds up where the caller asked. */
6288 *ptarget_oval
= target_oval
;
6290 *ptarget_bool
= target_bool
;
6294 /* Generate asm volatile("" : : : "memory") as the memory blockage. */
6297 expand_asm_memory_blockage (void)
6301 asm_op
= gen_rtx_ASM_OPERANDS (VOIDmode
, "", "", 0,
6302 rtvec_alloc (0), rtvec_alloc (0),
6303 rtvec_alloc (0), UNKNOWN_LOCATION
);
6304 MEM_VOLATILE_P (asm_op
) = 1;
6306 clob
= gen_rtx_SCRATCH (VOIDmode
);
6307 clob
= gen_rtx_MEM (BLKmode
, clob
);
6308 clob
= gen_rtx_CLOBBER (VOIDmode
, clob
);
6310 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, asm_op
, clob
)));
6313 /* Do not propagate memory accesses across this point. */
6316 expand_memory_blockage (void)
6318 if (targetm
.have_memory_blockage ())
6319 emit_insn (targetm
.gen_memory_blockage ());
6321 expand_asm_memory_blockage ();
6324 /* This routine will either emit the mem_thread_fence pattern or issue a
6325 sync_synchronize to generate a fence for memory model MEMMODEL. */
6328 expand_mem_thread_fence (enum memmodel model
)
6330 if (is_mm_relaxed (model
))
6332 if (targetm
.have_mem_thread_fence ())
6334 emit_insn (targetm
.gen_mem_thread_fence (GEN_INT (model
)));
6335 expand_memory_blockage ();
6337 else if (targetm
.have_memory_barrier ())
6338 emit_insn (targetm
.gen_memory_barrier ());
6339 else if (synchronize_libfunc
!= NULL_RTX
)
6340 emit_library_call (synchronize_libfunc
, LCT_NORMAL
, VOIDmode
);
6342 expand_memory_blockage ();
6345 /* Emit a signal fence with given memory model. */
6348 expand_mem_signal_fence (enum memmodel model
)
6350 /* No machine barrier is required to implement a signal fence, but
6351 a compiler memory barrier must be issued, except for relaxed MM. */
6352 if (!is_mm_relaxed (model
))
6353 expand_memory_blockage ();
6356 /* This function expands the atomic load operation:
6357 return the atomically loaded value in MEM.
6359 MEMMODEL is the memory model variant to use.
6360 TARGET is an option place to stick the return value. */
6363 expand_atomic_load (rtx target
, rtx mem
, enum memmodel model
)
6365 machine_mode mode
= GET_MODE (mem
);
6366 enum insn_code icode
;
6368 /* If the target supports the load directly, great. */
6369 icode
= direct_optab_handler (atomic_load_optab
, mode
);
6370 if (icode
!= CODE_FOR_nothing
)
6372 struct expand_operand ops
[3];
6373 rtx_insn
*last
= get_last_insn ();
6374 if (is_mm_seq_cst (model
))
6375 expand_memory_blockage ();
6377 create_output_operand (&ops
[0], target
, mode
);
6378 create_fixed_operand (&ops
[1], mem
);
6379 create_integer_operand (&ops
[2], model
);
6380 if (maybe_expand_insn (icode
, 3, ops
))
6382 if (!is_mm_relaxed (model
))
6383 expand_memory_blockage ();
6384 return ops
[0].value
;
6386 delete_insns_since (last
);
6389 /* If the size of the object is greater than word size on this target,
6390 then we assume that a load will not be atomic. We could try to
6391 emulate a load with a compare-and-swap operation, but the store that
6392 doing this could result in would be incorrect if this is a volatile
6393 atomic load or targetting read-only-mapped memory. */
6394 if (GET_MODE_PRECISION (mode
) > BITS_PER_WORD
)
6395 /* If there is no atomic load, leave the library call. */
6398 /* Otherwise assume loads are atomic, and emit the proper barriers. */
6399 if (!target
|| target
== const0_rtx
)
6400 target
= gen_reg_rtx (mode
);
6402 /* For SEQ_CST, emit a barrier before the load. */
6403 if (is_mm_seq_cst (model
))
6404 expand_mem_thread_fence (model
);
6406 emit_move_insn (target
, mem
);
6408 /* Emit the appropriate barrier after the load. */
6409 expand_mem_thread_fence (model
);
6414 /* This function expands the atomic store operation:
6415 Atomically store VAL in MEM.
6416 MEMMODEL is the memory model variant to use.
6417 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
6418 function returns const0_rtx if a pattern was emitted. */
6421 expand_atomic_store (rtx mem
, rtx val
, enum memmodel model
, bool use_release
)
6423 machine_mode mode
= GET_MODE (mem
);
6424 enum insn_code icode
;
6425 struct expand_operand ops
[3];
6427 /* If the target supports the store directly, great. */
6428 icode
= direct_optab_handler (atomic_store_optab
, mode
);
6429 if (icode
!= CODE_FOR_nothing
)
6431 rtx_insn
*last
= get_last_insn ();
6432 if (!is_mm_relaxed (model
))
6433 expand_memory_blockage ();
6434 create_fixed_operand (&ops
[0], mem
);
6435 create_input_operand (&ops
[1], val
, mode
);
6436 create_integer_operand (&ops
[2], model
);
6437 if (maybe_expand_insn (icode
, 3, ops
))
6439 if (is_mm_seq_cst (model
))
6440 expand_memory_blockage ();
6443 delete_insns_since (last
);
6446 /* If using __sync_lock_release is a viable alternative, try it.
6447 Note that this will not be set to true if we are expanding a generic
6448 __atomic_store_n. */
6451 icode
= direct_optab_handler (sync_lock_release_optab
, mode
);
6452 if (icode
!= CODE_FOR_nothing
)
6454 create_fixed_operand (&ops
[0], mem
);
6455 create_input_operand (&ops
[1], const0_rtx
, mode
);
6456 if (maybe_expand_insn (icode
, 2, ops
))
6458 /* lock_release is only a release barrier. */
6459 if (is_mm_seq_cst (model
))
6460 expand_mem_thread_fence (model
);
6466 /* If the size of the object is greater than word size on this target,
6467 a default store will not be atomic. */
6468 if (GET_MODE_PRECISION (mode
) > BITS_PER_WORD
)
6470 /* If loads are atomic or we are called to provide a __sync builtin,
6471 we can try a atomic_exchange and throw away the result. Otherwise,
6472 don't do anything so that we do not create an inconsistency between
6473 loads and stores. */
6474 if (can_atomic_load_p (mode
) || is_mm_sync (model
))
6476 rtx target
= maybe_emit_atomic_exchange (NULL_RTX
, mem
, val
, model
);
6478 target
= maybe_emit_compare_and_swap_exchange_loop (NULL_RTX
, mem
,
6486 /* Otherwise assume stores are atomic, and emit the proper barriers. */
6487 expand_mem_thread_fence (model
);
6489 emit_move_insn (mem
, val
);
6491 /* For SEQ_CST, also emit a barrier after the store. */
6492 if (is_mm_seq_cst (model
))
6493 expand_mem_thread_fence (model
);
6499 /* Structure containing the pointers and values required to process the
6500 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
6502 struct atomic_op_functions
6504 direct_optab mem_fetch_before
;
6505 direct_optab mem_fetch_after
;
6506 direct_optab mem_no_result
;
6509 direct_optab no_result
;
6510 enum rtx_code reverse_code
;
6514 /* Fill in structure pointed to by OP with the various optab entries for an
6515 operation of type CODE. */
6518 get_atomic_op_for_code (struct atomic_op_functions
*op
, enum rtx_code code
)
6520 gcc_assert (op
!= NULL
);
6522 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
6523 in the source code during compilation, and the optab entries are not
6524 computable until runtime. Fill in the values at runtime. */
6528 op
->mem_fetch_before
= atomic_fetch_add_optab
;
6529 op
->mem_fetch_after
= atomic_add_fetch_optab
;
6530 op
->mem_no_result
= atomic_add_optab
;
6531 op
->fetch_before
= sync_old_add_optab
;
6532 op
->fetch_after
= sync_new_add_optab
;
6533 op
->no_result
= sync_add_optab
;
6534 op
->reverse_code
= MINUS
;
6537 op
->mem_fetch_before
= atomic_fetch_sub_optab
;
6538 op
->mem_fetch_after
= atomic_sub_fetch_optab
;
6539 op
->mem_no_result
= atomic_sub_optab
;
6540 op
->fetch_before
= sync_old_sub_optab
;
6541 op
->fetch_after
= sync_new_sub_optab
;
6542 op
->no_result
= sync_sub_optab
;
6543 op
->reverse_code
= PLUS
;
6546 op
->mem_fetch_before
= atomic_fetch_xor_optab
;
6547 op
->mem_fetch_after
= atomic_xor_fetch_optab
;
6548 op
->mem_no_result
= atomic_xor_optab
;
6549 op
->fetch_before
= sync_old_xor_optab
;
6550 op
->fetch_after
= sync_new_xor_optab
;
6551 op
->no_result
= sync_xor_optab
;
6552 op
->reverse_code
= XOR
;
6555 op
->mem_fetch_before
= atomic_fetch_and_optab
;
6556 op
->mem_fetch_after
= atomic_and_fetch_optab
;
6557 op
->mem_no_result
= atomic_and_optab
;
6558 op
->fetch_before
= sync_old_and_optab
;
6559 op
->fetch_after
= sync_new_and_optab
;
6560 op
->no_result
= sync_and_optab
;
6561 op
->reverse_code
= UNKNOWN
;
6564 op
->mem_fetch_before
= atomic_fetch_or_optab
;
6565 op
->mem_fetch_after
= atomic_or_fetch_optab
;
6566 op
->mem_no_result
= atomic_or_optab
;
6567 op
->fetch_before
= sync_old_ior_optab
;
6568 op
->fetch_after
= sync_new_ior_optab
;
6569 op
->no_result
= sync_ior_optab
;
6570 op
->reverse_code
= UNKNOWN
;
6573 op
->mem_fetch_before
= atomic_fetch_nand_optab
;
6574 op
->mem_fetch_after
= atomic_nand_fetch_optab
;
6575 op
->mem_no_result
= atomic_nand_optab
;
6576 op
->fetch_before
= sync_old_nand_optab
;
6577 op
->fetch_after
= sync_new_nand_optab
;
6578 op
->no_result
= sync_nand_optab
;
6579 op
->reverse_code
= UNKNOWN
;
6586 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
6587 using memory order MODEL. If AFTER is true the operation needs to return
6588 the value of *MEM after the operation, otherwise the previous value.
6589 TARGET is an optional place to place the result. The result is unused if
6591 Return the result if there is a better sequence, otherwise NULL_RTX. */
6594 maybe_optimize_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
6595 enum memmodel model
, bool after
)
6597 /* If the value is prefetched, or not used, it may be possible to replace
6598 the sequence with a native exchange operation. */
6599 if (!after
|| target
== const0_rtx
)
6601 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
6602 if (code
== AND
&& val
== const0_rtx
)
6604 if (target
== const0_rtx
)
6605 target
= gen_reg_rtx (GET_MODE (mem
));
6606 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
6609 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
6610 if (code
== IOR
&& val
== constm1_rtx
)
6612 if (target
== const0_rtx
)
6613 target
= gen_reg_rtx (GET_MODE (mem
));
6614 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
6621 /* Try to emit an instruction for a specific operation varaition.
6622 OPTAB contains the OP functions.
6623 TARGET is an optional place to return the result. const0_rtx means unused.
6624 MEM is the memory location to operate on.
6625 VAL is the value to use in the operation.
6626 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
6627 MODEL is the memory model, if used.
6628 AFTER is true if the returned result is the value after the operation. */
6631 maybe_emit_op (const struct atomic_op_functions
*optab
, rtx target
, rtx mem
,
6632 rtx val
, bool use_memmodel
, enum memmodel model
, bool after
)
6634 machine_mode mode
= GET_MODE (mem
);
6635 struct expand_operand ops
[4];
6636 enum insn_code icode
;
6640 /* Check to see if there is a result returned. */
6641 if (target
== const0_rtx
)
6645 icode
= direct_optab_handler (optab
->mem_no_result
, mode
);
6646 create_integer_operand (&ops
[2], model
);
6651 icode
= direct_optab_handler (optab
->no_result
, mode
);
6655 /* Otherwise, we need to generate a result. */
6660 icode
= direct_optab_handler (after
? optab
->mem_fetch_after
6661 : optab
->mem_fetch_before
, mode
);
6662 create_integer_operand (&ops
[3], model
);
6667 icode
= optab_handler (after
? optab
->fetch_after
6668 : optab
->fetch_before
, mode
);
6671 create_output_operand (&ops
[op_counter
++], target
, mode
);
6673 if (icode
== CODE_FOR_nothing
)
6676 create_fixed_operand (&ops
[op_counter
++], mem
);
6677 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6678 create_convert_operand_to (&ops
[op_counter
++], val
, mode
, true);
6680 if (maybe_expand_insn (icode
, num_ops
, ops
))
6681 return (target
== const0_rtx
? const0_rtx
: ops
[0].value
);
6687 /* This function expands an atomic fetch_OP or OP_fetch operation:
6688 TARGET is an option place to stick the return value. const0_rtx indicates
6689 the result is unused.
6690 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6691 CODE is the operation being performed (OP)
6692 MEMMODEL is the memory model variant to use.
6693 AFTER is true to return the result of the operation (OP_fetch).
6694 AFTER is false to return the value before the operation (fetch_OP).
6696 This function will *only* generate instructions if there is a direct
6697 optab. No compare and swap loops or libcalls will be generated. */
6700 expand_atomic_fetch_op_no_fallback (rtx target
, rtx mem
, rtx val
,
6701 enum rtx_code code
, enum memmodel model
,
6704 machine_mode mode
= GET_MODE (mem
);
6705 struct atomic_op_functions optab
;
6707 bool unused_result
= (target
== const0_rtx
);
6709 get_atomic_op_for_code (&optab
, code
);
6711 /* Check to see if there are any better instructions. */
6712 result
= maybe_optimize_fetch_op (target
, mem
, val
, code
, model
, after
);
6716 /* Check for the case where the result isn't used and try those patterns. */
6719 /* Try the memory model variant first. */
6720 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, true);
6724 /* Next try the old style withuot a memory model. */
6725 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, true);
6729 /* There is no no-result pattern, so try patterns with a result. */
6733 /* Try the __atomic version. */
6734 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, after
);
6738 /* Try the older __sync version. */
6739 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, after
);
6743 /* If the fetch value can be calculated from the other variation of fetch,
6744 try that operation. */
6745 if (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
)
6747 /* Try the __atomic version, then the older __sync version. */
6748 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, !after
);
6750 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, !after
);
6754 /* If the result isn't used, no need to do compensation code. */
6758 /* Issue compensation code. Fetch_after == fetch_before OP val.
6759 Fetch_before == after REVERSE_OP val. */
6761 code
= optab
.reverse_code
;
6764 result
= expand_simple_binop (mode
, AND
, result
, val
, NULL_RTX
,
6765 true, OPTAB_LIB_WIDEN
);
6766 result
= expand_simple_unop (mode
, NOT
, result
, target
, true);
6769 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
6770 true, OPTAB_LIB_WIDEN
);
6775 /* No direct opcode can be generated. */
6781 /* This function expands an atomic fetch_OP or OP_fetch operation:
6782 TARGET is an option place to stick the return value. const0_rtx indicates
6783 the result is unused.
6784 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6785 CODE is the operation being performed (OP)
6786 MEMMODEL is the memory model variant to use.
6787 AFTER is true to return the result of the operation (OP_fetch).
6788 AFTER is false to return the value before the operation (fetch_OP). */
6790 expand_atomic_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
6791 enum memmodel model
, bool after
)
6793 machine_mode mode
= GET_MODE (mem
);
6795 bool unused_result
= (target
== const0_rtx
);
6797 /* If loads are not atomic for the required size and we are not called to
6798 provide a __sync builtin, do not do anything so that we stay consistent
6799 with atomic loads of the same size. */
6800 if (!can_atomic_load_p (mode
) && !is_mm_sync (model
))
6803 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, val
, code
, model
,
6809 /* Add/sub can be implemented by doing the reverse operation with -(val). */
6810 if (code
== PLUS
|| code
== MINUS
)
6813 enum rtx_code reverse
= (code
== PLUS
? MINUS
: PLUS
);
6816 tmp
= expand_simple_unop (mode
, NEG
, val
, NULL_RTX
, true);
6817 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, tmp
, reverse
,
6821 /* PLUS worked so emit the insns and return. */
6828 /* PLUS did not work, so throw away the negation code and continue. */
6832 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
6833 if (!can_compare_and_swap_p (mode
, false))
6837 enum rtx_code orig_code
= code
;
6838 struct atomic_op_functions optab
;
6840 get_atomic_op_for_code (&optab
, code
);
6841 libfunc
= optab_libfunc (after
? optab
.fetch_after
6842 : optab
.fetch_before
, mode
);
6844 && (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
))
6848 code
= optab
.reverse_code
;
6849 libfunc
= optab_libfunc (after
? optab
.fetch_before
6850 : optab
.fetch_after
, mode
);
6852 if (libfunc
!= NULL
)
6854 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
6855 result
= emit_library_call_value (libfunc
, NULL
, LCT_NORMAL
, mode
,
6856 addr
, ptr_mode
, val
, mode
);
6858 if (!unused_result
&& fixup
)
6859 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
6860 true, OPTAB_LIB_WIDEN
);
6864 /* We need the original code for any further attempts. */
6868 /* If nothing else has succeeded, default to a compare and swap loop. */
6869 if (can_compare_and_swap_p (mode
, true))
6872 rtx t0
= gen_reg_rtx (mode
), t1
;
6876 /* If the result is used, get a register for it. */
6879 if (!target
|| !register_operand (target
, mode
))
6880 target
= gen_reg_rtx (mode
);
6881 /* If fetch_before, copy the value now. */
6883 emit_move_insn (target
, t0
);
6886 target
= const0_rtx
;
6891 t1
= expand_simple_binop (mode
, AND
, t1
, val
, NULL_RTX
,
6892 true, OPTAB_LIB_WIDEN
);
6893 t1
= expand_simple_unop (mode
, code
, t1
, NULL_RTX
, true);
6896 t1
= expand_simple_binop (mode
, code
, t1
, val
, NULL_RTX
, true,
6899 /* For after, copy the value now. */
6900 if (!unused_result
&& after
)
6901 emit_move_insn (target
, t1
);
6902 insn
= get_insns ();
6905 if (t1
!= NULL
&& expand_compare_and_swap_loop (mem
, t0
, t1
, insn
))
6912 /* Return true if OPERAND is suitable for operand number OPNO of
6913 instruction ICODE. */
6916 insn_operand_matches (enum insn_code icode
, unsigned int opno
, rtx operand
)
6918 return (!insn_data
[(int) icode
].operand
[opno
].predicate
6919 || (insn_data
[(int) icode
].operand
[opno
].predicate
6920 (operand
, insn_data
[(int) icode
].operand
[opno
].mode
)));
6923 /* TARGET is a target of a multiword operation that we are going to
6924 implement as a series of word-mode operations. Return true if
6925 TARGET is suitable for this purpose. */
6928 valid_multiword_target_p (rtx target
)
6933 mode
= GET_MODE (target
);
6934 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
+= UNITS_PER_WORD
)
6935 if (!validate_subreg (word_mode
, mode
, target
, i
))
6940 /* Like maybe_legitimize_operand, but do not change the code of the
6941 current rtx value. */
6944 maybe_legitimize_operand_same_code (enum insn_code icode
, unsigned int opno
,
6945 struct expand_operand
*op
)
6947 /* See if the operand matches in its current form. */
6948 if (insn_operand_matches (icode
, opno
, op
->value
))
6951 /* If the operand is a memory whose address has no side effects,
6952 try forcing the address into a non-virtual pseudo register.
6953 The check for side effects is important because copy_to_mode_reg
6954 cannot handle things like auto-modified addresses. */
6955 if (insn_data
[(int) icode
].operand
[opno
].allows_mem
&& MEM_P (op
->value
))
6960 addr
= XEXP (mem
, 0);
6961 if (!(REG_P (addr
) && REGNO (addr
) > LAST_VIRTUAL_REGISTER
)
6962 && !side_effects_p (addr
))
6967 last
= get_last_insn ();
6968 mode
= get_address_mode (mem
);
6969 mem
= replace_equiv_address (mem
, copy_to_mode_reg (mode
, addr
));
6970 if (insn_operand_matches (icode
, opno
, mem
))
6975 delete_insns_since (last
);
6982 /* Try to make OP match operand OPNO of instruction ICODE. Return true
6983 on success, storing the new operand value back in OP. */
6986 maybe_legitimize_operand (enum insn_code icode
, unsigned int opno
,
6987 struct expand_operand
*op
)
6989 machine_mode mode
, imode
;
6990 bool old_volatile_ok
, result
;
6996 old_volatile_ok
= volatile_ok
;
6998 result
= maybe_legitimize_operand_same_code (icode
, opno
, op
);
6999 volatile_ok
= old_volatile_ok
;
7003 gcc_assert (mode
!= VOIDmode
);
7005 && op
->value
!= const0_rtx
7006 && GET_MODE (op
->value
) == mode
7007 && maybe_legitimize_operand_same_code (icode
, opno
, op
))
7010 op
->value
= gen_reg_rtx (mode
);
7016 gcc_assert (mode
!= VOIDmode
);
7017 gcc_assert (GET_MODE (op
->value
) == VOIDmode
7018 || GET_MODE (op
->value
) == mode
);
7019 if (maybe_legitimize_operand_same_code (icode
, opno
, op
))
7022 op
->value
= copy_to_mode_reg (mode
, op
->value
);
7025 case EXPAND_CONVERT_TO
:
7026 gcc_assert (mode
!= VOIDmode
);
7027 op
->value
= convert_to_mode (mode
, op
->value
, op
->unsigned_p
);
7030 case EXPAND_CONVERT_FROM
:
7031 if (GET_MODE (op
->value
) != VOIDmode
)
7032 mode
= GET_MODE (op
->value
);
7034 /* The caller must tell us what mode this value has. */
7035 gcc_assert (mode
!= VOIDmode
);
7037 imode
= insn_data
[(int) icode
].operand
[opno
].mode
;
7038 if (imode
!= VOIDmode
&& imode
!= mode
)
7040 op
->value
= convert_modes (imode
, mode
, op
->value
, op
->unsigned_p
);
7045 case EXPAND_ADDRESS
:
7046 op
->value
= convert_memory_address (as_a
<scalar_int_mode
> (mode
),
7050 case EXPAND_INTEGER
:
7051 mode
= insn_data
[(int) icode
].operand
[opno
].mode
;
7052 if (mode
!= VOIDmode
&& const_int_operand (op
->value
, mode
))
7056 return insn_operand_matches (icode
, opno
, op
->value
);
7059 /* Make OP describe an input operand that should have the same value
7060 as VALUE, after any mode conversion that the target might request.
7061 TYPE is the type of VALUE. */
7064 create_convert_operand_from_type (struct expand_operand
*op
,
7065 rtx value
, tree type
)
7067 create_convert_operand_from (op
, value
, TYPE_MODE (type
),
7068 TYPE_UNSIGNED (type
));
7071 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
7072 of instruction ICODE. Return true on success, leaving the new operand
7073 values in the OPS themselves. Emit no code on failure. */
7076 maybe_legitimize_operands (enum insn_code icode
, unsigned int opno
,
7077 unsigned int nops
, struct expand_operand
*ops
)
7082 last
= get_last_insn ();
7083 for (i
= 0; i
< nops
; i
++)
7084 if (!maybe_legitimize_operand (icode
, opno
+ i
, &ops
[i
]))
7086 delete_insns_since (last
);
7092 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
7093 as its operands. Return the instruction pattern on success,
7094 and emit any necessary set-up code. Return null and emit no
7098 maybe_gen_insn (enum insn_code icode
, unsigned int nops
,
7099 struct expand_operand
*ops
)
7101 gcc_assert (nops
== (unsigned int) insn_data
[(int) icode
].n_generator_args
);
7102 if (!maybe_legitimize_operands (icode
, 0, nops
, ops
))
7108 return GEN_FCN (icode
) (ops
[0].value
);
7110 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
);
7112 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
);
7114 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7117 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7118 ops
[3].value
, ops
[4].value
);
7120 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7121 ops
[3].value
, ops
[4].value
, ops
[5].value
);
7123 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7124 ops
[3].value
, ops
[4].value
, ops
[5].value
,
7127 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7128 ops
[3].value
, ops
[4].value
, ops
[5].value
,
7129 ops
[6].value
, ops
[7].value
);
7131 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7132 ops
[3].value
, ops
[4].value
, ops
[5].value
,
7133 ops
[6].value
, ops
[7].value
, ops
[8].value
);
7138 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7139 as its operands. Return true on success and emit no code on failure. */
7142 maybe_expand_insn (enum insn_code icode
, unsigned int nops
,
7143 struct expand_operand
*ops
)
7145 rtx_insn
*pat
= maybe_gen_insn (icode
, nops
, ops
);
7154 /* Like maybe_expand_insn, but for jumps. */
7157 maybe_expand_jump_insn (enum insn_code icode
, unsigned int nops
,
7158 struct expand_operand
*ops
)
7160 rtx_insn
*pat
= maybe_gen_insn (icode
, nops
, ops
);
7163 emit_jump_insn (pat
);
7169 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
7173 expand_insn (enum insn_code icode
, unsigned int nops
,
7174 struct expand_operand
*ops
)
7176 if (!maybe_expand_insn (icode
, nops
, ops
))
7180 /* Like expand_insn, but for jumps. */
7183 expand_jump_insn (enum insn_code icode
, unsigned int nops
,
7184 struct expand_operand
*ops
)
7186 if (!maybe_expand_jump_insn (icode
, nops
, ops
))