1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
34 #include "diagnostic-core.h"
36 /* Include insn-config.h before expr.h so that HAVE_conditional_move
37 is properly defined. */
38 #include "stor-layout.h"
43 #include "optabs-tree.h"
46 static void prepare_float_lib_cmp (rtx
, rtx
, enum rtx_code
, rtx
*,
48 static rtx
expand_unop_direct (machine_mode
, optab
, rtx
, rtx
, int);
49 static void emit_libcall_block_1 (rtx_insn
*, rtx
, rtx
, rtx
, bool);
51 /* Debug facility for use in GDB. */
52 void debug_optab_libfuncs (void);
54 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
55 the result of operation CODE applied to OP0 (and OP1 if it is a binary
58 If the last insn does not set TARGET, don't do anything, but return 1.
60 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
61 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
62 try again, ensuring that TARGET is not one of the operands. */
65 add_equal_note (rtx_insn
*insns
, rtx target
, enum rtx_code code
, rtx op0
, rtx op1
)
71 gcc_assert (insns
&& INSN_P (insns
) && NEXT_INSN (insns
));
73 if (GET_RTX_CLASS (code
) != RTX_COMM_ARITH
74 && GET_RTX_CLASS (code
) != RTX_BIN_ARITH
75 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
76 && GET_RTX_CLASS (code
) != RTX_COMPARE
77 && GET_RTX_CLASS (code
) != RTX_UNARY
)
80 if (GET_CODE (target
) == ZERO_EXTRACT
)
83 for (last_insn
= insns
;
84 NEXT_INSN (last_insn
) != NULL_RTX
;
85 last_insn
= NEXT_INSN (last_insn
))
88 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
89 a value changing in the insn, so the note would be invalid for CSE. */
90 if (reg_overlap_mentioned_p (target
, op0
)
91 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
94 && (rtx_equal_p (target
, op0
)
95 || (op1
&& rtx_equal_p (target
, op1
))))
97 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
98 over expanding it as temp = MEM op X, MEM = temp. If the target
99 supports MEM = MEM op X instructions, it is sometimes too hard
100 to reconstruct that form later, especially if X is also a memory,
101 and due to multiple occurrences of addresses the address might
102 be forced into register unnecessarily.
103 Note that not emitting the REG_EQUIV note might inhibit
104 CSE in some cases. */
105 set
= single_set (last_insn
);
107 && GET_CODE (SET_SRC (set
)) == code
108 && MEM_P (SET_DEST (set
))
109 && (rtx_equal_p (SET_DEST (set
), XEXP (SET_SRC (set
), 0))
110 || (op1
&& rtx_equal_p (SET_DEST (set
),
111 XEXP (SET_SRC (set
), 1)))))
117 set
= set_for_reg_notes (last_insn
);
121 if (! rtx_equal_p (SET_DEST (set
), target
)
122 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
123 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
124 || ! rtx_equal_p (XEXP (SET_DEST (set
), 0), target
)))
127 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
137 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (target
) != GET_MODE (op0
))
139 note
= gen_rtx_fmt_e (code
, GET_MODE (op0
), copy_rtx (op0
));
140 if (GET_MODE_SIZE (GET_MODE (op0
))
141 > GET_MODE_SIZE (GET_MODE (target
)))
142 note
= simplify_gen_unary (TRUNCATE
, GET_MODE (target
),
143 note
, GET_MODE (op0
));
145 note
= simplify_gen_unary (ZERO_EXTEND
, GET_MODE (target
),
146 note
, GET_MODE (op0
));
151 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
155 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
157 set_unique_reg_note (last_insn
, REG_EQUAL
, note
);
162 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
163 for a widening operation would be. In most cases this would be OP0, but if
164 that's a constant it'll be VOIDmode, which isn't useful. */
167 widened_mode (machine_mode to_mode
, rtx op0
, rtx op1
)
169 machine_mode m0
= GET_MODE (op0
);
170 machine_mode m1
= GET_MODE (op1
);
173 if (m0
== VOIDmode
&& m1
== VOIDmode
)
175 else if (m0
== VOIDmode
|| GET_MODE_SIZE (m0
) < GET_MODE_SIZE (m1
))
180 if (GET_MODE_SIZE (result
) > GET_MODE_SIZE (to_mode
))
186 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
187 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
188 not actually do a sign-extend or zero-extend, but can leave the
189 higher-order bits of the result rtx undefined, for example, in the case
190 of logical operations, but not right shifts. */
193 widen_operand (rtx op
, machine_mode mode
, machine_mode oldmode
,
194 int unsignedp
, int no_extend
)
198 /* If we don't have to extend and this is a constant, return it. */
199 if (no_extend
&& GET_MODE (op
) == VOIDmode
)
202 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
203 extend since it will be more efficient to do so unless the signedness of
204 a promoted object differs from our extension. */
206 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)
207 && SUBREG_CHECK_PROMOTED_SIGN (op
, unsignedp
)))
208 return convert_modes (mode
, oldmode
, op
, unsignedp
);
210 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
212 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
213 return gen_lowpart (mode
, force_reg (GET_MODE (op
), op
));
215 /* Otherwise, get an object of MODE, clobber it, and set the low-order
218 result
= gen_reg_rtx (mode
);
219 emit_clobber (result
);
220 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
224 /* Expand vector widening operations.
226 There are two different classes of operations handled here:
227 1) Operations whose result is wider than all the arguments to the operation.
228 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
229 In this case OP0 and optionally OP1 would be initialized,
230 but WIDE_OP wouldn't (not relevant for this case).
231 2) Operations whose result is of the same size as the last argument to the
232 operation, but wider than all the other arguments to the operation.
233 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
234 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
236 E.g, when called to expand the following operations, this is how
237 the arguments will be initialized:
239 widening-sum 2 oprnd0 - oprnd1
240 widening-dot-product 3 oprnd0 oprnd1 oprnd2
241 widening-mult 2 oprnd0 oprnd1 -
242 type-promotion (vec-unpack) 1 oprnd0 - - */
245 expand_widen_pattern_expr (sepops ops
, rtx op0
, rtx op1
, rtx wide_op
,
246 rtx target
, int unsignedp
)
248 struct expand_operand eops
[4];
249 tree oprnd0
, oprnd1
, oprnd2
;
250 machine_mode wmode
= VOIDmode
, tmode0
, tmode1
= VOIDmode
;
251 optab widen_pattern_optab
;
252 enum insn_code icode
;
253 int nops
= TREE_CODE_LENGTH (ops
->code
);
257 tmode0
= TYPE_MODE (TREE_TYPE (oprnd0
));
258 widen_pattern_optab
=
259 optab_for_tree_code (ops
->code
, TREE_TYPE (oprnd0
), optab_default
);
260 if (ops
->code
== WIDEN_MULT_PLUS_EXPR
261 || ops
->code
== WIDEN_MULT_MINUS_EXPR
)
262 icode
= find_widening_optab_handler (widen_pattern_optab
,
263 TYPE_MODE (TREE_TYPE (ops
->op2
)),
266 icode
= optab_handler (widen_pattern_optab
, tmode0
);
267 gcc_assert (icode
!= CODE_FOR_nothing
);
272 tmode1
= TYPE_MODE (TREE_TYPE (oprnd1
));
275 /* The last operand is of a wider mode than the rest of the operands. */
280 gcc_assert (tmode1
== tmode0
);
283 wmode
= TYPE_MODE (TREE_TYPE (oprnd2
));
287 create_output_operand (&eops
[op
++], target
, TYPE_MODE (ops
->type
));
288 create_convert_operand_from (&eops
[op
++], op0
, tmode0
, unsignedp
);
290 create_convert_operand_from (&eops
[op
++], op1
, tmode1
, unsignedp
);
292 create_convert_operand_from (&eops
[op
++], wide_op
, wmode
, unsignedp
);
293 expand_insn (icode
, op
, eops
);
294 return eops
[0].value
;
297 /* Generate code to perform an operation specified by TERNARY_OPTAB
298 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
300 UNSIGNEDP is for the case where we have to widen the operands
301 to perform the operation. It says to use zero-extension.
303 If TARGET is nonzero, the value
304 is generated there, if it is convenient to do so.
305 In all cases an rtx is returned for the locus of the value;
306 this may or may not be TARGET. */
309 expand_ternary_op (machine_mode mode
, optab ternary_optab
, rtx op0
,
310 rtx op1
, rtx op2
, rtx target
, int unsignedp
)
312 struct expand_operand ops
[4];
313 enum insn_code icode
= optab_handler (ternary_optab
, mode
);
315 gcc_assert (optab_handler (ternary_optab
, mode
) != CODE_FOR_nothing
);
317 create_output_operand (&ops
[0], target
, mode
);
318 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
319 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
320 create_convert_operand_from (&ops
[3], op2
, mode
, unsignedp
);
321 expand_insn (icode
, 4, ops
);
326 /* Like expand_binop, but return a constant rtx if the result can be
327 calculated at compile time. The arguments and return value are
328 otherwise the same as for expand_binop. */
331 simplify_expand_binop (machine_mode mode
, optab binoptab
,
332 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
333 enum optab_methods methods
)
335 if (CONSTANT_P (op0
) && CONSTANT_P (op1
))
337 rtx x
= simplify_binary_operation (optab_to_code (binoptab
),
343 return expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
);
346 /* Like simplify_expand_binop, but always put the result in TARGET.
347 Return true if the expansion succeeded. */
350 force_expand_binop (machine_mode mode
, optab binoptab
,
351 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
352 enum optab_methods methods
)
354 rtx x
= simplify_expand_binop (mode
, binoptab
, op0
, op1
,
355 target
, unsignedp
, methods
);
359 emit_move_insn (target
, x
);
363 /* Create a new vector value in VMODE with all elements set to OP. The
364 mode of OP must be the element mode of VMODE. If OP is a constant,
365 then the return value will be a constant. */
368 expand_vector_broadcast (machine_mode vmode
, rtx op
)
370 enum insn_code icode
;
375 gcc_checking_assert (VECTOR_MODE_P (vmode
));
377 n
= GET_MODE_NUNITS (vmode
);
378 vec
= rtvec_alloc (n
);
379 for (i
= 0; i
< n
; ++i
)
380 RTVEC_ELT (vec
, i
) = op
;
383 return gen_rtx_CONST_VECTOR (vmode
, vec
);
385 /* ??? If the target doesn't have a vec_init, then we have no easy way
386 of performing this operation. Most of this sort of generic support
387 is hidden away in the vector lowering support in gimple. */
388 icode
= optab_handler (vec_init_optab
, vmode
);
389 if (icode
== CODE_FOR_nothing
)
392 ret
= gen_reg_rtx (vmode
);
393 emit_insn (GEN_FCN (icode
) (ret
, gen_rtx_PARALLEL (vmode
, vec
)));
398 /* This subroutine of expand_doubleword_shift handles the cases in which
399 the effective shift value is >= BITS_PER_WORD. The arguments and return
400 value are the same as for the parent routine, except that SUPERWORD_OP1
401 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
402 INTO_TARGET may be null if the caller has decided to calculate it. */
405 expand_superword_shift (optab binoptab
, rtx outof_input
, rtx superword_op1
,
406 rtx outof_target
, rtx into_target
,
407 int unsignedp
, enum optab_methods methods
)
409 if (into_target
!= 0)
410 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, superword_op1
,
411 into_target
, unsignedp
, methods
))
414 if (outof_target
!= 0)
416 /* For a signed right shift, we must fill OUTOF_TARGET with copies
417 of the sign bit, otherwise we must fill it with zeros. */
418 if (binoptab
!= ashr_optab
)
419 emit_move_insn (outof_target
, CONST0_RTX (word_mode
));
421 if (!force_expand_binop (word_mode
, binoptab
,
422 outof_input
, GEN_INT (BITS_PER_WORD
- 1),
423 outof_target
, unsignedp
, methods
))
429 /* This subroutine of expand_doubleword_shift handles the cases in which
430 the effective shift value is < BITS_PER_WORD. The arguments and return
431 value are the same as for the parent routine. */
434 expand_subword_shift (machine_mode op1_mode
, optab binoptab
,
435 rtx outof_input
, rtx into_input
, rtx op1
,
436 rtx outof_target
, rtx into_target
,
437 int unsignedp
, enum optab_methods methods
,
438 unsigned HOST_WIDE_INT shift_mask
)
440 optab reverse_unsigned_shift
, unsigned_shift
;
443 reverse_unsigned_shift
= (binoptab
== ashl_optab
? lshr_optab
: ashl_optab
);
444 unsigned_shift
= (binoptab
== ashl_optab
? ashl_optab
: lshr_optab
);
446 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
447 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
448 the opposite direction to BINOPTAB. */
449 if (CONSTANT_P (op1
) || shift_mask
>= BITS_PER_WORD
)
451 carries
= outof_input
;
452 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
,
453 op1_mode
), op1_mode
);
454 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
459 /* We must avoid shifting by BITS_PER_WORD bits since that is either
460 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
461 has unknown behavior. Do a single shift first, then shift by the
462 remainder. It's OK to use ~OP1 as the remainder if shift counts
463 are truncated to the mode size. */
464 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
465 outof_input
, const1_rtx
, 0, unsignedp
, methods
);
466 if (shift_mask
== BITS_PER_WORD
- 1)
468 tmp
= immed_wide_int_const
469 (wi::minus_one (GET_MODE_PRECISION (op1_mode
)), op1_mode
);
470 tmp
= simplify_expand_binop (op1_mode
, xor_optab
, op1
, tmp
,
475 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
- 1,
476 op1_mode
), op1_mode
);
477 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
481 if (tmp
== 0 || carries
== 0)
483 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
484 carries
, tmp
, 0, unsignedp
, methods
);
488 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
489 so the result can go directly into INTO_TARGET if convenient. */
490 tmp
= expand_binop (word_mode
, unsigned_shift
, into_input
, op1
,
491 into_target
, unsignedp
, methods
);
495 /* Now OR in the bits carried over from OUTOF_INPUT. */
496 if (!force_expand_binop (word_mode
, ior_optab
, tmp
, carries
,
497 into_target
, unsignedp
, methods
))
500 /* Use a standard word_mode shift for the out-of half. */
501 if (outof_target
!= 0)
502 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
503 outof_target
, unsignedp
, methods
))
510 /* Try implementing expand_doubleword_shift using conditional moves.
511 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
512 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
513 are the shift counts to use in the former and latter case. All other
514 arguments are the same as the parent routine. */
517 expand_doubleword_shift_condmove (machine_mode op1_mode
, optab binoptab
,
518 enum rtx_code cmp_code
, rtx cmp1
, rtx cmp2
,
519 rtx outof_input
, rtx into_input
,
520 rtx subword_op1
, rtx superword_op1
,
521 rtx outof_target
, rtx into_target
,
522 int unsignedp
, enum optab_methods methods
,
523 unsigned HOST_WIDE_INT shift_mask
)
525 rtx outof_superword
, into_superword
;
527 /* Put the superword version of the output into OUTOF_SUPERWORD and
529 outof_superword
= outof_target
!= 0 ? gen_reg_rtx (word_mode
) : 0;
530 if (outof_target
!= 0 && subword_op1
== superword_op1
)
532 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
533 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
534 into_superword
= outof_target
;
535 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
536 outof_superword
, 0, unsignedp
, methods
))
541 into_superword
= gen_reg_rtx (word_mode
);
542 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
543 outof_superword
, into_superword
,
548 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
549 if (!expand_subword_shift (op1_mode
, binoptab
,
550 outof_input
, into_input
, subword_op1
,
551 outof_target
, into_target
,
552 unsignedp
, methods
, shift_mask
))
555 /* Select between them. Do the INTO half first because INTO_SUPERWORD
556 might be the current value of OUTOF_TARGET. */
557 if (!emit_conditional_move (into_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
558 into_target
, into_superword
, word_mode
, false))
561 if (outof_target
!= 0)
562 if (!emit_conditional_move (outof_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
563 outof_target
, outof_superword
,
570 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
571 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
572 input operand; the shift moves bits in the direction OUTOF_INPUT->
573 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
574 of the target. OP1 is the shift count and OP1_MODE is its mode.
575 If OP1 is constant, it will have been truncated as appropriate
576 and is known to be nonzero.
578 If SHIFT_MASK is zero, the result of word shifts is undefined when the
579 shift count is outside the range [0, BITS_PER_WORD). This routine must
580 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
582 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
583 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
584 fill with zeros or sign bits as appropriate.
586 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
587 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
588 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
589 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
592 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
593 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
594 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
595 function wants to calculate it itself.
597 Return true if the shift could be successfully synthesized. */
600 expand_doubleword_shift (machine_mode op1_mode
, optab binoptab
,
601 rtx outof_input
, rtx into_input
, rtx op1
,
602 rtx outof_target
, rtx into_target
,
603 int unsignedp
, enum optab_methods methods
,
604 unsigned HOST_WIDE_INT shift_mask
)
606 rtx superword_op1
, tmp
, cmp1
, cmp2
;
607 enum rtx_code cmp_code
;
609 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
610 fill the result with sign or zero bits as appropriate. If so, the value
611 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
612 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
613 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
615 This isn't worthwhile for constant shifts since the optimizers will
616 cope better with in-range shift counts. */
617 if (shift_mask
>= BITS_PER_WORD
619 && !CONSTANT_P (op1
))
621 if (!expand_doubleword_shift (op1_mode
, binoptab
,
622 outof_input
, into_input
, op1
,
624 unsignedp
, methods
, shift_mask
))
626 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
627 outof_target
, unsignedp
, methods
))
632 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
633 is true when the effective shift value is less than BITS_PER_WORD.
634 Set SUPERWORD_OP1 to the shift count that should be used to shift
635 OUTOF_INPUT into INTO_TARGET when the condition is false. */
636 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
, op1_mode
), op1_mode
);
637 if (!CONSTANT_P (op1
) && shift_mask
== BITS_PER_WORD
- 1)
639 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
640 is a subword shift count. */
641 cmp1
= simplify_expand_binop (op1_mode
, and_optab
, op1
, tmp
,
643 cmp2
= CONST0_RTX (op1_mode
);
649 /* Set CMP1 to OP1 - BITS_PER_WORD. */
650 cmp1
= simplify_expand_binop (op1_mode
, sub_optab
, op1
, tmp
,
652 cmp2
= CONST0_RTX (op1_mode
);
654 superword_op1
= cmp1
;
659 /* If we can compute the condition at compile time, pick the
660 appropriate subroutine. */
661 tmp
= simplify_relational_operation (cmp_code
, SImode
, op1_mode
, cmp1
, cmp2
);
662 if (tmp
!= 0 && CONST_INT_P (tmp
))
664 if (tmp
== const0_rtx
)
665 return expand_superword_shift (binoptab
, outof_input
, superword_op1
,
666 outof_target
, into_target
,
669 return expand_subword_shift (op1_mode
, binoptab
,
670 outof_input
, into_input
, op1
,
671 outof_target
, into_target
,
672 unsignedp
, methods
, shift_mask
);
675 /* Try using conditional moves to generate straight-line code. */
676 if (HAVE_conditional_move
)
678 rtx_insn
*start
= get_last_insn ();
679 if (expand_doubleword_shift_condmove (op1_mode
, binoptab
,
680 cmp_code
, cmp1
, cmp2
,
681 outof_input
, into_input
,
683 outof_target
, into_target
,
684 unsignedp
, methods
, shift_mask
))
686 delete_insns_since (start
);
689 /* As a last resort, use branches to select the correct alternative. */
690 rtx_code_label
*subword_label
= gen_label_rtx ();
691 rtx_code_label
*done_label
= gen_label_rtx ();
694 do_compare_rtx_and_jump (cmp1
, cmp2
, cmp_code
, false, op1_mode
,
695 0, 0, subword_label
, -1);
698 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
699 outof_target
, into_target
,
703 emit_jump_insn (targetm
.gen_jump (done_label
));
705 emit_label (subword_label
);
707 if (!expand_subword_shift (op1_mode
, binoptab
,
708 outof_input
, into_input
, op1
,
709 outof_target
, into_target
,
710 unsignedp
, methods
, shift_mask
))
713 emit_label (done_label
);
717 /* Subroutine of expand_binop. Perform a double word multiplication of
718 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
719 as the target's word_mode. This function return NULL_RTX if anything
720 goes wrong, in which case it may have already emitted instructions
721 which need to be deleted.
723 If we want to multiply two two-word values and have normal and widening
724 multiplies of single-word values, we can do this with three smaller
727 The multiplication proceeds as follows:
728 _______________________
729 [__op0_high_|__op0_low__]
730 _______________________
731 * [__op1_high_|__op1_low__]
732 _______________________________________________
733 _______________________
734 (1) [__op0_low__*__op1_low__]
735 _______________________
736 (2a) [__op0_low__*__op1_high_]
737 _______________________
738 (2b) [__op0_high_*__op1_low__]
739 _______________________
740 (3) [__op0_high_*__op1_high_]
743 This gives a 4-word result. Since we are only interested in the
744 lower 2 words, partial result (3) and the upper words of (2a) and
745 (2b) don't need to be calculated. Hence (2a) and (2b) can be
746 calculated using non-widening multiplication.
748 (1), however, needs to be calculated with an unsigned widening
749 multiplication. If this operation is not directly supported we
750 try using a signed widening multiplication and adjust the result.
751 This adjustment works as follows:
753 If both operands are positive then no adjustment is needed.
755 If the operands have different signs, for example op0_low < 0 and
756 op1_low >= 0, the instruction treats the most significant bit of
757 op0_low as a sign bit instead of a bit with significance
758 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
759 with 2**BITS_PER_WORD - op0_low, and two's complements the
760 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
763 Similarly, if both operands are negative, we need to add
764 (op0_low + op1_low) * 2**BITS_PER_WORD.
766 We use a trick to adjust quickly. We logically shift op0_low right
767 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
768 op0_high (op1_high) before it is used to calculate 2b (2a). If no
769 logical shift exists, we do an arithmetic right shift and subtract
773 expand_doubleword_mult (machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
774 bool umulp
, enum optab_methods methods
)
776 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
777 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
778 rtx wordm1
= umulp
? NULL_RTX
: GEN_INT (BITS_PER_WORD
- 1);
779 rtx product
, adjust
, product_high
, temp
;
781 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
782 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
783 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
784 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
786 /* If we're using an unsigned multiply to directly compute the product
787 of the low-order words of the operands and perform any required
788 adjustments of the operands, we begin by trying two more multiplications
789 and then computing the appropriate sum.
791 We have checked above that the required addition is provided.
792 Full-word addition will normally always succeed, especially if
793 it is provided at all, so we don't worry about its failure. The
794 multiplication may well fail, however, so we do handle that. */
798 /* ??? This could be done with emit_store_flag where available. */
799 temp
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
800 NULL_RTX
, 1, methods
);
802 op0_high
= expand_binop (word_mode
, add_optab
, op0_high
, temp
,
803 NULL_RTX
, 0, OPTAB_DIRECT
);
806 temp
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
807 NULL_RTX
, 0, methods
);
810 op0_high
= expand_binop (word_mode
, sub_optab
, op0_high
, temp
,
811 NULL_RTX
, 0, OPTAB_DIRECT
);
818 adjust
= expand_binop (word_mode
, smul_optab
, op0_high
, op1_low
,
819 NULL_RTX
, 0, OPTAB_DIRECT
);
823 /* OP0_HIGH should now be dead. */
827 /* ??? This could be done with emit_store_flag where available. */
828 temp
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
829 NULL_RTX
, 1, methods
);
831 op1_high
= expand_binop (word_mode
, add_optab
, op1_high
, temp
,
832 NULL_RTX
, 0, OPTAB_DIRECT
);
835 temp
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
836 NULL_RTX
, 0, methods
);
839 op1_high
= expand_binop (word_mode
, sub_optab
, op1_high
, temp
,
840 NULL_RTX
, 0, OPTAB_DIRECT
);
847 temp
= expand_binop (word_mode
, smul_optab
, op1_high
, op0_low
,
848 NULL_RTX
, 0, OPTAB_DIRECT
);
852 /* OP1_HIGH should now be dead. */
854 adjust
= expand_binop (word_mode
, add_optab
, adjust
, temp
,
855 NULL_RTX
, 0, OPTAB_DIRECT
);
857 if (target
&& !REG_P (target
))
861 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
862 target
, 1, OPTAB_DIRECT
);
864 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
865 target
, 1, OPTAB_DIRECT
);
870 product_high
= operand_subword (product
, high
, 1, mode
);
871 adjust
= expand_binop (word_mode
, add_optab
, product_high
, adjust
,
872 NULL_RTX
, 0, OPTAB_DIRECT
);
873 emit_move_insn (product_high
, adjust
);
877 /* Wrapper around expand_binop which takes an rtx code to specify
878 the operation to perform, not an optab pointer. All other
879 arguments are the same. */
881 expand_simple_binop (machine_mode mode
, enum rtx_code code
, rtx op0
,
882 rtx op1
, rtx target
, int unsignedp
,
883 enum optab_methods methods
)
885 optab binop
= code_to_optab (code
);
888 return expand_binop (mode
, binop
, op0
, op1
, target
, unsignedp
, methods
);
891 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
892 binop. Order them according to commutative_operand_precedence and, if
893 possible, try to put TARGET or a pseudo first. */
895 swap_commutative_operands_with_target (rtx target
, rtx op0
, rtx op1
)
897 int op0_prec
= commutative_operand_precedence (op0
);
898 int op1_prec
= commutative_operand_precedence (op1
);
900 if (op0_prec
< op1_prec
)
903 if (op0_prec
> op1_prec
)
906 /* With equal precedence, both orders are ok, but it is better if the
907 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
908 if (target
== 0 || REG_P (target
))
909 return (REG_P (op1
) && !REG_P (op0
)) || target
== op1
;
911 return rtx_equal_p (op1
, target
);
914 /* Return true if BINOPTAB implements a shift operation. */
917 shift_optab_p (optab binoptab
)
919 switch (optab_to_code (binoptab
))
935 /* Return true if BINOPTAB implements a commutative binary operation. */
938 commutative_optab_p (optab binoptab
)
940 return (GET_RTX_CLASS (optab_to_code (binoptab
)) == RTX_COMM_ARITH
941 || binoptab
== smul_widen_optab
942 || binoptab
== umul_widen_optab
943 || binoptab
== smul_highpart_optab
944 || binoptab
== umul_highpart_optab
);
947 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
948 optimizing, and if the operand is a constant that costs more than
949 1 instruction, force the constant into a register and return that
950 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
953 avoid_expensive_constant (machine_mode mode
, optab binoptab
,
954 int opn
, rtx x
, bool unsignedp
)
956 bool speed
= optimize_insn_for_speed_p ();
961 && (rtx_cost (x
, mode
, optab_to_code (binoptab
), opn
, speed
)
962 > set_src_cost (x
, mode
, speed
)))
966 HOST_WIDE_INT intval
= trunc_int_for_mode (INTVAL (x
), mode
);
967 if (intval
!= INTVAL (x
))
968 x
= GEN_INT (intval
);
971 x
= convert_modes (mode
, VOIDmode
, x
, unsignedp
);
972 x
= force_reg (mode
, x
);
977 /* Helper function for expand_binop: handle the case where there
978 is an insn that directly implements the indicated operation.
979 Returns null if this is not possible. */
981 expand_binop_directly (machine_mode mode
, optab binoptab
,
983 rtx target
, int unsignedp
, enum optab_methods methods
,
986 machine_mode from_mode
= widened_mode (mode
, op0
, op1
);
987 enum insn_code icode
= find_widening_optab_handler (binoptab
, mode
,
989 machine_mode xmode0
= insn_data
[(int) icode
].operand
[1].mode
;
990 machine_mode xmode1
= insn_data
[(int) icode
].operand
[2].mode
;
991 machine_mode mode0
, mode1
, tmp_mode
;
992 struct expand_operand ops
[3];
995 rtx xop0
= op0
, xop1
= op1
;
997 /* If it is a commutative operator and the modes would match
998 if we would swap the operands, we can save the conversions. */
999 commutative_p
= commutative_optab_p (binoptab
);
1001 && GET_MODE (xop0
) != xmode0
&& GET_MODE (xop1
) != xmode1
1002 && GET_MODE (xop0
) == xmode1
&& GET_MODE (xop1
) == xmode1
)
1003 std::swap (xop0
, xop1
);
1005 /* If we are optimizing, force expensive constants into a register. */
1006 xop0
= avoid_expensive_constant (xmode0
, binoptab
, 0, xop0
, unsignedp
);
1007 if (!shift_optab_p (binoptab
))
1008 xop1
= avoid_expensive_constant (xmode1
, binoptab
, 1, xop1
, unsignedp
);
1010 /* In case the insn wants input operands in modes different from
1011 those of the actual operands, convert the operands. It would
1012 seem that we don't need to convert CONST_INTs, but we do, so
1013 that they're properly zero-extended, sign-extended or truncated
1016 mode0
= GET_MODE (xop0
) != VOIDmode
? GET_MODE (xop0
) : mode
;
1017 if (xmode0
!= VOIDmode
&& xmode0
!= mode0
)
1019 xop0
= convert_modes (xmode0
, mode0
, xop0
, unsignedp
);
1023 mode1
= GET_MODE (xop1
) != VOIDmode
? GET_MODE (xop1
) : mode
;
1024 if (xmode1
!= VOIDmode
&& xmode1
!= mode1
)
1026 xop1
= convert_modes (xmode1
, mode1
, xop1
, unsignedp
);
1030 /* If operation is commutative,
1031 try to make the first operand a register.
1032 Even better, try to make it the same as the target.
1033 Also try to make the last operand a constant. */
1035 && swap_commutative_operands_with_target (target
, xop0
, xop1
))
1036 std::swap (xop0
, xop1
);
1038 /* Now, if insn's predicates don't allow our operands, put them into
1041 if (binoptab
== vec_pack_trunc_optab
1042 || binoptab
== vec_pack_usat_optab
1043 || binoptab
== vec_pack_ssat_optab
1044 || binoptab
== vec_pack_ufix_trunc_optab
1045 || binoptab
== vec_pack_sfix_trunc_optab
)
1047 /* The mode of the result is different then the mode of the
1049 tmp_mode
= insn_data
[(int) icode
].operand
[0].mode
;
1050 if (VECTOR_MODE_P (mode
)
1051 && GET_MODE_NUNITS (tmp_mode
) != 2 * GET_MODE_NUNITS (mode
))
1053 delete_insns_since (last
);
1060 create_output_operand (&ops
[0], target
, tmp_mode
);
1061 create_input_operand (&ops
[1], xop0
, mode0
);
1062 create_input_operand (&ops
[2], xop1
, mode1
);
1063 pat
= maybe_gen_insn (icode
, 3, ops
);
1066 /* If PAT is composed of more than one insn, try to add an appropriate
1067 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1068 operand, call expand_binop again, this time without a target. */
1069 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
1070 && ! add_equal_note (pat
, ops
[0].value
,
1071 optab_to_code (binoptab
),
1072 ops
[1].value
, ops
[2].value
))
1074 delete_insns_since (last
);
1075 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
1076 unsignedp
, methods
);
1080 return ops
[0].value
;
1082 delete_insns_since (last
);
1086 /* Generate code to perform an operation specified by BINOPTAB
1087 on operands OP0 and OP1, with result having machine-mode MODE.
1089 UNSIGNEDP is for the case where we have to widen the operands
1090 to perform the operation. It says to use zero-extension.
1092 If TARGET is nonzero, the value
1093 is generated there, if it is convenient to do so.
1094 In all cases an rtx is returned for the locus of the value;
1095 this may or may not be TARGET. */
1098 expand_binop (machine_mode mode
, optab binoptab
, rtx op0
, rtx op1
,
1099 rtx target
, int unsignedp
, enum optab_methods methods
)
1101 enum optab_methods next_methods
1102 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
1103 ? OPTAB_WIDEN
: methods
);
1104 enum mode_class mclass
;
1105 machine_mode wider_mode
;
1108 rtx_insn
*entry_last
= get_last_insn ();
1111 mclass
= GET_MODE_CLASS (mode
);
1113 /* If subtracting an integer constant, convert this into an addition of
1114 the negated constant. */
1116 if (binoptab
== sub_optab
&& CONST_INT_P (op1
))
1118 op1
= negate_rtx (mode
, op1
);
1119 binoptab
= add_optab
;
1122 /* Record where to delete back to if we backtrack. */
1123 last
= get_last_insn ();
1125 /* If we can do it with a three-operand insn, do so. */
1127 if (methods
!= OPTAB_MUST_WIDEN
1128 && find_widening_optab_handler (binoptab
, mode
,
1129 widened_mode (mode
, op0
, op1
), 1)
1130 != CODE_FOR_nothing
)
1132 temp
= expand_binop_directly (mode
, binoptab
, op0
, op1
, target
,
1133 unsignedp
, methods
, last
);
1138 /* If we were trying to rotate, and that didn't work, try rotating
1139 the other direction before falling back to shifts and bitwise-or. */
1140 if (((binoptab
== rotl_optab
1141 && optab_handler (rotr_optab
, mode
) != CODE_FOR_nothing
)
1142 || (binoptab
== rotr_optab
1143 && optab_handler (rotl_optab
, mode
) != CODE_FOR_nothing
))
1144 && mclass
== MODE_INT
)
1146 optab otheroptab
= (binoptab
== rotl_optab
? rotr_optab
: rotl_optab
);
1148 unsigned int bits
= GET_MODE_PRECISION (mode
);
1150 if (CONST_INT_P (op1
))
1151 newop1
= GEN_INT (bits
- INTVAL (op1
));
1152 else if (targetm
.shift_truncation_mask (mode
) == bits
- 1)
1153 newop1
= negate_rtx (GET_MODE (op1
), op1
);
1155 newop1
= expand_binop (GET_MODE (op1
), sub_optab
,
1156 gen_int_mode (bits
, GET_MODE (op1
)), op1
,
1157 NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1159 temp
= expand_binop_directly (mode
, otheroptab
, op0
, newop1
,
1160 target
, unsignedp
, methods
, last
);
1165 /* If this is a multiply, see if we can do a widening operation that
1166 takes operands of this mode and makes a wider mode. */
1168 if (binoptab
== smul_optab
1169 && GET_MODE_2XWIDER_MODE (mode
) != VOIDmode
1170 && (widening_optab_handler ((unsignedp
? umul_widen_optab
1171 : smul_widen_optab
),
1172 GET_MODE_2XWIDER_MODE (mode
), mode
)
1173 != CODE_FOR_nothing
))
1175 temp
= expand_binop (GET_MODE_2XWIDER_MODE (mode
),
1176 unsignedp
? umul_widen_optab
: smul_widen_optab
,
1177 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1181 if (GET_MODE_CLASS (mode
) == MODE_INT
1182 && TRULY_NOOP_TRUNCATION_MODES_P (mode
, GET_MODE (temp
)))
1183 return gen_lowpart (mode
, temp
);
1185 return convert_to_mode (mode
, temp
, unsignedp
);
1189 /* If this is a vector shift by a scalar, see if we can do a vector
1190 shift by a vector. If so, broadcast the scalar into a vector. */
1191 if (mclass
== MODE_VECTOR_INT
)
1193 optab otheroptab
= unknown_optab
;
1195 if (binoptab
== ashl_optab
)
1196 otheroptab
= vashl_optab
;
1197 else if (binoptab
== ashr_optab
)
1198 otheroptab
= vashr_optab
;
1199 else if (binoptab
== lshr_optab
)
1200 otheroptab
= vlshr_optab
;
1201 else if (binoptab
== rotl_optab
)
1202 otheroptab
= vrotl_optab
;
1203 else if (binoptab
== rotr_optab
)
1204 otheroptab
= vrotr_optab
;
1206 if (otheroptab
&& optab_handler (otheroptab
, mode
) != CODE_FOR_nothing
)
1208 /* The scalar may have been extended to be too wide. Truncate
1209 it back to the proper size to fit in the broadcast vector. */
1210 machine_mode inner_mode
= GET_MODE_INNER (mode
);
1211 if (!CONST_INT_P (op1
)
1212 && (GET_MODE_BITSIZE (inner_mode
)
1213 < GET_MODE_BITSIZE (GET_MODE (op1
))))
1214 op1
= force_reg (inner_mode
,
1215 simplify_gen_unary (TRUNCATE
, inner_mode
, op1
,
1217 rtx vop1
= expand_vector_broadcast (mode
, op1
);
1220 temp
= expand_binop_directly (mode
, otheroptab
, op0
, vop1
,
1221 target
, unsignedp
, methods
, last
);
1228 /* Look for a wider mode of the same class for which we think we
1229 can open-code the operation. Check for a widening multiply at the
1230 wider mode as well. */
1232 if (CLASS_HAS_WIDER_MODES_P (mclass
)
1233 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
1234 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
1235 wider_mode
!= VOIDmode
;
1236 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1238 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
1239 || (binoptab
== smul_optab
1240 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
1241 && (find_widening_optab_handler ((unsignedp
1243 : smul_widen_optab
),
1244 GET_MODE_WIDER_MODE (wider_mode
),
1246 != CODE_FOR_nothing
)))
1248 rtx xop0
= op0
, xop1
= op1
;
1251 /* For certain integer operations, we need not actually extend
1252 the narrow operands, as long as we will truncate
1253 the results to the same narrowness. */
1255 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1256 || binoptab
== xor_optab
1257 || binoptab
== add_optab
|| binoptab
== sub_optab
1258 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1259 && mclass
== MODE_INT
)
1262 xop0
= avoid_expensive_constant (mode
, binoptab
, 0,
1264 if (binoptab
!= ashl_optab
)
1265 xop1
= avoid_expensive_constant (mode
, binoptab
, 1,
1269 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
1271 /* The second operand of a shift must always be extended. */
1272 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1273 no_extend
&& binoptab
!= ashl_optab
);
1275 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1276 unsignedp
, OPTAB_DIRECT
);
1279 if (mclass
!= MODE_INT
1280 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
1283 target
= gen_reg_rtx (mode
);
1284 convert_move (target
, temp
, 0);
1288 return gen_lowpart (mode
, temp
);
1291 delete_insns_since (last
);
1295 /* If operation is commutative,
1296 try to make the first operand a register.
1297 Even better, try to make it the same as the target.
1298 Also try to make the last operand a constant. */
1299 if (commutative_optab_p (binoptab
)
1300 && swap_commutative_operands_with_target (target
, op0
, op1
))
1301 std::swap (op0
, op1
);
1303 /* These can be done a word at a time. */
1304 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
1305 && mclass
== MODE_INT
1306 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1307 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1312 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1313 won't be accurate, so use a new target. */
1317 || !valid_multiword_target_p (target
))
1318 target
= gen_reg_rtx (mode
);
1322 /* Do the actual arithmetic. */
1323 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1325 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1326 rtx x
= expand_binop (word_mode
, binoptab
,
1327 operand_subword_force (op0
, i
, mode
),
1328 operand_subword_force (op1
, i
, mode
),
1329 target_piece
, unsignedp
, next_methods
);
1334 if (target_piece
!= x
)
1335 emit_move_insn (target_piece
, x
);
1338 insns
= get_insns ();
1341 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
1348 /* Synthesize double word shifts from single word shifts. */
1349 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
1350 || binoptab
== ashr_optab
)
1351 && mclass
== MODE_INT
1352 && (CONST_INT_P (op1
) || optimize_insn_for_speed_p ())
1353 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1354 && GET_MODE_PRECISION (mode
) == GET_MODE_BITSIZE (mode
)
1355 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
1356 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1357 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1359 unsigned HOST_WIDE_INT shift_mask
, double_shift_mask
;
1360 machine_mode op1_mode
;
1362 double_shift_mask
= targetm
.shift_truncation_mask (mode
);
1363 shift_mask
= targetm
.shift_truncation_mask (word_mode
);
1364 op1_mode
= GET_MODE (op1
) != VOIDmode
? GET_MODE (op1
) : word_mode
;
1366 /* Apply the truncation to constant shifts. */
1367 if (double_shift_mask
> 0 && CONST_INT_P (op1
))
1368 op1
= GEN_INT (INTVAL (op1
) & double_shift_mask
);
1370 if (op1
== CONST0_RTX (op1_mode
))
1373 /* Make sure that this is a combination that expand_doubleword_shift
1374 can handle. See the comments there for details. */
1375 if (double_shift_mask
== 0
1376 || (shift_mask
== BITS_PER_WORD
- 1
1377 && double_shift_mask
== BITS_PER_WORD
* 2 - 1))
1380 rtx into_target
, outof_target
;
1381 rtx into_input
, outof_input
;
1382 int left_shift
, outof_word
;
1384 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1385 won't be accurate, so use a new target. */
1389 || !valid_multiword_target_p (target
))
1390 target
= gen_reg_rtx (mode
);
1394 /* OUTOF_* is the word we are shifting bits away from, and
1395 INTO_* is the word that we are shifting bits towards, thus
1396 they differ depending on the direction of the shift and
1397 WORDS_BIG_ENDIAN. */
1399 left_shift
= binoptab
== ashl_optab
;
1400 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1402 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1403 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1405 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1406 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1408 if (expand_doubleword_shift (op1_mode
, binoptab
,
1409 outof_input
, into_input
, op1
,
1410 outof_target
, into_target
,
1411 unsignedp
, next_methods
, shift_mask
))
1413 insns
= get_insns ();
1423 /* Synthesize double word rotates from single word shifts. */
1424 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
1425 && mclass
== MODE_INT
1426 && CONST_INT_P (op1
)
1427 && GET_MODE_PRECISION (mode
) == 2 * BITS_PER_WORD
1428 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1429 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1432 rtx into_target
, outof_target
;
1433 rtx into_input
, outof_input
;
1435 int shift_count
, left_shift
, outof_word
;
1437 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1438 won't be accurate, so use a new target. Do this also if target is not
1439 a REG, first because having a register instead may open optimization
1440 opportunities, and second because if target and op0 happen to be MEMs
1441 designating the same location, we would risk clobbering it too early
1442 in the code sequence we generate below. */
1447 || !valid_multiword_target_p (target
))
1448 target
= gen_reg_rtx (mode
);
1452 shift_count
= INTVAL (op1
);
1454 /* OUTOF_* is the word we are shifting bits away from, and
1455 INTO_* is the word that we are shifting bits towards, thus
1456 they differ depending on the direction of the shift and
1457 WORDS_BIG_ENDIAN. */
1459 left_shift
= (binoptab
== rotl_optab
);
1460 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1462 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1463 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1465 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1466 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1468 if (shift_count
== BITS_PER_WORD
)
1470 /* This is just a word swap. */
1471 emit_move_insn (outof_target
, into_input
);
1472 emit_move_insn (into_target
, outof_input
);
1477 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1478 rtx first_shift_count
, second_shift_count
;
1479 optab reverse_unsigned_shift
, unsigned_shift
;
1481 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1482 ? lshr_optab
: ashl_optab
);
1484 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1485 ? ashl_optab
: lshr_optab
);
1487 if (shift_count
> BITS_PER_WORD
)
1489 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
1490 second_shift_count
= GEN_INT (2 * BITS_PER_WORD
- shift_count
);
1494 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
1495 second_shift_count
= GEN_INT (shift_count
);
1498 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1499 outof_input
, first_shift_count
,
1500 NULL_RTX
, unsignedp
, next_methods
);
1501 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1502 into_input
, second_shift_count
,
1503 NULL_RTX
, unsignedp
, next_methods
);
1505 if (into_temp1
!= 0 && into_temp2
!= 0)
1506 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1507 into_target
, unsignedp
, next_methods
);
1511 if (inter
!= 0 && inter
!= into_target
)
1512 emit_move_insn (into_target
, inter
);
1514 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1515 into_input
, first_shift_count
,
1516 NULL_RTX
, unsignedp
, next_methods
);
1517 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1518 outof_input
, second_shift_count
,
1519 NULL_RTX
, unsignedp
, next_methods
);
1521 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1522 inter
= expand_binop (word_mode
, ior_optab
,
1523 outof_temp1
, outof_temp2
,
1524 outof_target
, unsignedp
, next_methods
);
1526 if (inter
!= 0 && inter
!= outof_target
)
1527 emit_move_insn (outof_target
, inter
);
1530 insns
= get_insns ();
1540 /* These can be done a word at a time by propagating carries. */
1541 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1542 && mclass
== MODE_INT
1543 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
1544 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1547 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1548 const unsigned int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
1549 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1550 rtx xop0
, xop1
, xtarget
;
1552 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1553 value is one of those, use it. Otherwise, use 1 since it is the
1554 one easiest to get. */
1555 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1556 int normalizep
= STORE_FLAG_VALUE
;
1561 /* Prepare the operands. */
1562 xop0
= force_reg (mode
, op0
);
1563 xop1
= force_reg (mode
, op1
);
1565 xtarget
= gen_reg_rtx (mode
);
1567 if (target
== 0 || !REG_P (target
) || !valid_multiword_target_p (target
))
1570 /* Indicate for flow that the entire target reg is being set. */
1572 emit_clobber (xtarget
);
1574 /* Do the actual arithmetic. */
1575 for (i
= 0; i
< nwords
; i
++)
1577 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
1578 rtx target_piece
= operand_subword (xtarget
, index
, 1, mode
);
1579 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
1580 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
1583 /* Main add/subtract of the input operands. */
1584 x
= expand_binop (word_mode
, binoptab
,
1585 op0_piece
, op1_piece
,
1586 target_piece
, unsignedp
, next_methods
);
1592 /* Store carry from main add/subtract. */
1593 carry_out
= gen_reg_rtx (word_mode
);
1594 carry_out
= emit_store_flag_force (carry_out
,
1595 (binoptab
== add_optab
1598 word_mode
, 1, normalizep
);
1605 /* Add/subtract previous carry to main result. */
1606 newx
= expand_binop (word_mode
,
1607 normalizep
== 1 ? binoptab
: otheroptab
,
1609 NULL_RTX
, 1, next_methods
);
1613 /* Get out carry from adding/subtracting carry in. */
1614 rtx carry_tmp
= gen_reg_rtx (word_mode
);
1615 carry_tmp
= emit_store_flag_force (carry_tmp
,
1616 (binoptab
== add_optab
1619 word_mode
, 1, normalizep
);
1621 /* Logical-ior the two poss. carry together. */
1622 carry_out
= expand_binop (word_mode
, ior_optab
,
1623 carry_out
, carry_tmp
,
1624 carry_out
, 0, next_methods
);
1628 emit_move_insn (target_piece
, newx
);
1632 if (x
!= target_piece
)
1633 emit_move_insn (target_piece
, x
);
1636 carry_in
= carry_out
;
1639 if (i
== GET_MODE_BITSIZE (mode
) / (unsigned) BITS_PER_WORD
)
1641 if (optab_handler (mov_optab
, mode
) != CODE_FOR_nothing
1642 || ! rtx_equal_p (target
, xtarget
))
1644 rtx_insn
*temp
= emit_move_insn (target
, xtarget
);
1646 set_dst_reg_note (temp
, REG_EQUAL
,
1647 gen_rtx_fmt_ee (optab_to_code (binoptab
),
1648 mode
, copy_rtx (xop0
),
1659 delete_insns_since (last
);
1662 /* Attempt to synthesize double word multiplies using a sequence of word
1663 mode multiplications. We first attempt to generate a sequence using a
1664 more efficient unsigned widening multiply, and if that fails we then
1665 try using a signed widening multiply. */
1667 if (binoptab
== smul_optab
1668 && mclass
== MODE_INT
1669 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1670 && optab_handler (smul_optab
, word_mode
) != CODE_FOR_nothing
1671 && optab_handler (add_optab
, word_mode
) != CODE_FOR_nothing
)
1673 rtx product
= NULL_RTX
;
1674 if (widening_optab_handler (umul_widen_optab
, mode
, word_mode
)
1675 != CODE_FOR_nothing
)
1677 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
1680 delete_insns_since (last
);
1683 if (product
== NULL_RTX
1684 && widening_optab_handler (smul_widen_optab
, mode
, word_mode
)
1685 != CODE_FOR_nothing
)
1687 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
1690 delete_insns_since (last
);
1693 if (product
!= NULL_RTX
)
1695 if (optab_handler (mov_optab
, mode
) != CODE_FOR_nothing
)
1697 temp
= emit_move_insn (target
? target
: product
, product
);
1698 set_dst_reg_note (temp
,
1700 gen_rtx_fmt_ee (MULT
, mode
,
1703 target
? target
: product
);
1709 /* It can't be open-coded in this mode.
1710 Use a library call if one is available and caller says that's ok. */
1712 libfunc
= optab_libfunc (binoptab
, mode
);
1714 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1718 machine_mode op1_mode
= mode
;
1723 if (shift_optab_p (binoptab
))
1725 op1_mode
= targetm
.libgcc_shift_count_mode ();
1726 /* Specify unsigned here,
1727 since negative shift counts are meaningless. */
1728 op1x
= convert_to_mode (op1_mode
, op1
, 1);
1731 if (GET_MODE (op0
) != VOIDmode
1732 && GET_MODE (op0
) != mode
)
1733 op0
= convert_to_mode (mode
, op0
, unsignedp
);
1735 /* Pass 1 for NO_QUEUE so we don't lose any increments
1736 if the libcall is cse'd or moved. */
1737 value
= emit_library_call_value (libfunc
,
1738 NULL_RTX
, LCT_CONST
, mode
, 2,
1739 op0
, mode
, op1x
, op1_mode
);
1741 insns
= get_insns ();
1744 bool trapv
= trapv_binoptab_p (binoptab
);
1745 target
= gen_reg_rtx (mode
);
1746 emit_libcall_block_1 (insns
, target
, value
,
1748 : gen_rtx_fmt_ee (optab_to_code (binoptab
),
1749 mode
, op0
, op1
), trapv
);
1754 delete_insns_since (last
);
1756 /* It can't be done in this mode. Can we do it in a wider mode? */
1758 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1759 || methods
== OPTAB_MUST_WIDEN
))
1761 /* Caller says, don't even try. */
1762 delete_insns_since (entry_last
);
1766 /* Compute the value of METHODS to pass to recursive calls.
1767 Don't allow widening to be tried recursively. */
1769 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1771 /* Look for a wider mode of the same class for which it appears we can do
1774 if (CLASS_HAS_WIDER_MODES_P (mclass
))
1776 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
1777 wider_mode
!= VOIDmode
;
1778 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1780 if (find_widening_optab_handler (binoptab
, wider_mode
, mode
, 1)
1782 || (methods
== OPTAB_LIB
1783 && optab_libfunc (binoptab
, wider_mode
)))
1785 rtx xop0
= op0
, xop1
= op1
;
1788 /* For certain integer operations, we need not actually extend
1789 the narrow operands, as long as we will truncate
1790 the results to the same narrowness. */
1792 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1793 || binoptab
== xor_optab
1794 || binoptab
== add_optab
|| binoptab
== sub_optab
1795 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1796 && mclass
== MODE_INT
)
1799 xop0
= widen_operand (xop0
, wider_mode
, mode
,
1800 unsignedp
, no_extend
);
1802 /* The second operand of a shift must always be extended. */
1803 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1804 no_extend
&& binoptab
!= ashl_optab
);
1806 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1807 unsignedp
, methods
);
1810 if (mclass
!= MODE_INT
1811 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
1814 target
= gen_reg_rtx (mode
);
1815 convert_move (target
, temp
, 0);
1819 return gen_lowpart (mode
, temp
);
1822 delete_insns_since (last
);
1827 delete_insns_since (entry_last
);
1831 /* Expand a binary operator which has both signed and unsigned forms.
1832 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1835 If we widen unsigned operands, we may use a signed wider operation instead
1836 of an unsigned wider operation, since the result would be the same. */
1839 sign_expand_binop (machine_mode mode
, optab uoptab
, optab soptab
,
1840 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
1841 enum optab_methods methods
)
1844 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1847 /* Do it without widening, if possible. */
1848 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1849 unsignedp
, OPTAB_DIRECT
);
1850 if (temp
|| methods
== OPTAB_DIRECT
)
1853 /* Try widening to a signed int. Disable any direct use of any
1854 signed insn in the current mode. */
1855 save_enable
= swap_optab_enable (soptab
, mode
, false);
1857 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
1858 unsignedp
, OPTAB_WIDEN
);
1860 /* For unsigned operands, try widening to an unsigned int. */
1861 if (!temp
&& unsignedp
)
1862 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1863 unsignedp
, OPTAB_WIDEN
);
1864 if (temp
|| methods
== OPTAB_WIDEN
)
1867 /* Use the right width libcall if that exists. */
1868 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1869 unsignedp
, OPTAB_LIB
);
1870 if (temp
|| methods
== OPTAB_LIB
)
1873 /* Must widen and use a libcall, use either signed or unsigned. */
1874 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
1875 unsignedp
, methods
);
1876 if (!temp
&& unsignedp
)
1877 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1878 unsignedp
, methods
);
1881 /* Undo the fiddling above. */
1883 swap_optab_enable (soptab
, mode
, true);
1887 /* Generate code to perform an operation specified by UNOPPTAB
1888 on operand OP0, with two results to TARG0 and TARG1.
1889 We assume that the order of the operands for the instruction
1890 is TARG0, TARG1, OP0.
1892 Either TARG0 or TARG1 may be zero, but what that means is that
1893 the result is not actually wanted. We will generate it into
1894 a dummy pseudo-reg and discard it. They may not both be zero.
1896 Returns 1 if this operation can be performed; 0 if not. */
1899 expand_twoval_unop (optab unoptab
, rtx op0
, rtx targ0
, rtx targ1
,
1902 machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1903 enum mode_class mclass
;
1904 machine_mode wider_mode
;
1905 rtx_insn
*entry_last
= get_last_insn ();
1908 mclass
= GET_MODE_CLASS (mode
);
1911 targ0
= gen_reg_rtx (mode
);
1913 targ1
= gen_reg_rtx (mode
);
1915 /* Record where to go back to if we fail. */
1916 last
= get_last_insn ();
1918 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
1920 struct expand_operand ops
[3];
1921 enum insn_code icode
= optab_handler (unoptab
, mode
);
1923 create_fixed_operand (&ops
[0], targ0
);
1924 create_fixed_operand (&ops
[1], targ1
);
1925 create_convert_operand_from (&ops
[2], op0
, mode
, unsignedp
);
1926 if (maybe_expand_insn (icode
, 3, ops
))
1930 /* It can't be done in this mode. Can we do it in a wider mode? */
1932 if (CLASS_HAS_WIDER_MODES_P (mclass
))
1934 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
1935 wider_mode
!= VOIDmode
;
1936 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1938 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
1940 rtx t0
= gen_reg_rtx (wider_mode
);
1941 rtx t1
= gen_reg_rtx (wider_mode
);
1942 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
1944 if (expand_twoval_unop (unoptab
, cop0
, t0
, t1
, unsignedp
))
1946 convert_move (targ0
, t0
, unsignedp
);
1947 convert_move (targ1
, t1
, unsignedp
);
1951 delete_insns_since (last
);
1956 delete_insns_since (entry_last
);
1960 /* Generate code to perform an operation specified by BINOPTAB
1961 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1962 We assume that the order of the operands for the instruction
1963 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1964 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1966 Either TARG0 or TARG1 may be zero, but what that means is that
1967 the result is not actually wanted. We will generate it into
1968 a dummy pseudo-reg and discard it. They may not both be zero.
1970 Returns 1 if this operation can be performed; 0 if not. */
1973 expand_twoval_binop (optab binoptab
, rtx op0
, rtx op1
, rtx targ0
, rtx targ1
,
1976 machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1977 enum mode_class mclass
;
1978 machine_mode wider_mode
;
1979 rtx_insn
*entry_last
= get_last_insn ();
1982 mclass
= GET_MODE_CLASS (mode
);
1985 targ0
= gen_reg_rtx (mode
);
1987 targ1
= gen_reg_rtx (mode
);
1989 /* Record where to go back to if we fail. */
1990 last
= get_last_insn ();
1992 if (optab_handler (binoptab
, mode
) != CODE_FOR_nothing
)
1994 struct expand_operand ops
[4];
1995 enum insn_code icode
= optab_handler (binoptab
, mode
);
1996 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
1997 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
1998 rtx xop0
= op0
, xop1
= op1
;
2000 /* If we are optimizing, force expensive constants into a register. */
2001 xop0
= avoid_expensive_constant (mode0
, binoptab
, 0, xop0
, unsignedp
);
2002 xop1
= avoid_expensive_constant (mode1
, binoptab
, 1, xop1
, unsignedp
);
2004 create_fixed_operand (&ops
[0], targ0
);
2005 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
2006 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
2007 create_fixed_operand (&ops
[3], targ1
);
2008 if (maybe_expand_insn (icode
, 4, ops
))
2010 delete_insns_since (last
);
2013 /* It can't be done in this mode. Can we do it in a wider mode? */
2015 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2017 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2018 wider_mode
!= VOIDmode
;
2019 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2021 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
)
2023 rtx t0
= gen_reg_rtx (wider_mode
);
2024 rtx t1
= gen_reg_rtx (wider_mode
);
2025 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2026 rtx cop1
= convert_modes (wider_mode
, mode
, op1
, unsignedp
);
2028 if (expand_twoval_binop (binoptab
, cop0
, cop1
,
2031 convert_move (targ0
, t0
, unsignedp
);
2032 convert_move (targ1
, t1
, unsignedp
);
2036 delete_insns_since (last
);
2041 delete_insns_since (entry_last
);
2045 /* Expand the two-valued library call indicated by BINOPTAB, but
2046 preserve only one of the values. If TARG0 is non-NULL, the first
2047 value is placed into TARG0; otherwise the second value is placed
2048 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2049 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2050 This routine assumes that the value returned by the library call is
2051 as if the return value was of an integral mode twice as wide as the
2052 mode of OP0. Returns 1 if the call was successful. */
2055 expand_twoval_binop_libfunc (optab binoptab
, rtx op0
, rtx op1
,
2056 rtx targ0
, rtx targ1
, enum rtx_code code
)
2059 machine_mode libval_mode
;
2064 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2065 gcc_assert (!targ0
!= !targ1
);
2067 mode
= GET_MODE (op0
);
2068 libfunc
= optab_libfunc (binoptab
, mode
);
2072 /* The value returned by the library function will have twice as
2073 many bits as the nominal MODE. */
2074 libval_mode
= smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode
),
2077 libval
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
2081 /* Get the part of VAL containing the value that we want. */
2082 libval
= simplify_gen_subreg (mode
, libval
, libval_mode
,
2083 targ0
? 0 : GET_MODE_SIZE (mode
));
2084 insns
= get_insns ();
2086 /* Move the into the desired location. */
2087 emit_libcall_block (insns
, targ0
? targ0
: targ1
, libval
,
2088 gen_rtx_fmt_ee (code
, mode
, op0
, op1
));
2094 /* Wrapper around expand_unop which takes an rtx code to specify
2095 the operation to perform, not an optab pointer. All other
2096 arguments are the same. */
2098 expand_simple_unop (machine_mode mode
, enum rtx_code code
, rtx op0
,
2099 rtx target
, int unsignedp
)
2101 optab unop
= code_to_optab (code
);
2104 return expand_unop (mode
, unop
, op0
, target
, unsignedp
);
2110 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2112 A similar operation can be used for clrsb. UNOPTAB says which operation
2113 we are trying to expand. */
2115 widen_leading (machine_mode mode
, rtx op0
, rtx target
, optab unoptab
)
2117 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2118 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2120 machine_mode wider_mode
;
2121 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2122 wider_mode
!= VOIDmode
;
2123 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2125 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2130 last
= get_last_insn ();
2133 target
= gen_reg_rtx (mode
);
2134 xop0
= widen_operand (op0
, wider_mode
, mode
,
2135 unoptab
!= clrsb_optab
, false);
2136 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2137 unoptab
!= clrsb_optab
);
2140 (wider_mode
, sub_optab
, temp
,
2141 gen_int_mode (GET_MODE_PRECISION (wider_mode
)
2142 - GET_MODE_PRECISION (mode
),
2144 target
, true, OPTAB_DIRECT
);
2146 delete_insns_since (last
);
2155 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2156 quantities, choosing which based on whether the high word is nonzero. */
2158 expand_doubleword_clz (machine_mode mode
, rtx op0
, rtx target
)
2160 rtx xop0
= force_reg (mode
, op0
);
2161 rtx subhi
= gen_highpart (word_mode
, xop0
);
2162 rtx sublo
= gen_lowpart (word_mode
, xop0
);
2163 rtx_code_label
*hi0_label
= gen_label_rtx ();
2164 rtx_code_label
*after_label
= gen_label_rtx ();
2168 /* If we were not given a target, use a word_mode register, not a
2169 'mode' register. The result will fit, and nobody is expecting
2170 anything bigger (the return type of __builtin_clz* is int). */
2172 target
= gen_reg_rtx (word_mode
);
2174 /* In any case, write to a word_mode scratch in both branches of the
2175 conditional, so we can ensure there is a single move insn setting
2176 'target' to tag a REG_EQUAL note on. */
2177 result
= gen_reg_rtx (word_mode
);
2181 /* If the high word is not equal to zero,
2182 then clz of the full value is clz of the high word. */
2183 emit_cmp_and_jump_insns (subhi
, CONST0_RTX (word_mode
), EQ
, 0,
2184 word_mode
, true, hi0_label
);
2186 temp
= expand_unop_direct (word_mode
, clz_optab
, subhi
, result
, true);
2191 convert_move (result
, temp
, true);
2193 emit_jump_insn (targetm
.gen_jump (after_label
));
2196 /* Else clz of the full value is clz of the low word plus the number
2197 of bits in the high word. */
2198 emit_label (hi0_label
);
2200 temp
= expand_unop_direct (word_mode
, clz_optab
, sublo
, 0, true);
2203 temp
= expand_binop (word_mode
, add_optab
, temp
,
2204 gen_int_mode (GET_MODE_BITSIZE (word_mode
), word_mode
),
2205 result
, true, OPTAB_DIRECT
);
2209 convert_move (result
, temp
, true);
2211 emit_label (after_label
);
2212 convert_move (target
, result
, true);
2217 add_equal_note (seq
, target
, CLZ
, xop0
, 0);
2226 /* Try calculating popcount of a double-word quantity as two popcount's of
2227 word-sized quantities and summing up the results. */
2229 expand_doubleword_popcount (machine_mode mode
, rtx op0
, rtx target
)
2236 t0
= expand_unop_direct (word_mode
, popcount_optab
,
2237 operand_subword_force (op0
, 0, mode
), NULL_RTX
,
2239 t1
= expand_unop_direct (word_mode
, popcount_optab
,
2240 operand_subword_force (op0
, 1, mode
), NULL_RTX
,
2248 /* If we were not given a target, use a word_mode register, not a
2249 'mode' register. The result will fit, and nobody is expecting
2250 anything bigger (the return type of __builtin_popcount* is int). */
2252 target
= gen_reg_rtx (word_mode
);
2254 t
= expand_binop (word_mode
, add_optab
, t0
, t1
, target
, 0, OPTAB_DIRECT
);
2259 add_equal_note (seq
, t
, POPCOUNT
, op0
, 0);
2267 (parity:narrow (low (x) ^ high (x))) */
2269 expand_doubleword_parity (machine_mode mode
, rtx op0
, rtx target
)
2271 rtx t
= expand_binop (word_mode
, xor_optab
,
2272 operand_subword_force (op0
, 0, mode
),
2273 operand_subword_force (op0
, 1, mode
),
2274 NULL_RTX
, 0, OPTAB_DIRECT
);
2275 return expand_unop (word_mode
, parity_optab
, t
, target
, true);
2281 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2283 widen_bswap (machine_mode mode
, rtx op0
, rtx target
)
2285 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2286 machine_mode wider_mode
;
2290 if (!CLASS_HAS_WIDER_MODES_P (mclass
))
2293 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2294 wider_mode
!= VOIDmode
;
2295 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2296 if (optab_handler (bswap_optab
, wider_mode
) != CODE_FOR_nothing
)
2301 last
= get_last_insn ();
2303 x
= widen_operand (op0
, wider_mode
, mode
, true, true);
2304 x
= expand_unop (wider_mode
, bswap_optab
, x
, NULL_RTX
, true);
2306 gcc_assert (GET_MODE_PRECISION (wider_mode
) == GET_MODE_BITSIZE (wider_mode
)
2307 && GET_MODE_PRECISION (mode
) == GET_MODE_BITSIZE (mode
));
2309 x
= expand_shift (RSHIFT_EXPR
, wider_mode
, x
,
2310 GET_MODE_BITSIZE (wider_mode
)
2311 - GET_MODE_BITSIZE (mode
),
2317 target
= gen_reg_rtx (mode
);
2318 emit_move_insn (target
, gen_lowpart (mode
, x
));
2321 delete_insns_since (last
);
2326 /* Try calculating bswap as two bswaps of two word-sized operands. */
2329 expand_doubleword_bswap (machine_mode mode
, rtx op
, rtx target
)
2333 t1
= expand_unop (word_mode
, bswap_optab
,
2334 operand_subword_force (op
, 0, mode
), NULL_RTX
, true);
2335 t0
= expand_unop (word_mode
, bswap_optab
,
2336 operand_subword_force (op
, 1, mode
), NULL_RTX
, true);
2338 if (target
== 0 || !valid_multiword_target_p (target
))
2339 target
= gen_reg_rtx (mode
);
2341 emit_clobber (target
);
2342 emit_move_insn (operand_subword (target
, 0, 1, mode
), t0
);
2343 emit_move_insn (operand_subword (target
, 1, 1, mode
), t1
);
2348 /* Try calculating (parity x) as (and (popcount x) 1), where
2349 popcount can also be done in a wider mode. */
2351 expand_parity (machine_mode mode
, rtx op0
, rtx target
)
2353 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2354 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2356 machine_mode wider_mode
;
2357 for (wider_mode
= mode
; wider_mode
!= VOIDmode
;
2358 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2360 if (optab_handler (popcount_optab
, wider_mode
) != CODE_FOR_nothing
)
2365 last
= get_last_insn ();
2368 target
= gen_reg_rtx (mode
);
2369 xop0
= widen_operand (op0
, wider_mode
, mode
, true, false);
2370 temp
= expand_unop (wider_mode
, popcount_optab
, xop0
, NULL_RTX
,
2373 temp
= expand_binop (wider_mode
, and_optab
, temp
, const1_rtx
,
2374 target
, true, OPTAB_DIRECT
);
2376 delete_insns_since (last
);
2385 /* Try calculating ctz(x) as K - clz(x & -x) ,
2386 where K is GET_MODE_PRECISION(mode) - 1.
2388 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2389 don't have to worry about what the hardware does in that case. (If
2390 the clz instruction produces the usual value at 0, which is K, the
2391 result of this code sequence will be -1; expand_ffs, below, relies
2392 on this. It might be nice to have it be K instead, for consistency
2393 with the (very few) processors that provide a ctz with a defined
2394 value, but that would take one more instruction, and it would be
2395 less convenient for expand_ffs anyway. */
2398 expand_ctz (machine_mode mode
, rtx op0
, rtx target
)
2403 if (optab_handler (clz_optab
, mode
) == CODE_FOR_nothing
)
2408 temp
= expand_unop_direct (mode
, neg_optab
, op0
, NULL_RTX
, true);
2410 temp
= expand_binop (mode
, and_optab
, op0
, temp
, NULL_RTX
,
2411 true, OPTAB_DIRECT
);
2413 temp
= expand_unop_direct (mode
, clz_optab
, temp
, NULL_RTX
, true);
2415 temp
= expand_binop (mode
, sub_optab
,
2416 gen_int_mode (GET_MODE_PRECISION (mode
) - 1, mode
),
2418 true, OPTAB_DIRECT
);
2428 add_equal_note (seq
, temp
, CTZ
, op0
, 0);
2434 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2435 else with the sequence used by expand_clz.
2437 The ffs builtin promises to return zero for a zero value and ctz/clz
2438 may have an undefined value in that case. If they do not give us a
2439 convenient value, we have to generate a test and branch. */
2441 expand_ffs (machine_mode mode
, rtx op0
, rtx target
)
2443 HOST_WIDE_INT val
= 0;
2444 bool defined_at_zero
= false;
2448 if (optab_handler (ctz_optab
, mode
) != CODE_FOR_nothing
)
2452 temp
= expand_unop_direct (mode
, ctz_optab
, op0
, 0, true);
2456 defined_at_zero
= (CTZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2);
2458 else if (optab_handler (clz_optab
, mode
) != CODE_FOR_nothing
)
2461 temp
= expand_ctz (mode
, op0
, 0);
2465 if (CLZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2)
2467 defined_at_zero
= true;
2468 val
= (GET_MODE_PRECISION (mode
) - 1) - val
;
2474 if (defined_at_zero
&& val
== -1)
2475 /* No correction needed at zero. */;
2478 /* We don't try to do anything clever with the situation found
2479 on some processors (eg Alpha) where ctz(0:mode) ==
2480 bitsize(mode). If someone can think of a way to send N to -1
2481 and leave alone all values in the range 0..N-1 (where N is a
2482 power of two), cheaper than this test-and-branch, please add it.
2484 The test-and-branch is done after the operation itself, in case
2485 the operation sets condition codes that can be recycled for this.
2486 (This is true on i386, for instance.) */
2488 rtx_code_label
*nonzero_label
= gen_label_rtx ();
2489 emit_cmp_and_jump_insns (op0
, CONST0_RTX (mode
), NE
, 0,
2490 mode
, true, nonzero_label
);
2492 convert_move (temp
, GEN_INT (-1), false);
2493 emit_label (nonzero_label
);
2496 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2497 to produce a value in the range 0..bitsize. */
2498 temp
= expand_binop (mode
, add_optab
, temp
, gen_int_mode (1, mode
),
2499 target
, false, OPTAB_DIRECT
);
2506 add_equal_note (seq
, temp
, FFS
, op0
, 0);
2515 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2516 conditions, VAL may already be a SUBREG against which we cannot generate
2517 a further SUBREG. In this case, we expect forcing the value into a
2518 register will work around the situation. */
2521 lowpart_subreg_maybe_copy (machine_mode omode
, rtx val
,
2525 ret
= lowpart_subreg (omode
, val
, imode
);
2528 val
= force_reg (imode
, val
);
2529 ret
= lowpart_subreg (omode
, val
, imode
);
2530 gcc_assert (ret
!= NULL
);
2535 /* Expand a floating point absolute value or negation operation via a
2536 logical operation on the sign bit. */
2539 expand_absneg_bit (enum rtx_code code
, machine_mode mode
,
2540 rtx op0
, rtx target
)
2542 const struct real_format
*fmt
;
2543 int bitpos
, word
, nwords
, i
;
2548 /* The format has to have a simple sign bit. */
2549 fmt
= REAL_MODE_FORMAT (mode
);
2553 bitpos
= fmt
->signbit_rw
;
2557 /* Don't create negative zeros if the format doesn't support them. */
2558 if (code
== NEG
&& !fmt
->has_signed_zero
)
2561 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
2563 imode
= int_mode_for_mode (mode
);
2564 if (imode
== BLKmode
)
2573 if (FLOAT_WORDS_BIG_ENDIAN
)
2574 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
2576 word
= bitpos
/ BITS_PER_WORD
;
2577 bitpos
= bitpos
% BITS_PER_WORD
;
2578 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
2581 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
2587 || (nwords
> 1 && !valid_multiword_target_p (target
)))
2588 target
= gen_reg_rtx (mode
);
2594 for (i
= 0; i
< nwords
; ++i
)
2596 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
2597 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
2601 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2603 immed_wide_int_const (mask
, imode
),
2604 targ_piece
, 1, OPTAB_LIB_WIDEN
);
2605 if (temp
!= targ_piece
)
2606 emit_move_insn (targ_piece
, temp
);
2609 emit_move_insn (targ_piece
, op0_piece
);
2612 insns
= get_insns ();
2619 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2620 gen_lowpart (imode
, op0
),
2621 immed_wide_int_const (mask
, imode
),
2622 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
2623 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
2625 set_dst_reg_note (get_last_insn (), REG_EQUAL
,
2626 gen_rtx_fmt_e (code
, mode
, copy_rtx (op0
)),
2633 /* As expand_unop, but will fail rather than attempt the operation in a
2634 different mode or with a libcall. */
2636 expand_unop_direct (machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
2639 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
2641 struct expand_operand ops
[2];
2642 enum insn_code icode
= optab_handler (unoptab
, mode
);
2643 rtx_insn
*last
= get_last_insn ();
2646 create_output_operand (&ops
[0], target
, mode
);
2647 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
2648 pat
= maybe_gen_insn (icode
, 2, ops
);
2651 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
2652 && ! add_equal_note (pat
, ops
[0].value
,
2653 optab_to_code (unoptab
),
2654 ops
[1].value
, NULL_RTX
))
2656 delete_insns_since (last
);
2657 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
2662 return ops
[0].value
;
2668 /* Generate code to perform an operation specified by UNOPTAB
2669 on operand OP0, with result having machine-mode MODE.
2671 UNSIGNEDP is for the case where we have to widen the operands
2672 to perform the operation. It says to use zero-extension.
2674 If TARGET is nonzero, the value
2675 is generated there, if it is convenient to do so.
2676 In all cases an rtx is returned for the locus of the value;
2677 this may or may not be TARGET. */
2680 expand_unop (machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
2683 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2684 machine_mode wider_mode
;
2688 temp
= expand_unop_direct (mode
, unoptab
, op0
, target
, unsignedp
);
2692 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2694 /* Widening (or narrowing) clz needs special treatment. */
2695 if (unoptab
== clz_optab
)
2697 temp
= widen_leading (mode
, op0
, target
, unoptab
);
2701 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
2702 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
2704 temp
= expand_doubleword_clz (mode
, op0
, target
);
2712 if (unoptab
== clrsb_optab
)
2714 temp
= widen_leading (mode
, op0
, target
, unoptab
);
2720 if (unoptab
== popcount_optab
2721 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
2722 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
2723 && optimize_insn_for_speed_p ())
2725 temp
= expand_doubleword_popcount (mode
, op0
, target
);
2730 if (unoptab
== parity_optab
2731 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
2732 && (optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
2733 || optab_handler (popcount_optab
, word_mode
) != CODE_FOR_nothing
)
2734 && optimize_insn_for_speed_p ())
2736 temp
= expand_doubleword_parity (mode
, op0
, target
);
2741 /* Widening (or narrowing) bswap needs special treatment. */
2742 if (unoptab
== bswap_optab
)
2744 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
2745 or ROTATERT. First try these directly; if this fails, then try the
2746 obvious pair of shifts with allowed widening, as this will probably
2747 be always more efficient than the other fallback methods. */
2753 if (optab_handler (rotl_optab
, mode
) != CODE_FOR_nothing
)
2755 temp
= expand_binop (mode
, rotl_optab
, op0
, GEN_INT (8), target
,
2756 unsignedp
, OPTAB_DIRECT
);
2761 if (optab_handler (rotr_optab
, mode
) != CODE_FOR_nothing
)
2763 temp
= expand_binop (mode
, rotr_optab
, op0
, GEN_INT (8), target
,
2764 unsignedp
, OPTAB_DIRECT
);
2769 last
= get_last_insn ();
2771 temp1
= expand_binop (mode
, ashl_optab
, op0
, GEN_INT (8), NULL_RTX
,
2772 unsignedp
, OPTAB_WIDEN
);
2773 temp2
= expand_binop (mode
, lshr_optab
, op0
, GEN_INT (8), NULL_RTX
,
2774 unsignedp
, OPTAB_WIDEN
);
2777 temp
= expand_binop (mode
, ior_optab
, temp1
, temp2
, target
,
2778 unsignedp
, OPTAB_WIDEN
);
2783 delete_insns_since (last
);
2786 temp
= widen_bswap (mode
, op0
, target
);
2790 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
2791 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
2793 temp
= expand_doubleword_bswap (mode
, op0
, target
);
2801 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2802 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2803 wider_mode
!= VOIDmode
;
2804 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2806 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2809 rtx_insn
*last
= get_last_insn ();
2811 /* For certain operations, we need not actually extend
2812 the narrow operand, as long as we will truncate the
2813 results to the same narrowness. */
2815 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2816 (unoptab
== neg_optab
2817 || unoptab
== one_cmpl_optab
)
2818 && mclass
== MODE_INT
);
2820 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2825 if (mclass
!= MODE_INT
2826 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
2829 target
= gen_reg_rtx (mode
);
2830 convert_move (target
, temp
, 0);
2834 return gen_lowpart (mode
, temp
);
2837 delete_insns_since (last
);
2841 /* These can be done a word at a time. */
2842 if (unoptab
== one_cmpl_optab
2843 && mclass
== MODE_INT
2844 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
2845 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
2850 if (target
== 0 || target
== op0
|| !valid_multiword_target_p (target
))
2851 target
= gen_reg_rtx (mode
);
2855 /* Do the actual arithmetic. */
2856 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
2858 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
2859 rtx x
= expand_unop (word_mode
, unoptab
,
2860 operand_subword_force (op0
, i
, mode
),
2861 target_piece
, unsignedp
);
2863 if (target_piece
!= x
)
2864 emit_move_insn (target_piece
, x
);
2867 insns
= get_insns ();
2874 if (optab_to_code (unoptab
) == NEG
)
2876 /* Try negating floating point values by flipping the sign bit. */
2877 if (SCALAR_FLOAT_MODE_P (mode
))
2879 temp
= expand_absneg_bit (NEG
, mode
, op0
, target
);
2884 /* If there is no negation pattern, and we have no negative zero,
2885 try subtracting from zero. */
2886 if (!HONOR_SIGNED_ZEROS (mode
))
2888 temp
= expand_binop (mode
, (unoptab
== negv_optab
2889 ? subv_optab
: sub_optab
),
2890 CONST0_RTX (mode
), op0
, target
,
2891 unsignedp
, OPTAB_DIRECT
);
2897 /* Try calculating parity (x) as popcount (x) % 2. */
2898 if (unoptab
== parity_optab
)
2900 temp
= expand_parity (mode
, op0
, target
);
2905 /* Try implementing ffs (x) in terms of clz (x). */
2906 if (unoptab
== ffs_optab
)
2908 temp
= expand_ffs (mode
, op0
, target
);
2913 /* Try implementing ctz (x) in terms of clz (x). */
2914 if (unoptab
== ctz_optab
)
2916 temp
= expand_ctz (mode
, op0
, target
);
2922 /* Now try a library call in this mode. */
2923 libfunc
= optab_libfunc (unoptab
, mode
);
2929 machine_mode outmode
= mode
;
2931 /* All of these functions return small values. Thus we choose to
2932 have them return something that isn't a double-word. */
2933 if (unoptab
== ffs_optab
|| unoptab
== clz_optab
|| unoptab
== ctz_optab
2934 || unoptab
== clrsb_optab
|| unoptab
== popcount_optab
2935 || unoptab
== parity_optab
)
2937 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node
),
2938 optab_libfunc (unoptab
, mode
)));
2942 /* Pass 1 for NO_QUEUE so we don't lose any increments
2943 if the libcall is cse'd or moved. */
2944 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, outmode
,
2946 insns
= get_insns ();
2949 target
= gen_reg_rtx (outmode
);
2950 bool trapv
= trapv_unoptab_p (unoptab
);
2952 eq_value
= NULL_RTX
;
2955 eq_value
= gen_rtx_fmt_e (optab_to_code (unoptab
), mode
, op0
);
2956 if (GET_MODE_SIZE (outmode
) < GET_MODE_SIZE (mode
))
2957 eq_value
= simplify_gen_unary (TRUNCATE
, outmode
, eq_value
, mode
);
2958 else if (GET_MODE_SIZE (outmode
) > GET_MODE_SIZE (mode
))
2959 eq_value
= simplify_gen_unary (ZERO_EXTEND
,
2960 outmode
, eq_value
, mode
);
2962 emit_libcall_block_1 (insns
, target
, value
, eq_value
, trapv
);
2967 /* It can't be done in this mode. Can we do it in a wider mode? */
2969 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2971 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2972 wider_mode
!= VOIDmode
;
2973 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2975 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
2976 || optab_libfunc (unoptab
, wider_mode
))
2979 rtx_insn
*last
= get_last_insn ();
2981 /* For certain operations, we need not actually extend
2982 the narrow operand, as long as we will truncate the
2983 results to the same narrowness. */
2984 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2985 (unoptab
== neg_optab
2986 || unoptab
== one_cmpl_optab
2987 || unoptab
== bswap_optab
)
2988 && mclass
== MODE_INT
);
2990 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2993 /* If we are generating clz using wider mode, adjust the
2994 result. Similarly for clrsb. */
2995 if ((unoptab
== clz_optab
|| unoptab
== clrsb_optab
)
2998 (wider_mode
, sub_optab
, temp
,
2999 gen_int_mode (GET_MODE_PRECISION (wider_mode
)
3000 - GET_MODE_PRECISION (mode
),
3002 target
, true, OPTAB_DIRECT
);
3004 /* Likewise for bswap. */
3005 if (unoptab
== bswap_optab
&& temp
!= 0)
3007 gcc_assert (GET_MODE_PRECISION (wider_mode
)
3008 == GET_MODE_BITSIZE (wider_mode
)
3009 && GET_MODE_PRECISION (mode
)
3010 == GET_MODE_BITSIZE (mode
));
3012 temp
= expand_shift (RSHIFT_EXPR
, wider_mode
, temp
,
3013 GET_MODE_BITSIZE (wider_mode
)
3014 - GET_MODE_BITSIZE (mode
),
3020 if (mclass
!= MODE_INT
)
3023 target
= gen_reg_rtx (mode
);
3024 convert_move (target
, temp
, 0);
3028 return gen_lowpart (mode
, temp
);
3031 delete_insns_since (last
);
3036 /* One final attempt at implementing negation via subtraction,
3037 this time allowing widening of the operand. */
3038 if (optab_to_code (unoptab
) == NEG
&& !HONOR_SIGNED_ZEROS (mode
))
3041 temp
= expand_binop (mode
,
3042 unoptab
== negv_optab
? subv_optab
: sub_optab
,
3043 CONST0_RTX (mode
), op0
,
3044 target
, unsignedp
, OPTAB_LIB_WIDEN
);
3052 /* Emit code to compute the absolute value of OP0, with result to
3053 TARGET if convenient. (TARGET may be 0.) The return value says
3054 where the result actually is to be found.
3056 MODE is the mode of the operand; the mode of the result is
3057 different but can be deduced from MODE.
3062 expand_abs_nojump (machine_mode mode
, rtx op0
, rtx target
,
3063 int result_unsignedp
)
3067 if (GET_MODE_CLASS (mode
) != MODE_INT
3069 result_unsignedp
= 1;
3071 /* First try to do it with a special abs instruction. */
3072 temp
= expand_unop (mode
, result_unsignedp
? abs_optab
: absv_optab
,
3077 /* For floating point modes, try clearing the sign bit. */
3078 if (SCALAR_FLOAT_MODE_P (mode
))
3080 temp
= expand_absneg_bit (ABS
, mode
, op0
, target
);
3085 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3086 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
3087 && !HONOR_SIGNED_ZEROS (mode
))
3089 rtx_insn
*last
= get_last_insn ();
3091 temp
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3094 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3100 delete_insns_since (last
);
3103 /* If this machine has expensive jumps, we can do integer absolute
3104 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3105 where W is the width of MODE. */
3107 if (GET_MODE_CLASS (mode
) == MODE_INT
3108 && BRANCH_COST (optimize_insn_for_speed_p (),
3111 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
3112 GET_MODE_PRECISION (mode
) - 1,
3115 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
3118 temp
= expand_binop (mode
, result_unsignedp
? sub_optab
: subv_optab
,
3119 temp
, extended
, target
, 0, OPTAB_LIB_WIDEN
);
3129 expand_abs (machine_mode mode
, rtx op0
, rtx target
,
3130 int result_unsignedp
, int safe
)
3133 rtx_code_label
*op1
;
3135 if (GET_MODE_CLASS (mode
) != MODE_INT
3137 result_unsignedp
= 1;
3139 temp
= expand_abs_nojump (mode
, op0
, target
, result_unsignedp
);
3143 /* If that does not win, use conditional jump and negate. */
3145 /* It is safe to use the target if it is the same
3146 as the source if this is also a pseudo register */
3147 if (op0
== target
&& REG_P (op0
)
3148 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
3151 op1
= gen_label_rtx ();
3152 if (target
== 0 || ! safe
3153 || GET_MODE (target
) != mode
3154 || (MEM_P (target
) && MEM_VOLATILE_P (target
))
3156 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
3157 target
= gen_reg_rtx (mode
);
3159 emit_move_insn (target
, op0
);
3162 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
3163 NULL_RTX
, NULL
, op1
, -1);
3165 op0
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3168 emit_move_insn (target
, op0
);
3174 /* Emit code to compute the one's complement absolute value of OP0
3175 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3176 (TARGET may be NULL_RTX.) The return value says where the result
3177 actually is to be found.
3179 MODE is the mode of the operand; the mode of the result is
3180 different but can be deduced from MODE. */
3183 expand_one_cmpl_abs_nojump (machine_mode mode
, rtx op0
, rtx target
)
3187 /* Not applicable for floating point modes. */
3188 if (FLOAT_MODE_P (mode
))
3191 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3192 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
)
3194 rtx_insn
*last
= get_last_insn ();
3196 temp
= expand_unop (mode
, one_cmpl_optab
, op0
, NULL_RTX
, 0);
3198 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3204 delete_insns_since (last
);
3207 /* If this machine has expensive jumps, we can do one's complement
3208 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3210 if (GET_MODE_CLASS (mode
) == MODE_INT
3211 && BRANCH_COST (optimize_insn_for_speed_p (),
3214 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
3215 GET_MODE_PRECISION (mode
) - 1,
3218 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
3228 /* A subroutine of expand_copysign, perform the copysign operation using the
3229 abs and neg primitives advertised to exist on the target. The assumption
3230 is that we have a split register file, and leaving op0 in fp registers,
3231 and not playing with subregs so much, will help the register allocator. */
3234 expand_copysign_absneg (machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3235 int bitpos
, bool op0_is_abs
)
3238 enum insn_code icode
;
3240 rtx_code_label
*label
;
3245 /* Check if the back end provides an insn that handles signbit for the
3247 icode
= optab_handler (signbit_optab
, mode
);
3248 if (icode
!= CODE_FOR_nothing
)
3250 imode
= insn_data
[(int) icode
].operand
[0].mode
;
3251 sign
= gen_reg_rtx (imode
);
3252 emit_unop_insn (icode
, sign
, op1
, UNKNOWN
);
3256 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3258 imode
= int_mode_for_mode (mode
);
3259 if (imode
== BLKmode
)
3261 op1
= gen_lowpart (imode
, op1
);
3268 if (FLOAT_WORDS_BIG_ENDIAN
)
3269 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3271 word
= bitpos
/ BITS_PER_WORD
;
3272 bitpos
= bitpos
% BITS_PER_WORD
;
3273 op1
= operand_subword_force (op1
, word
, mode
);
3276 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3277 sign
= expand_binop (imode
, and_optab
, op1
,
3278 immed_wide_int_const (mask
, imode
),
3279 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3284 op0
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
3291 if (target
== NULL_RTX
)
3292 target
= copy_to_reg (op0
);
3294 emit_move_insn (target
, op0
);
3297 label
= gen_label_rtx ();
3298 emit_cmp_and_jump_insns (sign
, const0_rtx
, EQ
, NULL_RTX
, imode
, 1, label
);
3300 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3301 op0
= simplify_unary_operation (NEG
, mode
, op0
, mode
);
3303 op0
= expand_unop (mode
, neg_optab
, op0
, target
, 0);
3305 emit_move_insn (target
, op0
);
3313 /* A subroutine of expand_copysign, perform the entire copysign operation
3314 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3315 is true if op0 is known to have its sign bit clear. */
3318 expand_copysign_bit (machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3319 int bitpos
, bool op0_is_abs
)
3322 int word
, nwords
, i
;
3326 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3328 imode
= int_mode_for_mode (mode
);
3329 if (imode
== BLKmode
)
3338 if (FLOAT_WORDS_BIG_ENDIAN
)
3339 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3341 word
= bitpos
/ BITS_PER_WORD
;
3342 bitpos
= bitpos
% BITS_PER_WORD
;
3343 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
3346 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3351 || (nwords
> 1 && !valid_multiword_target_p (target
)))
3352 target
= gen_reg_rtx (mode
);
3358 for (i
= 0; i
< nwords
; ++i
)
3360 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
3361 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
3367 = expand_binop (imode
, and_optab
, op0_piece
,
3368 immed_wide_int_const (~mask
, imode
),
3369 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3370 op1
= expand_binop (imode
, and_optab
,
3371 operand_subword_force (op1
, i
, mode
),
3372 immed_wide_int_const (mask
, imode
),
3373 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3375 temp
= expand_binop (imode
, ior_optab
, op0_piece
, op1
,
3376 targ_piece
, 1, OPTAB_LIB_WIDEN
);
3377 if (temp
!= targ_piece
)
3378 emit_move_insn (targ_piece
, temp
);
3381 emit_move_insn (targ_piece
, op0_piece
);
3384 insns
= get_insns ();
3391 op1
= expand_binop (imode
, and_optab
, gen_lowpart (imode
, op1
),
3392 immed_wide_int_const (mask
, imode
),
3393 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3395 op0
= gen_lowpart (imode
, op0
);
3397 op0
= expand_binop (imode
, and_optab
, op0
,
3398 immed_wide_int_const (~mask
, imode
),
3399 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3401 temp
= expand_binop (imode
, ior_optab
, op0
, op1
,
3402 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3403 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3409 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3410 scalar floating point mode. Return NULL if we do not know how to
3411 expand the operation inline. */
3414 expand_copysign (rtx op0
, rtx op1
, rtx target
)
3416 machine_mode mode
= GET_MODE (op0
);
3417 const struct real_format
*fmt
;
3421 gcc_assert (SCALAR_FLOAT_MODE_P (mode
));
3422 gcc_assert (GET_MODE (op1
) == mode
);
3424 /* First try to do it with a special instruction. */
3425 temp
= expand_binop (mode
, copysign_optab
, op0
, op1
,
3426 target
, 0, OPTAB_DIRECT
);
3430 fmt
= REAL_MODE_FORMAT (mode
);
3431 if (fmt
== NULL
|| !fmt
->has_signed_zero
)
3435 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3437 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0
)))
3438 op0
= simplify_unary_operation (ABS
, mode
, op0
, mode
);
3442 if (fmt
->signbit_ro
>= 0
3443 && (CONST_DOUBLE_AS_FLOAT_P (op0
)
3444 || (optab_handler (neg_optab
, mode
) != CODE_FOR_nothing
3445 && optab_handler (abs_optab
, mode
) != CODE_FOR_nothing
)))
3447 temp
= expand_copysign_absneg (mode
, op0
, op1
, target
,
3448 fmt
->signbit_ro
, op0_is_abs
);
3453 if (fmt
->signbit_rw
< 0)
3455 return expand_copysign_bit (mode
, op0
, op1
, target
,
3456 fmt
->signbit_rw
, op0_is_abs
);
3459 /* Generate an instruction whose insn-code is INSN_CODE,
3460 with two operands: an output TARGET and an input OP0.
3461 TARGET *must* be nonzero, and the output is always stored there.
3462 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3463 the value that is stored into TARGET.
3465 Return false if expansion failed. */
3468 maybe_emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
,
3471 struct expand_operand ops
[2];
3474 create_output_operand (&ops
[0], target
, GET_MODE (target
));
3475 create_input_operand (&ops
[1], op0
, GET_MODE (op0
));
3476 pat
= maybe_gen_insn (icode
, 2, ops
);
3480 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
3482 add_equal_note (pat
, ops
[0].value
, code
, ops
[1].value
, NULL_RTX
);
3486 if (ops
[0].value
!= target
)
3487 emit_move_insn (target
, ops
[0].value
);
3490 /* Generate an instruction whose insn-code is INSN_CODE,
3491 with two operands: an output TARGET and an input OP0.
3492 TARGET *must* be nonzero, and the output is always stored there.
3493 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3494 the value that is stored into TARGET. */
3497 emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
, enum rtx_code code
)
3499 bool ok
= maybe_emit_unop_insn (icode
, target
, op0
, code
);
3503 struct no_conflict_data
3506 rtx_insn
*first
, *insn
;
3510 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3511 the currently examined clobber / store has to stay in the list of
3512 insns that constitute the actual libcall block. */
3514 no_conflict_move_test (rtx dest
, const_rtx set
, void *p0
)
3516 struct no_conflict_data
*p
= (struct no_conflict_data
*) p0
;
3518 /* If this inns directly contributes to setting the target, it must stay. */
3519 if (reg_overlap_mentioned_p (p
->target
, dest
))
3520 p
->must_stay
= true;
3521 /* If we haven't committed to keeping any other insns in the list yet,
3522 there is nothing more to check. */
3523 else if (p
->insn
== p
->first
)
3525 /* If this insn sets / clobbers a register that feeds one of the insns
3526 already in the list, this insn has to stay too. */
3527 else if (reg_overlap_mentioned_p (dest
, PATTERN (p
->first
))
3528 || (CALL_P (p
->first
) && (find_reg_fusage (p
->first
, USE
, dest
)))
3529 || reg_used_between_p (dest
, p
->first
, p
->insn
)
3530 /* Likewise if this insn depends on a register set by a previous
3531 insn in the list, or if it sets a result (presumably a hard
3532 register) that is set or clobbered by a previous insn.
3533 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3534 SET_DEST perform the former check on the address, and the latter
3535 check on the MEM. */
3536 || (GET_CODE (set
) == SET
3537 && (modified_in_p (SET_SRC (set
), p
->first
)
3538 || modified_in_p (SET_DEST (set
), p
->first
)
3539 || modified_between_p (SET_SRC (set
), p
->first
, p
->insn
)
3540 || modified_between_p (SET_DEST (set
), p
->first
, p
->insn
))))
3541 p
->must_stay
= true;
3545 /* Emit code to make a call to a constant function or a library call.
3547 INSNS is a list containing all insns emitted in the call.
3548 These insns leave the result in RESULT. Our block is to copy RESULT
3549 to TARGET, which is logically equivalent to EQUIV.
3551 We first emit any insns that set a pseudo on the assumption that these are
3552 loading constants into registers; doing so allows them to be safely cse'ed
3553 between blocks. Then we emit all the other insns in the block, followed by
3554 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3555 note with an operand of EQUIV. */
3558 emit_libcall_block_1 (rtx_insn
*insns
, rtx target
, rtx result
, rtx equiv
,
3559 bool equiv_may_trap
)
3561 rtx final_dest
= target
;
3562 rtx_insn
*next
, *last
, *insn
;
3564 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3565 into a MEM later. Protect the libcall block from this change. */
3566 if (! REG_P (target
) || REG_USERVAR_P (target
))
3567 target
= gen_reg_rtx (GET_MODE (target
));
3569 /* If we're using non-call exceptions, a libcall corresponding to an
3570 operation that may trap may also trap. */
3571 /* ??? See the comment in front of make_reg_eh_region_note. */
3572 if (cfun
->can_throw_non_call_exceptions
3573 && (equiv_may_trap
|| may_trap_p (equiv
)))
3575 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3578 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
3581 int lp_nr
= INTVAL (XEXP (note
, 0));
3582 if (lp_nr
== 0 || lp_nr
== INT_MIN
)
3583 remove_note (insn
, note
);
3589 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3590 reg note to indicate that this call cannot throw or execute a nonlocal
3591 goto (unless there is already a REG_EH_REGION note, in which case
3593 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3595 make_reg_eh_region_note_nothrow_nononlocal (insn
);
3598 /* First emit all insns that set pseudos. Remove them from the list as
3599 we go. Avoid insns that set pseudos which were referenced in previous
3600 insns. These can be generated by move_by_pieces, for example,
3601 to update an address. Similarly, avoid insns that reference things
3602 set in previous insns. */
3604 for (insn
= insns
; insn
; insn
= next
)
3606 rtx set
= single_set (insn
);
3608 next
= NEXT_INSN (insn
);
3610 if (set
!= 0 && REG_P (SET_DEST (set
))
3611 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
)
3613 struct no_conflict_data data
;
3615 data
.target
= const0_rtx
;
3619 note_stores (PATTERN (insn
), no_conflict_move_test
, &data
);
3620 if (! data
.must_stay
)
3622 if (PREV_INSN (insn
))
3623 SET_NEXT_INSN (PREV_INSN (insn
)) = next
;
3628 SET_PREV_INSN (next
) = PREV_INSN (insn
);
3634 /* Some ports use a loop to copy large arguments onto the stack.
3635 Don't move anything outside such a loop. */
3640 /* Write the remaining insns followed by the final copy. */
3641 for (insn
= insns
; insn
; insn
= next
)
3643 next
= NEXT_INSN (insn
);
3648 last
= emit_move_insn (target
, result
);
3650 set_dst_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
), target
);
3652 if (final_dest
!= target
)
3653 emit_move_insn (final_dest
, target
);
3657 emit_libcall_block (rtx insns
, rtx target
, rtx result
, rtx equiv
)
3659 emit_libcall_block_1 (safe_as_a
<rtx_insn
*> (insns
),
3660 target
, result
, equiv
, false);
3663 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3664 PURPOSE describes how this comparison will be used. CODE is the rtx
3665 comparison code we will be using.
3667 ??? Actually, CODE is slightly weaker than that. A target is still
3668 required to implement all of the normal bcc operations, but not
3669 required to implement all (or any) of the unordered bcc operations. */
3672 can_compare_p (enum rtx_code code
, machine_mode mode
,
3673 enum can_compare_purpose purpose
)
3676 test
= gen_rtx_fmt_ee (code
, mode
, const0_rtx
, const0_rtx
);
3679 enum insn_code icode
;
3681 if (purpose
== ccp_jump
3682 && (icode
= optab_handler (cbranch_optab
, mode
)) != CODE_FOR_nothing
3683 && insn_operand_matches (icode
, 0, test
))
3685 if (purpose
== ccp_store_flag
3686 && (icode
= optab_handler (cstore_optab
, mode
)) != CODE_FOR_nothing
3687 && insn_operand_matches (icode
, 1, test
))
3689 if (purpose
== ccp_cmov
3690 && optab_handler (cmov_optab
, mode
) != CODE_FOR_nothing
)
3693 mode
= GET_MODE_WIDER_MODE (mode
);
3694 PUT_MODE (test
, mode
);
3696 while (mode
!= VOIDmode
);
3701 /* This function is called when we are going to emit a compare instruction that
3702 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3704 *PMODE is the mode of the inputs (in case they are const_int).
3705 *PUNSIGNEDP nonzero says that the operands are unsigned;
3706 this matters if they need to be widened (as given by METHODS).
3708 If they have mode BLKmode, then SIZE specifies the size of both operands.
3710 This function performs all the setup necessary so that the caller only has
3711 to emit a single comparison insn. This setup can involve doing a BLKmode
3712 comparison or emitting a library call to perform the comparison if no insn
3713 is available to handle it.
3714 The values which are passed in through pointers can be modified; the caller
3715 should perform the comparison on the modified values. Constant
3716 comparisons must have already been folded. */
3719 prepare_cmp_insn (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
3720 int unsignedp
, enum optab_methods methods
,
3721 rtx
*ptest
, machine_mode
*pmode
)
3723 machine_mode mode
= *pmode
;
3725 machine_mode cmp_mode
;
3726 enum mode_class mclass
;
3728 /* The other methods are not needed. */
3729 gcc_assert (methods
== OPTAB_DIRECT
|| methods
== OPTAB_WIDEN
3730 || methods
== OPTAB_LIB_WIDEN
);
3732 /* If we are optimizing, force expensive constants into a register. */
3733 if (CONSTANT_P (x
) && optimize
3734 && (rtx_cost (x
, mode
, COMPARE
, 0, optimize_insn_for_speed_p ())
3735 > COSTS_N_INSNS (1)))
3736 x
= force_reg (mode
, x
);
3738 if (CONSTANT_P (y
) && optimize
3739 && (rtx_cost (y
, mode
, COMPARE
, 1, optimize_insn_for_speed_p ())
3740 > COSTS_N_INSNS (1)))
3741 y
= force_reg (mode
, y
);
3744 /* Make sure if we have a canonical comparison. The RTL
3745 documentation states that canonical comparisons are required only
3746 for targets which have cc0. */
3747 gcc_assert (!CONSTANT_P (x
) || CONSTANT_P (y
));
3750 /* Don't let both operands fail to indicate the mode. */
3751 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
3752 x
= force_reg (mode
, x
);
3753 if (mode
== VOIDmode
)
3754 mode
= GET_MODE (x
) != VOIDmode
? GET_MODE (x
) : GET_MODE (y
);
3756 /* Handle all BLKmode compares. */
3758 if (mode
== BLKmode
)
3760 machine_mode result_mode
;
3761 enum insn_code cmp_code
;
3766 = GEN_INT (MIN (MEM_ALIGN (x
), MEM_ALIGN (y
)) / BITS_PER_UNIT
);
3770 /* Try to use a memory block compare insn - either cmpstr
3771 or cmpmem will do. */
3772 for (cmp_mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
3773 cmp_mode
!= VOIDmode
;
3774 cmp_mode
= GET_MODE_WIDER_MODE (cmp_mode
))
3776 cmp_code
= direct_optab_handler (cmpmem_optab
, cmp_mode
);
3777 if (cmp_code
== CODE_FOR_nothing
)
3778 cmp_code
= direct_optab_handler (cmpstr_optab
, cmp_mode
);
3779 if (cmp_code
== CODE_FOR_nothing
)
3780 cmp_code
= direct_optab_handler (cmpstrn_optab
, cmp_mode
);
3781 if (cmp_code
== CODE_FOR_nothing
)
3784 /* Must make sure the size fits the insn's mode. */
3785 if ((CONST_INT_P (size
)
3786 && INTVAL (size
) >= (1 << GET_MODE_BITSIZE (cmp_mode
)))
3787 || (GET_MODE_BITSIZE (GET_MODE (size
))
3788 > GET_MODE_BITSIZE (cmp_mode
)))
3791 result_mode
= insn_data
[cmp_code
].operand
[0].mode
;
3792 result
= gen_reg_rtx (result_mode
);
3793 size
= convert_to_mode (cmp_mode
, size
, 1);
3794 emit_insn (GEN_FCN (cmp_code
) (result
, x
, y
, size
, opalign
));
3796 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, result
, const0_rtx
);
3797 *pmode
= result_mode
;
3801 if (methods
!= OPTAB_LIB
&& methods
!= OPTAB_LIB_WIDEN
)
3804 /* Otherwise call a library function, memcmp. */
3805 libfunc
= memcmp_libfunc
;
3806 length_type
= sizetype
;
3807 result_mode
= TYPE_MODE (integer_type_node
);
3808 cmp_mode
= TYPE_MODE (length_type
);
3809 size
= convert_to_mode (TYPE_MODE (length_type
), size
,
3810 TYPE_UNSIGNED (length_type
));
3812 result
= emit_library_call_value (libfunc
, 0, LCT_PURE
,
3820 methods
= OPTAB_LIB_WIDEN
;
3824 /* Don't allow operands to the compare to trap, as that can put the
3825 compare and branch in different basic blocks. */
3826 if (cfun
->can_throw_non_call_exceptions
)
3829 x
= force_reg (mode
, x
);
3831 y
= force_reg (mode
, y
);
3834 if (GET_MODE_CLASS (mode
) == MODE_CC
)
3836 enum insn_code icode
= optab_handler (cbranch_optab
, CCmode
);
3837 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
3838 gcc_assert (icode
!= CODE_FOR_nothing
3839 && insn_operand_matches (icode
, 0, test
));
3844 mclass
= GET_MODE_CLASS (mode
);
3845 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
3849 enum insn_code icode
;
3850 icode
= optab_handler (cbranch_optab
, cmp_mode
);
3851 if (icode
!= CODE_FOR_nothing
3852 && insn_operand_matches (icode
, 0, test
))
3854 rtx_insn
*last
= get_last_insn ();
3855 rtx op0
= prepare_operand (icode
, x
, 1, mode
, cmp_mode
, unsignedp
);
3856 rtx op1
= prepare_operand (icode
, y
, 2, mode
, cmp_mode
, unsignedp
);
3858 && insn_operand_matches (icode
, 1, op0
)
3859 && insn_operand_matches (icode
, 2, op1
))
3861 XEXP (test
, 0) = op0
;
3862 XEXP (test
, 1) = op1
;
3867 delete_insns_since (last
);
3870 if (methods
== OPTAB_DIRECT
|| !CLASS_HAS_WIDER_MODES_P (mclass
))
3872 cmp_mode
= GET_MODE_WIDER_MODE (cmp_mode
);
3874 while (cmp_mode
!= VOIDmode
);
3876 if (methods
!= OPTAB_LIB_WIDEN
)
3879 if (!SCALAR_FLOAT_MODE_P (mode
))
3882 machine_mode ret_mode
;
3884 /* Handle a libcall just for the mode we are using. */
3885 libfunc
= optab_libfunc (cmp_optab
, mode
);
3886 gcc_assert (libfunc
);
3888 /* If we want unsigned, and this mode has a distinct unsigned
3889 comparison routine, use that. */
3892 rtx ulibfunc
= optab_libfunc (ucmp_optab
, mode
);
3897 ret_mode
= targetm
.libgcc_cmp_return_mode ();
3898 result
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
3899 ret_mode
, 2, x
, mode
, y
, mode
);
3901 /* There are two kinds of comparison routines. Biased routines
3902 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3903 of gcc expect that the comparison operation is equivalent
3904 to the modified comparison. For signed comparisons compare the
3905 result against 1 in the biased case, and zero in the unbiased
3906 case. For unsigned comparisons always compare against 1 after
3907 biasing the unbiased result by adding 1. This gives us a way to
3909 The comparisons in the fixed-point helper library are always
3914 if (!TARGET_LIB_INT_CMP_BIASED
&& !ALL_FIXED_POINT_MODE_P (mode
))
3917 x
= plus_constant (ret_mode
, result
, 1);
3923 prepare_cmp_insn (x
, y
, comparison
, NULL_RTX
, unsignedp
, methods
,
3927 prepare_float_lib_cmp (x
, y
, comparison
, ptest
, pmode
);
3935 /* Before emitting an insn with code ICODE, make sure that X, which is going
3936 to be used for operand OPNUM of the insn, is converted from mode MODE to
3937 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3938 that it is accepted by the operand predicate. Return the new value. */
3941 prepare_operand (enum insn_code icode
, rtx x
, int opnum
, machine_mode mode
,
3942 machine_mode wider_mode
, int unsignedp
)
3944 if (mode
!= wider_mode
)
3945 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
3947 if (!insn_operand_matches (icode
, opnum
, x
))
3949 machine_mode op_mode
= insn_data
[(int) icode
].operand
[opnum
].mode
;
3950 if (reload_completed
)
3952 if (GET_MODE (x
) != op_mode
&& GET_MODE (x
) != VOIDmode
)
3954 x
= copy_to_mode_reg (op_mode
, x
);
3960 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3961 we can do the branch. */
3964 emit_cmp_and_jump_insn_1 (rtx test
, machine_mode mode
, rtx label
, int prob
)
3966 machine_mode optab_mode
;
3967 enum mode_class mclass
;
3968 enum insn_code icode
;
3971 mclass
= GET_MODE_CLASS (mode
);
3972 optab_mode
= (mclass
== MODE_CC
) ? CCmode
: mode
;
3973 icode
= optab_handler (cbranch_optab
, optab_mode
);
3975 gcc_assert (icode
!= CODE_FOR_nothing
);
3976 gcc_assert (insn_operand_matches (icode
, 0, test
));
3977 insn
= emit_jump_insn (GEN_FCN (icode
) (test
, XEXP (test
, 0),
3978 XEXP (test
, 1), label
));
3980 && profile_status_for_fn (cfun
) != PROFILE_ABSENT
3983 && any_condjump_p (insn
)
3984 && !find_reg_note (insn
, REG_BR_PROB
, 0))
3985 add_int_reg_note (insn
, REG_BR_PROB
, prob
);
3988 /* Generate code to compare X with Y so that the condition codes are
3989 set and to jump to LABEL if the condition is true. If X is a
3990 constant and Y is not a constant, then the comparison is swapped to
3991 ensure that the comparison RTL has the canonical form.
3993 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3994 need to be widened. UNSIGNEDP is also used to select the proper
3995 branch condition code.
3997 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3999 MODE is the mode of the inputs (in case they are const_int).
4001 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4002 It will be potentially converted into an unsigned variant based on
4003 UNSIGNEDP to select a proper jump instruction.
4005 PROB is the probability of jumping to LABEL. */
4008 emit_cmp_and_jump_insns (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4009 machine_mode mode
, int unsignedp
, rtx label
,
4012 rtx op0
= x
, op1
= y
;
4015 /* Swap operands and condition to ensure canonical RTL. */
4016 if (swap_commutative_operands_p (x
, y
)
4017 && can_compare_p (swap_condition (comparison
), mode
, ccp_jump
))
4020 comparison
= swap_condition (comparison
);
4023 /* If OP0 is still a constant, then both X and Y must be constants
4024 or the opposite comparison is not supported. Force X into a register
4025 to create canonical RTL. */
4026 if (CONSTANT_P (op0
))
4027 op0
= force_reg (mode
, op0
);
4030 comparison
= unsigned_condition (comparison
);
4032 prepare_cmp_insn (op0
, op1
, comparison
, size
, unsignedp
, OPTAB_LIB_WIDEN
,
4034 emit_cmp_and_jump_insn_1 (test
, mode
, label
, prob
);
4038 /* Emit a library call comparison between floating point X and Y.
4039 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4042 prepare_float_lib_cmp (rtx x
, rtx y
, enum rtx_code comparison
,
4043 rtx
*ptest
, machine_mode
*pmode
)
4045 enum rtx_code swapped
= swap_condition (comparison
);
4046 enum rtx_code reversed
= reverse_condition_maybe_unordered (comparison
);
4047 machine_mode orig_mode
= GET_MODE (x
);
4048 machine_mode mode
, cmp_mode
;
4049 rtx true_rtx
, false_rtx
;
4050 rtx value
, target
, equiv
;
4053 bool reversed_p
= false;
4054 cmp_mode
= targetm
.libgcc_cmp_return_mode ();
4056 for (mode
= orig_mode
;
4058 mode
= GET_MODE_WIDER_MODE (mode
))
4060 if (code_to_optab (comparison
)
4061 && (libfunc
= optab_libfunc (code_to_optab (comparison
), mode
)))
4064 if (code_to_optab (swapped
)
4065 && (libfunc
= optab_libfunc (code_to_optab (swapped
), mode
)))
4068 comparison
= swapped
;
4072 if (code_to_optab (reversed
)
4073 && (libfunc
= optab_libfunc (code_to_optab (reversed
), mode
)))
4075 comparison
= reversed
;
4081 gcc_assert (mode
!= VOIDmode
);
4083 if (mode
!= orig_mode
)
4085 x
= convert_to_mode (mode
, x
, 0);
4086 y
= convert_to_mode (mode
, y
, 0);
4089 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4090 the RTL. The allows the RTL optimizers to delete the libcall if the
4091 condition can be determined at compile-time. */
4092 if (comparison
== UNORDERED
4093 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4095 true_rtx
= const_true_rtx
;
4096 false_rtx
= const0_rtx
;
4103 true_rtx
= const0_rtx
;
4104 false_rtx
= const_true_rtx
;
4108 true_rtx
= const_true_rtx
;
4109 false_rtx
= const0_rtx
;
4113 true_rtx
= const1_rtx
;
4114 false_rtx
= const0_rtx
;
4118 true_rtx
= const0_rtx
;
4119 false_rtx
= constm1_rtx
;
4123 true_rtx
= constm1_rtx
;
4124 false_rtx
= const0_rtx
;
4128 true_rtx
= const0_rtx
;
4129 false_rtx
= const1_rtx
;
4137 if (comparison
== UNORDERED
)
4139 rtx temp
= simplify_gen_relational (NE
, cmp_mode
, mode
, x
, x
);
4140 equiv
= simplify_gen_relational (NE
, cmp_mode
, mode
, y
, y
);
4141 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4142 temp
, const_true_rtx
, equiv
);
4146 equiv
= simplify_gen_relational (comparison
, cmp_mode
, mode
, x
, y
);
4147 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4148 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4149 equiv
, true_rtx
, false_rtx
);
4153 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4154 cmp_mode
, 2, x
, mode
, y
, mode
);
4155 insns
= get_insns ();
4158 target
= gen_reg_rtx (cmp_mode
);
4159 emit_libcall_block (insns
, target
, value
, equiv
);
4161 if (comparison
== UNORDERED
4162 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
)
4164 *ptest
= gen_rtx_fmt_ee (reversed_p
? EQ
: NE
, VOIDmode
, target
, false_rtx
);
4166 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, target
, const0_rtx
);
4171 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4174 emit_indirect_jump (rtx loc
)
4176 if (!targetm
.have_indirect_jump ())
4177 sorry ("indirect jumps are not available on this target");
4180 struct expand_operand ops
[1];
4181 create_address_operand (&ops
[0], loc
);
4182 expand_jump_insn (targetm
.code_for_indirect_jump
, 1, ops
);
4188 /* Emit a conditional move instruction if the machine supports one for that
4189 condition and machine mode.
4191 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4192 the mode to use should they be constants. If it is VOIDmode, they cannot
4195 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4196 should be stored there. MODE is the mode to use should they be constants.
4197 If it is VOIDmode, they cannot both be constants.
4199 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4200 is not supported. */
4203 emit_conditional_move (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4204 machine_mode cmode
, rtx op2
, rtx op3
,
4205 machine_mode mode
, int unsignedp
)
4209 enum insn_code icode
;
4210 enum rtx_code reversed
;
4212 /* If one operand is constant, make it the second one. Only do this
4213 if the other operand is not constant as well. */
4215 if (swap_commutative_operands_p (op0
, op1
))
4217 std::swap (op0
, op1
);
4218 code
= swap_condition (code
);
4221 /* get_condition will prefer to generate LT and GT even if the old
4222 comparison was against zero, so undo that canonicalization here since
4223 comparisons against zero are cheaper. */
4224 if (code
== LT
&& op1
== const1_rtx
)
4225 code
= LE
, op1
= const0_rtx
;
4226 else if (code
== GT
&& op1
== constm1_rtx
)
4227 code
= GE
, op1
= const0_rtx
;
4229 if (cmode
== VOIDmode
)
4230 cmode
= GET_MODE (op0
);
4232 if (swap_commutative_operands_p (op2
, op3
)
4233 && ((reversed
= reversed_comparison_code_parts (code
, op0
, op1
, NULL
))
4236 std::swap (op2
, op3
);
4240 if (mode
== VOIDmode
)
4241 mode
= GET_MODE (op2
);
4243 icode
= direct_optab_handler (movcc_optab
, mode
);
4245 if (icode
== CODE_FOR_nothing
)
4249 target
= gen_reg_rtx (mode
);
4251 code
= unsignedp
? unsigned_condition (code
) : code
;
4252 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4254 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4255 return NULL and let the caller figure out how best to deal with this
4257 if (!COMPARISON_P (comparison
))
4260 saved_pending_stack_adjust save
;
4261 save_pending_stack_adjust (&save
);
4262 last
= get_last_insn ();
4263 do_pending_stack_adjust ();
4264 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4265 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4266 &comparison
, &cmode
);
4269 struct expand_operand ops
[4];
4271 create_output_operand (&ops
[0], target
, mode
);
4272 create_fixed_operand (&ops
[1], comparison
);
4273 create_input_operand (&ops
[2], op2
, mode
);
4274 create_input_operand (&ops
[3], op3
, mode
);
4275 if (maybe_expand_insn (icode
, 4, ops
))
4277 if (ops
[0].value
!= target
)
4278 convert_move (target
, ops
[0].value
, false);
4282 delete_insns_since (last
);
4283 restore_pending_stack_adjust (&save
);
4288 /* Emit a conditional negate or bitwise complement using the
4289 negcc or notcc optabs if available. Return NULL_RTX if such operations
4290 are not available. Otherwise return the RTX holding the result.
4291 TARGET is the desired destination of the result. COMP is the comparison
4292 on which to negate. If COND is true move into TARGET the negation
4293 or bitwise complement of OP1. Otherwise move OP2 into TARGET.
4294 CODE is either NEG or NOT. MODE is the machine mode in which the
4295 operation is performed. */
4298 emit_conditional_neg_or_complement (rtx target
, rtx_code code
,
4299 machine_mode mode
, rtx cond
, rtx op1
,
4302 optab op
= unknown_optab
;
4305 else if (code
== NOT
)
4310 insn_code icode
= direct_optab_handler (op
, mode
);
4312 if (icode
== CODE_FOR_nothing
)
4316 target
= gen_reg_rtx (mode
);
4318 rtx_insn
*last
= get_last_insn ();
4319 struct expand_operand ops
[4];
4321 create_output_operand (&ops
[0], target
, mode
);
4322 create_fixed_operand (&ops
[1], cond
);
4323 create_input_operand (&ops
[2], op1
, mode
);
4324 create_input_operand (&ops
[3], op2
, mode
);
4326 if (maybe_expand_insn (icode
, 4, ops
))
4328 if (ops
[0].value
!= target
)
4329 convert_move (target
, ops
[0].value
, false);
4333 delete_insns_since (last
);
4337 /* Emit a conditional addition instruction if the machine supports one for that
4338 condition and machine mode.
4340 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4341 the mode to use should they be constants. If it is VOIDmode, they cannot
4344 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4345 should be stored there. MODE is the mode to use should they be constants.
4346 If it is VOIDmode, they cannot both be constants.
4348 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4349 is not supported. */
4352 emit_conditional_add (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4353 machine_mode cmode
, rtx op2
, rtx op3
,
4354 machine_mode mode
, int unsignedp
)
4358 enum insn_code icode
;
4360 /* If one operand is constant, make it the second one. Only do this
4361 if the other operand is not constant as well. */
4363 if (swap_commutative_operands_p (op0
, op1
))
4365 std::swap (op0
, op1
);
4366 code
= swap_condition (code
);
4369 /* get_condition will prefer to generate LT and GT even if the old
4370 comparison was against zero, so undo that canonicalization here since
4371 comparisons against zero are cheaper. */
4372 if (code
== LT
&& op1
== const1_rtx
)
4373 code
= LE
, op1
= const0_rtx
;
4374 else if (code
== GT
&& op1
== constm1_rtx
)
4375 code
= GE
, op1
= const0_rtx
;
4377 if (cmode
== VOIDmode
)
4378 cmode
= GET_MODE (op0
);
4380 if (mode
== VOIDmode
)
4381 mode
= GET_MODE (op2
);
4383 icode
= optab_handler (addcc_optab
, mode
);
4385 if (icode
== CODE_FOR_nothing
)
4389 target
= gen_reg_rtx (mode
);
4391 code
= unsignedp
? unsigned_condition (code
) : code
;
4392 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4394 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4395 return NULL and let the caller figure out how best to deal with this
4397 if (!COMPARISON_P (comparison
))
4400 do_pending_stack_adjust ();
4401 last
= get_last_insn ();
4402 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4403 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4404 &comparison
, &cmode
);
4407 struct expand_operand ops
[4];
4409 create_output_operand (&ops
[0], target
, mode
);
4410 create_fixed_operand (&ops
[1], comparison
);
4411 create_input_operand (&ops
[2], op2
, mode
);
4412 create_input_operand (&ops
[3], op3
, mode
);
4413 if (maybe_expand_insn (icode
, 4, ops
))
4415 if (ops
[0].value
!= target
)
4416 convert_move (target
, ops
[0].value
, false);
4420 delete_insns_since (last
);
4424 /* These functions attempt to generate an insn body, rather than
4425 emitting the insn, but if the gen function already emits them, we
4426 make no attempt to turn them back into naked patterns. */
4428 /* Generate and return an insn body to add Y to X. */
4431 gen_add2_insn (rtx x
, rtx y
)
4433 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (x
));
4435 gcc_assert (insn_operand_matches (icode
, 0, x
));
4436 gcc_assert (insn_operand_matches (icode
, 1, x
));
4437 gcc_assert (insn_operand_matches (icode
, 2, y
));
4439 return GEN_FCN (icode
) (x
, x
, y
);
4442 /* Generate and return an insn body to add r1 and c,
4443 storing the result in r0. */
4446 gen_add3_insn (rtx r0
, rtx r1
, rtx c
)
4448 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (r0
));
4450 if (icode
== CODE_FOR_nothing
4451 || !insn_operand_matches (icode
, 0, r0
)
4452 || !insn_operand_matches (icode
, 1, r1
)
4453 || !insn_operand_matches (icode
, 2, c
))
4456 return GEN_FCN (icode
) (r0
, r1
, c
);
4460 have_add2_insn (rtx x
, rtx y
)
4462 enum insn_code icode
;
4464 gcc_assert (GET_MODE (x
) != VOIDmode
);
4466 icode
= optab_handler (add_optab
, GET_MODE (x
));
4468 if (icode
== CODE_FOR_nothing
)
4471 if (!insn_operand_matches (icode
, 0, x
)
4472 || !insn_operand_matches (icode
, 1, x
)
4473 || !insn_operand_matches (icode
, 2, y
))
4479 /* Generate and return an insn body to add Y to X. */
4482 gen_addptr3_insn (rtx x
, rtx y
, rtx z
)
4484 enum insn_code icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
4486 gcc_assert (insn_operand_matches (icode
, 0, x
));
4487 gcc_assert (insn_operand_matches (icode
, 1, y
));
4488 gcc_assert (insn_operand_matches (icode
, 2, z
));
4490 return GEN_FCN (icode
) (x
, y
, z
);
4493 /* Return true if the target implements an addptr pattern and X, Y,
4494 and Z are valid for the pattern predicates. */
4497 have_addptr3_insn (rtx x
, rtx y
, rtx z
)
4499 enum insn_code icode
;
4501 gcc_assert (GET_MODE (x
) != VOIDmode
);
4503 icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
4505 if (icode
== CODE_FOR_nothing
)
4508 if (!insn_operand_matches (icode
, 0, x
)
4509 || !insn_operand_matches (icode
, 1, y
)
4510 || !insn_operand_matches (icode
, 2, z
))
4516 /* Generate and return an insn body to subtract Y from X. */
4519 gen_sub2_insn (rtx x
, rtx y
)
4521 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (x
));
4523 gcc_assert (insn_operand_matches (icode
, 0, x
));
4524 gcc_assert (insn_operand_matches (icode
, 1, x
));
4525 gcc_assert (insn_operand_matches (icode
, 2, y
));
4527 return GEN_FCN (icode
) (x
, x
, y
);
4530 /* Generate and return an insn body to subtract r1 and c,
4531 storing the result in r0. */
4534 gen_sub3_insn (rtx r0
, rtx r1
, rtx c
)
4536 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (r0
));
4538 if (icode
== CODE_FOR_nothing
4539 || !insn_operand_matches (icode
, 0, r0
)
4540 || !insn_operand_matches (icode
, 1, r1
)
4541 || !insn_operand_matches (icode
, 2, c
))
4544 return GEN_FCN (icode
) (r0
, r1
, c
);
4548 have_sub2_insn (rtx x
, rtx y
)
4550 enum insn_code icode
;
4552 gcc_assert (GET_MODE (x
) != VOIDmode
);
4554 icode
= optab_handler (sub_optab
, GET_MODE (x
));
4556 if (icode
== CODE_FOR_nothing
)
4559 if (!insn_operand_matches (icode
, 0, x
)
4560 || !insn_operand_matches (icode
, 1, x
)
4561 || !insn_operand_matches (icode
, 2, y
))
4567 /* Generate the body of an insn to extend Y (with mode MFROM)
4568 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4571 gen_extend_insn (rtx x
, rtx y
, machine_mode mto
,
4572 machine_mode mfrom
, int unsignedp
)
4574 enum insn_code icode
= can_extend_p (mto
, mfrom
, unsignedp
);
4575 return GEN_FCN (icode
) (x
, y
);
4578 /* Generate code to convert FROM to floating point
4579 and store in TO. FROM must be fixed point and not VOIDmode.
4580 UNSIGNEDP nonzero means regard FROM as unsigned.
4581 Normally this is done by correcting the final value
4582 if it is negative. */
4585 expand_float (rtx to
, rtx from
, int unsignedp
)
4587 enum insn_code icode
;
4589 machine_mode fmode
, imode
;
4590 bool can_do_signed
= false;
4592 /* Crash now, because we won't be able to decide which mode to use. */
4593 gcc_assert (GET_MODE (from
) != VOIDmode
);
4595 /* Look for an insn to do the conversion. Do it in the specified
4596 modes if possible; otherwise convert either input, output or both to
4597 wider mode. If the integer mode is wider than the mode of FROM,
4598 we can do the conversion signed even if the input is unsigned. */
4600 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
4601 fmode
= GET_MODE_WIDER_MODE (fmode
))
4602 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
4603 imode
= GET_MODE_WIDER_MODE (imode
))
4605 int doing_unsigned
= unsignedp
;
4607 if (fmode
!= GET_MODE (to
)
4608 && significand_size (fmode
) < GET_MODE_PRECISION (GET_MODE (from
)))
4611 icode
= can_float_p (fmode
, imode
, unsignedp
);
4612 if (icode
== CODE_FOR_nothing
&& unsignedp
)
4614 enum insn_code scode
= can_float_p (fmode
, imode
, 0);
4615 if (scode
!= CODE_FOR_nothing
)
4616 can_do_signed
= true;
4617 if (imode
!= GET_MODE (from
))
4618 icode
= scode
, doing_unsigned
= 0;
4621 if (icode
!= CODE_FOR_nothing
)
4623 if (imode
!= GET_MODE (from
))
4624 from
= convert_to_mode (imode
, from
, unsignedp
);
4626 if (fmode
!= GET_MODE (to
))
4627 target
= gen_reg_rtx (fmode
);
4629 emit_unop_insn (icode
, target
, from
,
4630 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
4633 convert_move (to
, target
, 0);
4638 /* Unsigned integer, and no way to convert directly. Convert as signed,
4639 then unconditionally adjust the result. */
4640 if (unsignedp
&& can_do_signed
)
4642 rtx_code_label
*label
= gen_label_rtx ();
4644 REAL_VALUE_TYPE offset
;
4646 /* Look for a usable floating mode FMODE wider than the source and at
4647 least as wide as the target. Using FMODE will avoid rounding woes
4648 with unsigned values greater than the signed maximum value. */
4650 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
4651 fmode
= GET_MODE_WIDER_MODE (fmode
))
4652 if (GET_MODE_PRECISION (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
4653 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
4656 if (fmode
== VOIDmode
)
4658 /* There is no such mode. Pretend the target is wide enough. */
4659 fmode
= GET_MODE (to
);
4661 /* Avoid double-rounding when TO is narrower than FROM. */
4662 if ((significand_size (fmode
) + 1)
4663 < GET_MODE_PRECISION (GET_MODE (from
)))
4666 rtx_code_label
*neglabel
= gen_label_rtx ();
4668 /* Don't use TARGET if it isn't a register, is a hard register,
4669 or is the wrong mode. */
4671 || REGNO (target
) < FIRST_PSEUDO_REGISTER
4672 || GET_MODE (target
) != fmode
)
4673 target
= gen_reg_rtx (fmode
);
4675 imode
= GET_MODE (from
);
4676 do_pending_stack_adjust ();
4678 /* Test whether the sign bit is set. */
4679 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
4682 /* The sign bit is not set. Convert as signed. */
4683 expand_float (target
, from
, 0);
4684 emit_jump_insn (targetm
.gen_jump (label
));
4687 /* The sign bit is set.
4688 Convert to a usable (positive signed) value by shifting right
4689 one bit, while remembering if a nonzero bit was shifted
4690 out; i.e., compute (from & 1) | (from >> 1). */
4692 emit_label (neglabel
);
4693 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
4694 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
4695 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, 1, NULL_RTX
, 1);
4696 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
4698 expand_float (target
, temp
, 0);
4700 /* Multiply by 2 to undo the shift above. */
4701 temp
= expand_binop (fmode
, add_optab
, target
, target
,
4702 target
, 0, OPTAB_LIB_WIDEN
);
4704 emit_move_insn (target
, temp
);
4706 do_pending_stack_adjust ();
4712 /* If we are about to do some arithmetic to correct for an
4713 unsigned operand, do it in a pseudo-register. */
4715 if (GET_MODE (to
) != fmode
4716 || !REG_P (to
) || REGNO (to
) < FIRST_PSEUDO_REGISTER
)
4717 target
= gen_reg_rtx (fmode
);
4719 /* Convert as signed integer to floating. */
4720 expand_float (target
, from
, 0);
4722 /* If FROM is negative (and therefore TO is negative),
4723 correct its value by 2**bitwidth. */
4725 do_pending_stack_adjust ();
4726 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
),
4730 real_2expN (&offset
, GET_MODE_PRECISION (GET_MODE (from
)), fmode
);
4731 temp
= expand_binop (fmode
, add_optab
, target
,
4732 const_double_from_real_value (offset
, fmode
),
4733 target
, 0, OPTAB_LIB_WIDEN
);
4735 emit_move_insn (target
, temp
);
4737 do_pending_stack_adjust ();
4742 /* No hardware instruction available; call a library routine. */
4747 convert_optab tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
4749 if (GET_MODE_PRECISION (GET_MODE (from
)) < GET_MODE_PRECISION (SImode
))
4750 from
= convert_to_mode (SImode
, from
, unsignedp
);
4752 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
4753 gcc_assert (libfunc
);
4757 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4758 GET_MODE (to
), 1, from
,
4760 insns
= get_insns ();
4763 emit_libcall_block (insns
, target
, value
,
4764 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FLOAT
: FLOAT
,
4765 GET_MODE (to
), from
));
4770 /* Copy result to requested destination
4771 if we have been computing in a temp location. */
4775 if (GET_MODE (target
) == GET_MODE (to
))
4776 emit_move_insn (to
, target
);
4778 convert_move (to
, target
, 0);
4782 /* Generate code to convert FROM to fixed point and store in TO. FROM
4783 must be floating point. */
4786 expand_fix (rtx to
, rtx from
, int unsignedp
)
4788 enum insn_code icode
;
4790 machine_mode fmode
, imode
;
4791 bool must_trunc
= false;
4793 /* We first try to find a pair of modes, one real and one integer, at
4794 least as wide as FROM and TO, respectively, in which we can open-code
4795 this conversion. If the integer mode is wider than the mode of TO,
4796 we can do the conversion either signed or unsigned. */
4798 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
4799 fmode
= GET_MODE_WIDER_MODE (fmode
))
4800 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
4801 imode
= GET_MODE_WIDER_MODE (imode
))
4803 int doing_unsigned
= unsignedp
;
4805 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
4806 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
4807 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
4809 if (icode
!= CODE_FOR_nothing
)
4811 rtx_insn
*last
= get_last_insn ();
4812 if (fmode
!= GET_MODE (from
))
4813 from
= convert_to_mode (fmode
, from
, 0);
4817 rtx temp
= gen_reg_rtx (GET_MODE (from
));
4818 from
= expand_unop (GET_MODE (from
), ftrunc_optab
, from
,
4822 if (imode
!= GET_MODE (to
))
4823 target
= gen_reg_rtx (imode
);
4825 if (maybe_emit_unop_insn (icode
, target
, from
,
4826 doing_unsigned
? UNSIGNED_FIX
: FIX
))
4829 convert_move (to
, target
, unsignedp
);
4832 delete_insns_since (last
);
4836 /* For an unsigned conversion, there is one more way to do it.
4837 If we have a signed conversion, we generate code that compares
4838 the real value to the largest representable positive number. If if
4839 is smaller, the conversion is done normally. Otherwise, subtract
4840 one plus the highest signed number, convert, and add it back.
4842 We only need to check all real modes, since we know we didn't find
4843 anything with a wider integer mode.
4845 This code used to extend FP value into mode wider than the destination.
4846 This is needed for decimal float modes which cannot accurately
4847 represent one plus the highest signed number of the same size, but
4848 not for binary modes. Consider, for instance conversion from SFmode
4851 The hot path through the code is dealing with inputs smaller than 2^63
4852 and doing just the conversion, so there is no bits to lose.
4854 In the other path we know the value is positive in the range 2^63..2^64-1
4855 inclusive. (as for other input overflow happens and result is undefined)
4856 So we know that the most important bit set in mantissa corresponds to
4857 2^63. The subtraction of 2^63 should not generate any rounding as it
4858 simply clears out that bit. The rest is trivial. */
4860 if (unsignedp
&& GET_MODE_PRECISION (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
4861 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
4862 fmode
= GET_MODE_WIDER_MODE (fmode
))
4863 if (CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0, &must_trunc
)
4864 && (!DECIMAL_FLOAT_MODE_P (fmode
)
4865 || GET_MODE_BITSIZE (fmode
) > GET_MODE_PRECISION (GET_MODE (to
))))
4868 REAL_VALUE_TYPE offset
;
4870 rtx_code_label
*lab1
, *lab2
;
4873 bitsize
= GET_MODE_PRECISION (GET_MODE (to
));
4874 real_2expN (&offset
, bitsize
- 1, fmode
);
4875 limit
= const_double_from_real_value (offset
, fmode
);
4876 lab1
= gen_label_rtx ();
4877 lab2
= gen_label_rtx ();
4879 if (fmode
!= GET_MODE (from
))
4880 from
= convert_to_mode (fmode
, from
, 0);
4882 /* See if we need to do the subtraction. */
4883 do_pending_stack_adjust ();
4884 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
),
4887 /* If not, do the signed "fix" and branch around fixup code. */
4888 expand_fix (to
, from
, 0);
4889 emit_jump_insn (targetm
.gen_jump (lab2
));
4892 /* Otherwise, subtract 2**(N-1), convert to signed number,
4893 then add 2**(N-1). Do the addition using XOR since this
4894 will often generate better code. */
4896 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
4897 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4898 expand_fix (to
, target
, 0);
4899 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
4901 ((HOST_WIDE_INT
) 1 << (bitsize
- 1),
4903 to
, 1, OPTAB_LIB_WIDEN
);
4906 emit_move_insn (to
, target
);
4910 if (optab_handler (mov_optab
, GET_MODE (to
)) != CODE_FOR_nothing
)
4912 /* Make a place for a REG_NOTE and add it. */
4913 insn
= emit_move_insn (to
, to
);
4914 set_dst_reg_note (insn
, REG_EQUAL
,
4915 gen_rtx_fmt_e (UNSIGNED_FIX
, GET_MODE (to
),
4923 /* We can't do it with an insn, so use a library call. But first ensure
4924 that the mode of TO is at least as wide as SImode, since those are the
4925 only library calls we know about. */
4927 if (GET_MODE_PRECISION (GET_MODE (to
)) < GET_MODE_PRECISION (SImode
))
4929 target
= gen_reg_rtx (SImode
);
4931 expand_fix (target
, from
, unsignedp
);
4939 convert_optab tab
= unsignedp
? ufix_optab
: sfix_optab
;
4940 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
4941 gcc_assert (libfunc
);
4945 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4946 GET_MODE (to
), 1, from
,
4948 insns
= get_insns ();
4951 emit_libcall_block (insns
, target
, value
,
4952 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
4953 GET_MODE (to
), from
));
4958 if (GET_MODE (to
) == GET_MODE (target
))
4959 emit_move_insn (to
, target
);
4961 convert_move (to
, target
, 0);
4966 /* Promote integer arguments for a libcall if necessary.
4967 emit_library_call_value cannot do the promotion because it does not
4968 know if it should do a signed or unsigned promotion. This is because
4969 there are no tree types defined for libcalls. */
4972 prepare_libcall_arg (rtx arg
, int uintp
)
4974 machine_mode mode
= GET_MODE (arg
);
4975 machine_mode arg_mode
;
4976 if (SCALAR_INT_MODE_P (mode
))
4978 /* If we need to promote the integer function argument we need to do
4979 it here instead of inside emit_library_call_value because in
4980 emit_library_call_value we don't know if we should do a signed or
4981 unsigned promotion. */
4984 arg_mode
= promote_function_mode (NULL_TREE
, mode
,
4985 &unsigned_p
, NULL_TREE
, 0);
4986 if (arg_mode
!= mode
)
4987 return convert_to_mode (arg_mode
, arg
, uintp
);
4992 /* Generate code to convert FROM or TO a fixed-point.
4993 If UINTP is true, either TO or FROM is an unsigned integer.
4994 If SATP is true, we need to saturate the result. */
4997 expand_fixed_convert (rtx to
, rtx from
, int uintp
, int satp
)
4999 machine_mode to_mode
= GET_MODE (to
);
5000 machine_mode from_mode
= GET_MODE (from
);
5002 enum rtx_code this_code
;
5003 enum insn_code code
;
5008 if (to_mode
== from_mode
)
5010 emit_move_insn (to
, from
);
5016 tab
= satp
? satfractuns_optab
: fractuns_optab
;
5017 this_code
= satp
? UNSIGNED_SAT_FRACT
: UNSIGNED_FRACT_CONVERT
;
5021 tab
= satp
? satfract_optab
: fract_optab
;
5022 this_code
= satp
? SAT_FRACT
: FRACT_CONVERT
;
5024 code
= convert_optab_handler (tab
, to_mode
, from_mode
);
5025 if (code
!= CODE_FOR_nothing
)
5027 emit_unop_insn (code
, to
, from
, this_code
);
5031 libfunc
= convert_optab_libfunc (tab
, to_mode
, from_mode
);
5032 gcc_assert (libfunc
);
5034 from
= prepare_libcall_arg (from
, uintp
);
5035 from_mode
= GET_MODE (from
);
5038 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, to_mode
,
5039 1, from
, from_mode
);
5040 insns
= get_insns ();
5043 emit_libcall_block (insns
, to
, value
,
5044 gen_rtx_fmt_e (optab_to_code (tab
), to_mode
, from
));
5047 /* Generate code to convert FROM to fixed point and store in TO. FROM
5048 must be floating point, TO must be signed. Use the conversion optab
5049 TAB to do the conversion. */
5052 expand_sfix_optab (rtx to
, rtx from
, convert_optab tab
)
5054 enum insn_code icode
;
5056 machine_mode fmode
, imode
;
5058 /* We first try to find a pair of modes, one real and one integer, at
5059 least as wide as FROM and TO, respectively, in which we can open-code
5060 this conversion. If the integer mode is wider than the mode of TO,
5061 we can do the conversion either signed or unsigned. */
5063 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5064 fmode
= GET_MODE_WIDER_MODE (fmode
))
5065 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
5066 imode
= GET_MODE_WIDER_MODE (imode
))
5068 icode
= convert_optab_handler (tab
, imode
, fmode
);
5069 if (icode
!= CODE_FOR_nothing
)
5071 rtx_insn
*last
= get_last_insn ();
5072 if (fmode
!= GET_MODE (from
))
5073 from
= convert_to_mode (fmode
, from
, 0);
5075 if (imode
!= GET_MODE (to
))
5076 target
= gen_reg_rtx (imode
);
5078 if (!maybe_emit_unop_insn (icode
, target
, from
, UNKNOWN
))
5080 delete_insns_since (last
);
5084 convert_move (to
, target
, 0);
5092 /* Report whether we have an instruction to perform the operation
5093 specified by CODE on operands of mode MODE. */
5095 have_insn_for (enum rtx_code code
, machine_mode mode
)
5097 return (code_to_optab (code
)
5098 && (optab_handler (code_to_optab (code
), mode
)
5099 != CODE_FOR_nothing
));
5102 /* Print information about the current contents of the optabs on
5106 debug_optab_libfuncs (void)
5110 /* Dump the arithmetic optabs. */
5111 for (i
= FIRST_NORM_OPTAB
; i
<= LAST_NORMLIB_OPTAB
; ++i
)
5112 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
5114 rtx l
= optab_libfunc ((optab
) i
, (machine_mode
) j
);
5117 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
5118 fprintf (stderr
, "%s\t%s:\t%s\n",
5119 GET_RTX_NAME (optab_to_code ((optab
) i
)),
5125 /* Dump the conversion optabs. */
5126 for (i
= FIRST_CONV_OPTAB
; i
<= LAST_CONVLIB_OPTAB
; ++i
)
5127 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
5128 for (k
= 0; k
< NUM_MACHINE_MODES
; ++k
)
5130 rtx l
= convert_optab_libfunc ((optab
) i
, (machine_mode
) j
,
5134 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
5135 fprintf (stderr
, "%s\t%s\t%s:\t%s\n",
5136 GET_RTX_NAME (optab_to_code ((optab
) i
)),
5144 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5145 CODE. Return 0 on failure. */
5148 gen_cond_trap (enum rtx_code code
, rtx op1
, rtx op2
, rtx tcode
)
5150 machine_mode mode
= GET_MODE (op1
);
5151 enum insn_code icode
;
5155 if (mode
== VOIDmode
)
5158 icode
= optab_handler (ctrap_optab
, mode
);
5159 if (icode
== CODE_FOR_nothing
)
5162 /* Some targets only accept a zero trap code. */
5163 if (!insn_operand_matches (icode
, 3, tcode
))
5166 do_pending_stack_adjust ();
5168 prepare_cmp_insn (op1
, op2
, code
, NULL_RTX
, false, OPTAB_DIRECT
,
5173 insn
= GEN_FCN (icode
) (trap_rtx
, XEXP (trap_rtx
, 0), XEXP (trap_rtx
, 1),
5176 /* If that failed, then give up. */
5184 insn
= get_insns ();
5189 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5190 or unsigned operation code. */
5193 get_rtx_code (enum tree_code tcode
, bool unsignedp
)
5205 code
= unsignedp
? LTU
: LT
;
5208 code
= unsignedp
? LEU
: LE
;
5211 code
= unsignedp
? GTU
: GT
;
5214 code
= unsignedp
? GEU
: GE
;
5217 case UNORDERED_EXPR
:
5256 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
5257 unsigned operators. OPNO holds an index of the first comparison
5258 operand in insn with code ICODE. Do not generate compare instruction. */
5261 vector_compare_rtx (enum tree_code tcode
, tree t_op0
, tree t_op1
,
5262 bool unsignedp
, enum insn_code icode
,
5265 struct expand_operand ops
[2];
5266 rtx rtx_op0
, rtx_op1
;
5267 machine_mode m0
, m1
;
5268 enum rtx_code rcode
= get_rtx_code (tcode
, unsignedp
);
5270 gcc_assert (TREE_CODE_CLASS (tcode
) == tcc_comparison
);
5272 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
5273 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
5274 cases, use the original mode. */
5275 rtx_op0
= expand_expr (t_op0
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op0
)),
5277 m0
= GET_MODE (rtx_op0
);
5279 m0
= TYPE_MODE (TREE_TYPE (t_op0
));
5281 rtx_op1
= expand_expr (t_op1
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op1
)),
5283 m1
= GET_MODE (rtx_op1
);
5285 m1
= TYPE_MODE (TREE_TYPE (t_op1
));
5287 create_input_operand (&ops
[0], rtx_op0
, m0
);
5288 create_input_operand (&ops
[1], rtx_op1
, m1
);
5289 if (!maybe_legitimize_operands (icode
, opno
, 2, ops
))
5291 return gen_rtx_fmt_ee (rcode
, VOIDmode
, ops
[0].value
, ops
[1].value
);
5294 /* Checks if vec_perm mask SEL is a constant equivalent to a shift of the first
5295 vec_perm operand, assuming the second operand is a constant vector of zeroes.
5296 Return the shift distance in bits if so, or NULL_RTX if the vec_perm is not a
5299 shift_amt_for_vec_perm_mask (rtx sel
)
5301 unsigned int i
, first
, nelt
= GET_MODE_NUNITS (GET_MODE (sel
));
5302 unsigned int bitsize
= GET_MODE_UNIT_BITSIZE (GET_MODE (sel
));
5304 if (GET_CODE (sel
) != CONST_VECTOR
)
5307 first
= INTVAL (CONST_VECTOR_ELT (sel
, 0));
5310 for (i
= 1; i
< nelt
; i
++)
5312 int idx
= INTVAL (CONST_VECTOR_ELT (sel
, i
));
5313 unsigned int expected
= i
+ first
;
5314 /* Indices into the second vector are all equivalent. */
5315 if (idx
< 0 || (MIN (nelt
, (unsigned) idx
) != MIN (nelt
, expected
)))
5319 return GEN_INT (first
* bitsize
);
5322 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
5325 expand_vec_perm_1 (enum insn_code icode
, rtx target
,
5326 rtx v0
, rtx v1
, rtx sel
)
5328 machine_mode tmode
= GET_MODE (target
);
5329 machine_mode smode
= GET_MODE (sel
);
5330 struct expand_operand ops
[4];
5332 create_output_operand (&ops
[0], target
, tmode
);
5333 create_input_operand (&ops
[3], sel
, smode
);
5335 /* Make an effort to preserve v0 == v1. The target expander is able to
5336 rely on this to determine if we're permuting a single input operand. */
5337 if (rtx_equal_p (v0
, v1
))
5339 if (!insn_operand_matches (icode
, 1, v0
))
5340 v0
= force_reg (tmode
, v0
);
5341 gcc_checking_assert (insn_operand_matches (icode
, 1, v0
));
5342 gcc_checking_assert (insn_operand_matches (icode
, 2, v0
));
5344 create_fixed_operand (&ops
[1], v0
);
5345 create_fixed_operand (&ops
[2], v0
);
5349 create_input_operand (&ops
[1], v0
, tmode
);
5350 create_input_operand (&ops
[2], v1
, tmode
);
5353 if (maybe_expand_insn (icode
, 4, ops
))
5354 return ops
[0].value
;
5358 /* Generate instructions for vec_perm optab given its mode
5359 and three operands. */
5362 expand_vec_perm (machine_mode mode
, rtx v0
, rtx v1
, rtx sel
, rtx target
)
5364 enum insn_code icode
;
5365 machine_mode qimode
;
5366 unsigned int i
, w
, e
, u
;
5367 rtx tmp
, sel_qi
= NULL
;
5370 if (!target
|| GET_MODE (target
) != mode
)
5371 target
= gen_reg_rtx (mode
);
5373 w
= GET_MODE_SIZE (mode
);
5374 e
= GET_MODE_NUNITS (mode
);
5375 u
= GET_MODE_UNIT_SIZE (mode
);
5377 /* Set QIMODE to a different vector mode with byte elements.
5378 If no such mode, or if MODE already has byte elements, use VOIDmode. */
5380 if (GET_MODE_INNER (mode
) != QImode
)
5382 qimode
= mode_for_vector (QImode
, w
);
5383 if (!VECTOR_MODE_P (qimode
))
5387 /* If the input is a constant, expand it specially. */
5388 gcc_assert (GET_MODE_CLASS (GET_MODE (sel
)) == MODE_VECTOR_INT
);
5389 if (GET_CODE (sel
) == CONST_VECTOR
)
5391 /* See if this can be handled with a vec_shr. We only do this if the
5392 second vector is all zeroes. */
5393 enum insn_code shift_code
= optab_handler (vec_shr_optab
, mode
);
5394 enum insn_code shift_code_qi
= ((qimode
!= VOIDmode
&& qimode
!= mode
)
5395 ? optab_handler (vec_shr_optab
, qimode
)
5396 : CODE_FOR_nothing
);
5397 rtx shift_amt
= NULL_RTX
;
5398 if (v1
== CONST0_RTX (GET_MODE (v1
))
5399 && (shift_code
!= CODE_FOR_nothing
5400 || shift_code_qi
!= CODE_FOR_nothing
))
5402 shift_amt
= shift_amt_for_vec_perm_mask (sel
);
5405 struct expand_operand ops
[3];
5406 if (shift_code
!= CODE_FOR_nothing
)
5408 create_output_operand (&ops
[0], target
, mode
);
5409 create_input_operand (&ops
[1], v0
, mode
);
5410 create_convert_operand_from_type (&ops
[2], shift_amt
,
5412 if (maybe_expand_insn (shift_code
, 3, ops
))
5413 return ops
[0].value
;
5415 if (shift_code_qi
!= CODE_FOR_nothing
)
5417 tmp
= gen_reg_rtx (qimode
);
5418 create_output_operand (&ops
[0], tmp
, qimode
);
5419 create_input_operand (&ops
[1], gen_lowpart (qimode
, v0
),
5421 create_convert_operand_from_type (&ops
[2], shift_amt
,
5423 if (maybe_expand_insn (shift_code_qi
, 3, ops
))
5424 return gen_lowpart (mode
, ops
[0].value
);
5429 icode
= direct_optab_handler (vec_perm_const_optab
, mode
);
5430 if (icode
!= CODE_FOR_nothing
)
5432 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
5437 /* Fall back to a constant byte-based permutation. */
5438 if (qimode
!= VOIDmode
)
5440 vec
= rtvec_alloc (w
);
5441 for (i
= 0; i
< e
; ++i
)
5443 unsigned int j
, this_e
;
5445 this_e
= INTVAL (CONST_VECTOR_ELT (sel
, i
));
5446 this_e
&= 2 * e
- 1;
5449 for (j
= 0; j
< u
; ++j
)
5450 RTVEC_ELT (vec
, i
* u
+ j
) = GEN_INT (this_e
+ j
);
5452 sel_qi
= gen_rtx_CONST_VECTOR (qimode
, vec
);
5454 icode
= direct_optab_handler (vec_perm_const_optab
, qimode
);
5455 if (icode
!= CODE_FOR_nothing
)
5457 tmp
= mode
!= qimode
? gen_reg_rtx (qimode
) : target
;
5458 tmp
= expand_vec_perm_1 (icode
, tmp
, gen_lowpart (qimode
, v0
),
5459 gen_lowpart (qimode
, v1
), sel_qi
);
5461 return gen_lowpart (mode
, tmp
);
5466 /* Otherwise expand as a fully variable permuation. */
5467 icode
= direct_optab_handler (vec_perm_optab
, mode
);
5468 if (icode
!= CODE_FOR_nothing
)
5470 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
5475 /* As a special case to aid several targets, lower the element-based
5476 permutation to a byte-based permutation and try again. */
5477 if (qimode
== VOIDmode
)
5479 icode
= direct_optab_handler (vec_perm_optab
, qimode
);
5480 if (icode
== CODE_FOR_nothing
)
5485 /* Multiply each element by its byte size. */
5486 machine_mode selmode
= GET_MODE (sel
);
5488 sel
= expand_simple_binop (selmode
, PLUS
, sel
, sel
,
5489 NULL
, 0, OPTAB_DIRECT
);
5491 sel
= expand_simple_binop (selmode
, ASHIFT
, sel
,
5492 GEN_INT (exact_log2 (u
)),
5493 NULL
, 0, OPTAB_DIRECT
);
5494 gcc_assert (sel
!= NULL
);
5496 /* Broadcast the low byte each element into each of its bytes. */
5497 vec
= rtvec_alloc (w
);
5498 for (i
= 0; i
< w
; ++i
)
5500 int this_e
= i
/ u
* u
;
5501 if (BYTES_BIG_ENDIAN
)
5503 RTVEC_ELT (vec
, i
) = GEN_INT (this_e
);
5505 tmp
= gen_rtx_CONST_VECTOR (qimode
, vec
);
5506 sel
= gen_lowpart (qimode
, sel
);
5507 sel
= expand_vec_perm (qimode
, sel
, sel
, tmp
, NULL
);
5508 gcc_assert (sel
!= NULL
);
5510 /* Add the byte offset to each byte element. */
5511 /* Note that the definition of the indicies here is memory ordering,
5512 so there should be no difference between big and little endian. */
5513 vec
= rtvec_alloc (w
);
5514 for (i
= 0; i
< w
; ++i
)
5515 RTVEC_ELT (vec
, i
) = GEN_INT (i
% u
);
5516 tmp
= gen_rtx_CONST_VECTOR (qimode
, vec
);
5517 sel_qi
= expand_simple_binop (qimode
, PLUS
, sel
, tmp
,
5518 sel
, 0, OPTAB_DIRECT
);
5519 gcc_assert (sel_qi
!= NULL
);
5522 tmp
= mode
!= qimode
? gen_reg_rtx (qimode
) : target
;
5523 tmp
= expand_vec_perm_1 (icode
, tmp
, gen_lowpart (qimode
, v0
),
5524 gen_lowpart (qimode
, v1
), sel_qi
);
5526 tmp
= gen_lowpart (mode
, tmp
);
5530 /* Generate insns for a VEC_COND_EXPR with mask, given its TYPE and its
5534 expand_vec_cond_mask_expr (tree vec_cond_type
, tree op0
, tree op1
, tree op2
,
5537 struct expand_operand ops
[4];
5538 machine_mode mode
= TYPE_MODE (vec_cond_type
);
5539 machine_mode mask_mode
= TYPE_MODE (TREE_TYPE (op0
));
5540 enum insn_code icode
= get_vcond_mask_icode (mode
, mask_mode
);
5541 rtx mask
, rtx_op1
, rtx_op2
;
5543 if (icode
== CODE_FOR_nothing
)
5546 mask
= expand_normal (op0
);
5547 rtx_op1
= expand_normal (op1
);
5548 rtx_op2
= expand_normal (op2
);
5550 mask
= force_reg (GET_MODE (mask
), mask
);
5551 rtx_op1
= force_reg (GET_MODE (rtx_op1
), rtx_op1
);
5553 create_output_operand (&ops
[0], target
, mode
);
5554 create_input_operand (&ops
[1], rtx_op1
, mode
);
5555 create_input_operand (&ops
[2], rtx_op2
, mode
);
5556 create_input_operand (&ops
[3], mask
, mask_mode
);
5557 expand_insn (icode
, 4, ops
);
5559 return ops
[0].value
;
5562 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
5566 expand_vec_cond_expr (tree vec_cond_type
, tree op0
, tree op1
, tree op2
,
5569 struct expand_operand ops
[6];
5570 enum insn_code icode
;
5571 rtx comparison
, rtx_op1
, rtx_op2
;
5572 machine_mode mode
= TYPE_MODE (vec_cond_type
);
5573 machine_mode cmp_op_mode
;
5576 enum tree_code tcode
;
5578 if (COMPARISON_CLASS_P (op0
))
5580 op0a
= TREE_OPERAND (op0
, 0);
5581 op0b
= TREE_OPERAND (op0
, 1);
5582 tcode
= TREE_CODE (op0
);
5586 gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0
)));
5587 if (get_vcond_mask_icode (mode
, TYPE_MODE (TREE_TYPE (op0
)))
5588 != CODE_FOR_nothing
)
5589 return expand_vec_cond_mask_expr (vec_cond_type
, op0
, op1
,
5594 gcc_assert (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (op0
)))
5595 == MODE_VECTOR_INT
);
5597 op0b
= build_zero_cst (TREE_TYPE (op0
));
5601 cmp_op_mode
= TYPE_MODE (TREE_TYPE (op0a
));
5602 unsignedp
= TYPE_UNSIGNED (TREE_TYPE (op0a
));
5605 gcc_assert (GET_MODE_SIZE (mode
) == GET_MODE_SIZE (cmp_op_mode
)
5606 && GET_MODE_NUNITS (mode
) == GET_MODE_NUNITS (cmp_op_mode
));
5608 icode
= get_vcond_icode (mode
, cmp_op_mode
, unsignedp
);
5609 if (icode
== CODE_FOR_nothing
)
5612 comparison
= vector_compare_rtx (tcode
, op0a
, op0b
, unsignedp
, icode
, 4);
5613 rtx_op1
= expand_normal (op1
);
5614 rtx_op2
= expand_normal (op2
);
5616 create_output_operand (&ops
[0], target
, mode
);
5617 create_input_operand (&ops
[1], rtx_op1
, mode
);
5618 create_input_operand (&ops
[2], rtx_op2
, mode
);
5619 create_fixed_operand (&ops
[3], comparison
);
5620 create_fixed_operand (&ops
[4], XEXP (comparison
, 0));
5621 create_fixed_operand (&ops
[5], XEXP (comparison
, 1));
5622 expand_insn (icode
, 6, ops
);
5623 return ops
[0].value
;
5626 /* Generate insns for a vector comparison into a mask. */
5629 expand_vec_cmp_expr (tree type
, tree exp
, rtx target
)
5631 struct expand_operand ops
[4];
5632 enum insn_code icode
;
5634 machine_mode mask_mode
= TYPE_MODE (type
);
5638 enum tree_code tcode
;
5640 op0a
= TREE_OPERAND (exp
, 0);
5641 op0b
= TREE_OPERAND (exp
, 1);
5642 tcode
= TREE_CODE (exp
);
5644 unsignedp
= TYPE_UNSIGNED (TREE_TYPE (op0a
));
5645 vmode
= TYPE_MODE (TREE_TYPE (op0a
));
5647 icode
= get_vec_cmp_icode (vmode
, mask_mode
, unsignedp
);
5648 if (icode
== CODE_FOR_nothing
)
5651 comparison
= vector_compare_rtx (tcode
, op0a
, op0b
, unsignedp
, icode
, 2);
5652 create_output_operand (&ops
[0], target
, mask_mode
);
5653 create_fixed_operand (&ops
[1], comparison
);
5654 create_fixed_operand (&ops
[2], XEXP (comparison
, 0));
5655 create_fixed_operand (&ops
[3], XEXP (comparison
, 1));
5656 expand_insn (icode
, 4, ops
);
5657 return ops
[0].value
;
5660 /* Expand a highpart multiply. */
5663 expand_mult_highpart (machine_mode mode
, rtx op0
, rtx op1
,
5664 rtx target
, bool uns_p
)
5666 struct expand_operand eops
[3];
5667 enum insn_code icode
;
5668 int method
, i
, nunits
;
5674 method
= can_mult_highpart_p (mode
, uns_p
);
5680 tab1
= uns_p
? umul_highpart_optab
: smul_highpart_optab
;
5681 return expand_binop (mode
, tab1
, op0
, op1
, target
, uns_p
,
5684 tab1
= uns_p
? vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
5685 tab2
= uns_p
? vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
5688 tab1
= uns_p
? vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
5689 tab2
= uns_p
? vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
5690 if (BYTES_BIG_ENDIAN
)
5691 std::swap (tab1
, tab2
);
5697 icode
= optab_handler (tab1
, mode
);
5698 nunits
= GET_MODE_NUNITS (mode
);
5699 wmode
= insn_data
[icode
].operand
[0].mode
;
5700 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode
) == nunits
);
5701 gcc_checking_assert (GET_MODE_SIZE (wmode
) == GET_MODE_SIZE (mode
));
5703 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
5704 create_input_operand (&eops
[1], op0
, mode
);
5705 create_input_operand (&eops
[2], op1
, mode
);
5706 expand_insn (icode
, 3, eops
);
5707 m1
= gen_lowpart (mode
, eops
[0].value
);
5709 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
5710 create_input_operand (&eops
[1], op0
, mode
);
5711 create_input_operand (&eops
[2], op1
, mode
);
5712 expand_insn (optab_handler (tab2
, mode
), 3, eops
);
5713 m2
= gen_lowpart (mode
, eops
[0].value
);
5715 v
= rtvec_alloc (nunits
);
5718 for (i
= 0; i
< nunits
; ++i
)
5719 RTVEC_ELT (v
, i
) = GEN_INT (!BYTES_BIG_ENDIAN
+ (i
& ~1)
5720 + ((i
& 1) ? nunits
: 0));
5724 for (i
= 0; i
< nunits
; ++i
)
5725 RTVEC_ELT (v
, i
) = GEN_INT (2 * i
+ (BYTES_BIG_ENDIAN
? 0 : 1));
5727 perm
= gen_rtx_CONST_VECTOR (mode
, v
);
5729 return expand_vec_perm (mode
, m1
, m2
, perm
, target
);
5732 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
5736 find_cc_set (rtx x
, const_rtx pat
, void *data
)
5738 if (REG_P (x
) && GET_MODE_CLASS (GET_MODE (x
)) == MODE_CC
5739 && GET_CODE (pat
) == SET
)
5741 rtx
*p_cc_reg
= (rtx
*) data
;
5742 gcc_assert (!*p_cc_reg
);
5747 /* This is a helper function for the other atomic operations. This function
5748 emits a loop that contains SEQ that iterates until a compare-and-swap
5749 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5750 a set of instructions that takes a value from OLD_REG as an input and
5751 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5752 set to the current contents of MEM. After SEQ, a compare-and-swap will
5753 attempt to update MEM with NEW_REG. The function returns true when the
5754 loop was generated successfully. */
5757 expand_compare_and_swap_loop (rtx mem
, rtx old_reg
, rtx new_reg
, rtx seq
)
5759 machine_mode mode
= GET_MODE (mem
);
5760 rtx_code_label
*label
;
5761 rtx cmp_reg
, success
, oldval
;
5763 /* The loop we want to generate looks like
5769 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
5773 Note that we only do the plain load from memory once. Subsequent
5774 iterations use the value loaded by the compare-and-swap pattern. */
5776 label
= gen_label_rtx ();
5777 cmp_reg
= gen_reg_rtx (mode
);
5779 emit_move_insn (cmp_reg
, mem
);
5781 emit_move_insn (old_reg
, cmp_reg
);
5787 if (!expand_atomic_compare_and_swap (&success
, &oldval
, mem
, old_reg
,
5788 new_reg
, false, MEMMODEL_SYNC_SEQ_CST
,
5792 if (oldval
!= cmp_reg
)
5793 emit_move_insn (cmp_reg
, oldval
);
5795 /* Mark this jump predicted not taken. */
5796 emit_cmp_and_jump_insns (success
, const0_rtx
, EQ
, const0_rtx
,
5797 GET_MODE (success
), 1, label
, 0);
5802 /* This function tries to emit an atomic_exchange intruction. VAL is written
5803 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
5804 using TARGET if possible. */
5807 maybe_emit_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
5809 machine_mode mode
= GET_MODE (mem
);
5810 enum insn_code icode
;
5812 /* If the target supports the exchange directly, great. */
5813 icode
= direct_optab_handler (atomic_exchange_optab
, mode
);
5814 if (icode
!= CODE_FOR_nothing
)
5816 struct expand_operand ops
[4];
5818 create_output_operand (&ops
[0], target
, mode
);
5819 create_fixed_operand (&ops
[1], mem
);
5820 create_input_operand (&ops
[2], val
, mode
);
5821 create_integer_operand (&ops
[3], model
);
5822 if (maybe_expand_insn (icode
, 4, ops
))
5823 return ops
[0].value
;
5829 /* This function tries to implement an atomic exchange operation using
5830 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
5831 The previous contents of *MEM are returned, using TARGET if possible.
5832 Since this instructionn is an acquire barrier only, stronger memory
5833 models may require additional barriers to be emitted. */
5836 maybe_emit_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
,
5837 enum memmodel model
)
5839 machine_mode mode
= GET_MODE (mem
);
5840 enum insn_code icode
;
5841 rtx_insn
*last_insn
= get_last_insn ();
5843 icode
= optab_handler (sync_lock_test_and_set_optab
, mode
);
5845 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
5846 exists, and the memory model is stronger than acquire, add a release
5847 barrier before the instruction. */
5849 if (is_mm_seq_cst (model
) || is_mm_release (model
) || is_mm_acq_rel (model
))
5850 expand_mem_thread_fence (model
);
5852 if (icode
!= CODE_FOR_nothing
)
5854 struct expand_operand ops
[3];
5855 create_output_operand (&ops
[0], target
, mode
);
5856 create_fixed_operand (&ops
[1], mem
);
5857 create_input_operand (&ops
[2], val
, mode
);
5858 if (maybe_expand_insn (icode
, 3, ops
))
5859 return ops
[0].value
;
5862 /* If an external test-and-set libcall is provided, use that instead of
5863 any external compare-and-swap that we might get from the compare-and-
5864 swap-loop expansion later. */
5865 if (!can_compare_and_swap_p (mode
, false))
5867 rtx libfunc
= optab_libfunc (sync_lock_test_and_set_optab
, mode
);
5868 if (libfunc
!= NULL
)
5872 addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
5873 return emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
5874 mode
, 2, addr
, ptr_mode
,
5879 /* If the test_and_set can't be emitted, eliminate any barrier that might
5880 have been emitted. */
5881 delete_insns_since (last_insn
);
5885 /* This function tries to implement an atomic exchange operation using a
5886 compare_and_swap loop. VAL is written to *MEM. The previous contents of
5887 *MEM are returned, using TARGET if possible. No memory model is required
5888 since a compare_and_swap loop is seq-cst. */
5891 maybe_emit_compare_and_swap_exchange_loop (rtx target
, rtx mem
, rtx val
)
5893 machine_mode mode
= GET_MODE (mem
);
5895 if (can_compare_and_swap_p (mode
, true))
5897 if (!target
|| !register_operand (target
, mode
))
5898 target
= gen_reg_rtx (mode
);
5899 if (expand_compare_and_swap_loop (mem
, target
, val
, NULL_RTX
))
5906 /* This function tries to implement an atomic test-and-set operation
5907 using the atomic_test_and_set instruction pattern. A boolean value
5908 is returned from the operation, using TARGET if possible. */
5911 maybe_emit_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
5913 machine_mode pat_bool_mode
;
5914 struct expand_operand ops
[3];
5916 if (!targetm
.have_atomic_test_and_set ())
5919 /* While we always get QImode from __atomic_test_and_set, we get
5920 other memory modes from __sync_lock_test_and_set. Note that we
5921 use no endian adjustment here. This matches the 4.6 behavior
5922 in the Sparc backend. */
5923 enum insn_code icode
= targetm
.code_for_atomic_test_and_set
;
5924 gcc_checking_assert (insn_data
[icode
].operand
[1].mode
== QImode
);
5925 if (GET_MODE (mem
) != QImode
)
5926 mem
= adjust_address_nv (mem
, QImode
, 0);
5928 pat_bool_mode
= insn_data
[icode
].operand
[0].mode
;
5929 create_output_operand (&ops
[0], target
, pat_bool_mode
);
5930 create_fixed_operand (&ops
[1], mem
);
5931 create_integer_operand (&ops
[2], model
);
5933 if (maybe_expand_insn (icode
, 3, ops
))
5934 return ops
[0].value
;
5938 /* This function expands the legacy _sync_lock test_and_set operation which is
5939 generally an atomic exchange. Some limited targets only allow the
5940 constant 1 to be stored. This is an ACQUIRE operation.
5942 TARGET is an optional place to stick the return value.
5943 MEM is where VAL is stored. */
5946 expand_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
)
5950 /* Try an atomic_exchange first. */
5951 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, MEMMODEL_SYNC_ACQUIRE
);
5955 ret
= maybe_emit_sync_lock_test_and_set (target
, mem
, val
,
5956 MEMMODEL_SYNC_ACQUIRE
);
5960 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
5964 /* If there are no other options, try atomic_test_and_set if the value
5965 being stored is 1. */
5966 if (val
== const1_rtx
)
5967 ret
= maybe_emit_atomic_test_and_set (target
, mem
, MEMMODEL_SYNC_ACQUIRE
);
5972 /* This function expands the atomic test_and_set operation:
5973 atomically store a boolean TRUE into MEM and return the previous value.
5975 MEMMODEL is the memory model variant to use.
5976 TARGET is an optional place to stick the return value. */
5979 expand_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
5981 machine_mode mode
= GET_MODE (mem
);
5982 rtx ret
, trueval
, subtarget
;
5984 ret
= maybe_emit_atomic_test_and_set (target
, mem
, model
);
5988 /* Be binary compatible with non-default settings of trueval, and different
5989 cpu revisions. E.g. one revision may have atomic-test-and-set, but
5990 another only has atomic-exchange. */
5991 if (targetm
.atomic_test_and_set_trueval
== 1)
5993 trueval
= const1_rtx
;
5994 subtarget
= target
? target
: gen_reg_rtx (mode
);
5998 trueval
= gen_int_mode (targetm
.atomic_test_and_set_trueval
, mode
);
5999 subtarget
= gen_reg_rtx (mode
);
6002 /* Try the atomic-exchange optab... */
6003 ret
= maybe_emit_atomic_exchange (subtarget
, mem
, trueval
, model
);
6005 /* ... then an atomic-compare-and-swap loop ... */
6007 ret
= maybe_emit_compare_and_swap_exchange_loop (subtarget
, mem
, trueval
);
6009 /* ... before trying the vaguely defined legacy lock_test_and_set. */
6011 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, trueval
, model
);
6013 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
6014 things with the value 1. Thus we try again without trueval. */
6015 if (!ret
&& targetm
.atomic_test_and_set_trueval
!= 1)
6016 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, const1_rtx
, model
);
6018 /* Failing all else, assume a single threaded environment and simply
6019 perform the operation. */
6022 /* If the result is ignored skip the move to target. */
6023 if (subtarget
!= const0_rtx
)
6024 emit_move_insn (subtarget
, mem
);
6026 emit_move_insn (mem
, trueval
);
6030 /* Recall that have to return a boolean value; rectify if trueval
6031 is not exactly one. */
6032 if (targetm
.atomic_test_and_set_trueval
!= 1)
6033 ret
= emit_store_flag_force (target
, NE
, ret
, const0_rtx
, mode
, 0, 1);
6038 /* This function expands the atomic exchange operation:
6039 atomically store VAL in MEM and return the previous value in MEM.
6041 MEMMODEL is the memory model variant to use.
6042 TARGET is an optional place to stick the return value. */
6045 expand_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
6049 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, model
);
6051 /* Next try a compare-and-swap loop for the exchange. */
6053 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
6058 /* This function expands the atomic compare exchange operation:
6060 *PTARGET_BOOL is an optional place to store the boolean success/failure.
6061 *PTARGET_OVAL is an optional place to store the old value from memory.
6062 Both target parameters may be NULL or const0_rtx to indicate that we do
6063 not care about that return value. Both target parameters are updated on
6064 success to the actual location of the corresponding result.
6066 MEMMODEL is the memory model variant to use.
6068 The return value of the function is true for success. */
6071 expand_atomic_compare_and_swap (rtx
*ptarget_bool
, rtx
*ptarget_oval
,
6072 rtx mem
, rtx expected
, rtx desired
,
6073 bool is_weak
, enum memmodel succ_model
,
6074 enum memmodel fail_model
)
6076 machine_mode mode
= GET_MODE (mem
);
6077 struct expand_operand ops
[8];
6078 enum insn_code icode
;
6079 rtx target_oval
, target_bool
= NULL_RTX
;
6082 /* Load expected into a register for the compare and swap. */
6083 if (MEM_P (expected
))
6084 expected
= copy_to_reg (expected
);
6086 /* Make sure we always have some place to put the return oldval.
6087 Further, make sure that place is distinct from the input expected,
6088 just in case we need that path down below. */
6089 if (ptarget_oval
&& *ptarget_oval
== const0_rtx
)
6090 ptarget_oval
= NULL
;
6092 if (ptarget_oval
== NULL
6093 || (target_oval
= *ptarget_oval
) == NULL
6094 || reg_overlap_mentioned_p (expected
, target_oval
))
6095 target_oval
= gen_reg_rtx (mode
);
6097 icode
= direct_optab_handler (atomic_compare_and_swap_optab
, mode
);
6098 if (icode
!= CODE_FOR_nothing
)
6100 machine_mode bool_mode
= insn_data
[icode
].operand
[0].mode
;
6102 if (ptarget_bool
&& *ptarget_bool
== const0_rtx
)
6103 ptarget_bool
= NULL
;
6105 /* Make sure we always have a place for the bool operand. */
6106 if (ptarget_bool
== NULL
6107 || (target_bool
= *ptarget_bool
) == NULL
6108 || GET_MODE (target_bool
) != bool_mode
)
6109 target_bool
= gen_reg_rtx (bool_mode
);
6111 /* Emit the compare_and_swap. */
6112 create_output_operand (&ops
[0], target_bool
, bool_mode
);
6113 create_output_operand (&ops
[1], target_oval
, mode
);
6114 create_fixed_operand (&ops
[2], mem
);
6115 create_input_operand (&ops
[3], expected
, mode
);
6116 create_input_operand (&ops
[4], desired
, mode
);
6117 create_integer_operand (&ops
[5], is_weak
);
6118 create_integer_operand (&ops
[6], succ_model
);
6119 create_integer_operand (&ops
[7], fail_model
);
6120 if (maybe_expand_insn (icode
, 8, ops
))
6122 /* Return success/failure. */
6123 target_bool
= ops
[0].value
;
6124 target_oval
= ops
[1].value
;
6129 /* Otherwise fall back to the original __sync_val_compare_and_swap
6130 which is always seq-cst. */
6131 icode
= optab_handler (sync_compare_and_swap_optab
, mode
);
6132 if (icode
!= CODE_FOR_nothing
)
6136 create_output_operand (&ops
[0], target_oval
, mode
);
6137 create_fixed_operand (&ops
[1], mem
);
6138 create_input_operand (&ops
[2], expected
, mode
);
6139 create_input_operand (&ops
[3], desired
, mode
);
6140 if (!maybe_expand_insn (icode
, 4, ops
))
6143 target_oval
= ops
[0].value
;
6145 /* If the caller isn't interested in the boolean return value,
6146 skip the computation of it. */
6147 if (ptarget_bool
== NULL
)
6150 /* Otherwise, work out if the compare-and-swap succeeded. */
6152 if (have_insn_for (COMPARE
, CCmode
))
6153 note_stores (PATTERN (get_last_insn ()), find_cc_set
, &cc_reg
);
6156 target_bool
= emit_store_flag_force (target_bool
, EQ
, cc_reg
,
6157 const0_rtx
, VOIDmode
, 0, 1);
6160 goto success_bool_from_val
;
6163 /* Also check for library support for __sync_val_compare_and_swap. */
6164 libfunc
= optab_libfunc (sync_compare_and_swap_optab
, mode
);
6165 if (libfunc
!= NULL
)
6167 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
6168 rtx target
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
6169 mode
, 3, addr
, ptr_mode
,
6170 expected
, mode
, desired
, mode
);
6171 emit_move_insn (target_oval
, target
);
6173 /* Compute the boolean return value only if requested. */
6175 goto success_bool_from_val
;
6183 success_bool_from_val
:
6184 target_bool
= emit_store_flag_force (target_bool
, EQ
, target_oval
,
6185 expected
, VOIDmode
, 1, 1);
6187 /* Make sure that the oval output winds up where the caller asked. */
6189 *ptarget_oval
= target_oval
;
6191 *ptarget_bool
= target_bool
;
6195 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
6198 expand_asm_memory_barrier (void)
6202 asm_op
= gen_rtx_ASM_OPERANDS (VOIDmode
, empty_string
, empty_string
, 0,
6203 rtvec_alloc (0), rtvec_alloc (0),
6204 rtvec_alloc (0), UNKNOWN_LOCATION
);
6205 MEM_VOLATILE_P (asm_op
) = 1;
6207 clob
= gen_rtx_SCRATCH (VOIDmode
);
6208 clob
= gen_rtx_MEM (BLKmode
, clob
);
6209 clob
= gen_rtx_CLOBBER (VOIDmode
, clob
);
6211 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, asm_op
, clob
)));
6214 /* This routine will either emit the mem_thread_fence pattern or issue a
6215 sync_synchronize to generate a fence for memory model MEMMODEL. */
6218 expand_mem_thread_fence (enum memmodel model
)
6220 if (targetm
.have_mem_thread_fence ())
6221 emit_insn (targetm
.gen_mem_thread_fence (GEN_INT (model
)));
6222 else if (!is_mm_relaxed (model
))
6224 if (targetm
.have_memory_barrier ())
6225 emit_insn (targetm
.gen_memory_barrier ());
6226 else if (synchronize_libfunc
!= NULL_RTX
)
6227 emit_library_call (synchronize_libfunc
, LCT_NORMAL
, VOIDmode
, 0);
6229 expand_asm_memory_barrier ();
6233 /* This routine will either emit the mem_signal_fence pattern or issue a
6234 sync_synchronize to generate a fence for memory model MEMMODEL. */
6237 expand_mem_signal_fence (enum memmodel model
)
6239 if (targetm
.have_mem_signal_fence ())
6240 emit_insn (targetm
.gen_mem_signal_fence (GEN_INT (model
)));
6241 else if (!is_mm_relaxed (model
))
6243 /* By default targets are coherent between a thread and the signal
6244 handler running on the same thread. Thus this really becomes a
6245 compiler barrier, in that stores must not be sunk past
6246 (or raised above) a given point. */
6247 expand_asm_memory_barrier ();
6251 /* This function expands the atomic load operation:
6252 return the atomically loaded value in MEM.
6254 MEMMODEL is the memory model variant to use.
6255 TARGET is an option place to stick the return value. */
6258 expand_atomic_load (rtx target
, rtx mem
, enum memmodel model
)
6260 machine_mode mode
= GET_MODE (mem
);
6261 enum insn_code icode
;
6263 /* If the target supports the load directly, great. */
6264 icode
= direct_optab_handler (atomic_load_optab
, mode
);
6265 if (icode
!= CODE_FOR_nothing
)
6267 struct expand_operand ops
[3];
6269 create_output_operand (&ops
[0], target
, mode
);
6270 create_fixed_operand (&ops
[1], mem
);
6271 create_integer_operand (&ops
[2], model
);
6272 if (maybe_expand_insn (icode
, 3, ops
))
6273 return ops
[0].value
;
6276 /* If the size of the object is greater than word size on this target,
6277 then we assume that a load will not be atomic. */
6278 if (GET_MODE_PRECISION (mode
) > BITS_PER_WORD
)
6280 /* Issue val = compare_and_swap (mem, 0, 0).
6281 This may cause the occasional harmless store of 0 when the value is
6282 already 0, but it seems to be OK according to the standards guys. */
6283 if (expand_atomic_compare_and_swap (NULL
, &target
, mem
, const0_rtx
,
6284 const0_rtx
, false, model
, model
))
6287 /* Otherwise there is no atomic load, leave the library call. */
6291 /* Otherwise assume loads are atomic, and emit the proper barriers. */
6292 if (!target
|| target
== const0_rtx
)
6293 target
= gen_reg_rtx (mode
);
6295 /* For SEQ_CST, emit a barrier before the load. */
6296 if (is_mm_seq_cst (model
))
6297 expand_mem_thread_fence (model
);
6299 emit_move_insn (target
, mem
);
6301 /* Emit the appropriate barrier after the load. */
6302 expand_mem_thread_fence (model
);
6307 /* This function expands the atomic store operation:
6308 Atomically store VAL in MEM.
6309 MEMMODEL is the memory model variant to use.
6310 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
6311 function returns const0_rtx if a pattern was emitted. */
6314 expand_atomic_store (rtx mem
, rtx val
, enum memmodel model
, bool use_release
)
6316 machine_mode mode
= GET_MODE (mem
);
6317 enum insn_code icode
;
6318 struct expand_operand ops
[3];
6320 /* If the target supports the store directly, great. */
6321 icode
= direct_optab_handler (atomic_store_optab
, mode
);
6322 if (icode
!= CODE_FOR_nothing
)
6324 create_fixed_operand (&ops
[0], mem
);
6325 create_input_operand (&ops
[1], val
, mode
);
6326 create_integer_operand (&ops
[2], model
);
6327 if (maybe_expand_insn (icode
, 3, ops
))
6331 /* If using __sync_lock_release is a viable alternative, try it. */
6334 icode
= direct_optab_handler (sync_lock_release_optab
, mode
);
6335 if (icode
!= CODE_FOR_nothing
)
6337 create_fixed_operand (&ops
[0], mem
);
6338 create_input_operand (&ops
[1], const0_rtx
, mode
);
6339 if (maybe_expand_insn (icode
, 2, ops
))
6341 /* lock_release is only a release barrier. */
6342 if (is_mm_seq_cst (model
))
6343 expand_mem_thread_fence (model
);
6349 /* If the size of the object is greater than word size on this target,
6350 a default store will not be atomic, Try a mem_exchange and throw away
6351 the result. If that doesn't work, don't do anything. */
6352 if (GET_MODE_PRECISION (mode
) > BITS_PER_WORD
)
6354 rtx target
= maybe_emit_atomic_exchange (NULL_RTX
, mem
, val
, model
);
6356 target
= maybe_emit_compare_and_swap_exchange_loop (NULL_RTX
, mem
, val
);
6363 /* Otherwise assume stores are atomic, and emit the proper barriers. */
6364 expand_mem_thread_fence (model
);
6366 emit_move_insn (mem
, val
);
6368 /* For SEQ_CST, also emit a barrier after the store. */
6369 if (is_mm_seq_cst (model
))
6370 expand_mem_thread_fence (model
);
6376 /* Structure containing the pointers and values required to process the
6377 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
6379 struct atomic_op_functions
6381 direct_optab mem_fetch_before
;
6382 direct_optab mem_fetch_after
;
6383 direct_optab mem_no_result
;
6386 direct_optab no_result
;
6387 enum rtx_code reverse_code
;
6391 /* Fill in structure pointed to by OP with the various optab entries for an
6392 operation of type CODE. */
6395 get_atomic_op_for_code (struct atomic_op_functions
*op
, enum rtx_code code
)
6397 gcc_assert (op
!= NULL
);
6399 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
6400 in the source code during compilation, and the optab entries are not
6401 computable until runtime. Fill in the values at runtime. */
6405 op
->mem_fetch_before
= atomic_fetch_add_optab
;
6406 op
->mem_fetch_after
= atomic_add_fetch_optab
;
6407 op
->mem_no_result
= atomic_add_optab
;
6408 op
->fetch_before
= sync_old_add_optab
;
6409 op
->fetch_after
= sync_new_add_optab
;
6410 op
->no_result
= sync_add_optab
;
6411 op
->reverse_code
= MINUS
;
6414 op
->mem_fetch_before
= atomic_fetch_sub_optab
;
6415 op
->mem_fetch_after
= atomic_sub_fetch_optab
;
6416 op
->mem_no_result
= atomic_sub_optab
;
6417 op
->fetch_before
= sync_old_sub_optab
;
6418 op
->fetch_after
= sync_new_sub_optab
;
6419 op
->no_result
= sync_sub_optab
;
6420 op
->reverse_code
= PLUS
;
6423 op
->mem_fetch_before
= atomic_fetch_xor_optab
;
6424 op
->mem_fetch_after
= atomic_xor_fetch_optab
;
6425 op
->mem_no_result
= atomic_xor_optab
;
6426 op
->fetch_before
= sync_old_xor_optab
;
6427 op
->fetch_after
= sync_new_xor_optab
;
6428 op
->no_result
= sync_xor_optab
;
6429 op
->reverse_code
= XOR
;
6432 op
->mem_fetch_before
= atomic_fetch_and_optab
;
6433 op
->mem_fetch_after
= atomic_and_fetch_optab
;
6434 op
->mem_no_result
= atomic_and_optab
;
6435 op
->fetch_before
= sync_old_and_optab
;
6436 op
->fetch_after
= sync_new_and_optab
;
6437 op
->no_result
= sync_and_optab
;
6438 op
->reverse_code
= UNKNOWN
;
6441 op
->mem_fetch_before
= atomic_fetch_or_optab
;
6442 op
->mem_fetch_after
= atomic_or_fetch_optab
;
6443 op
->mem_no_result
= atomic_or_optab
;
6444 op
->fetch_before
= sync_old_ior_optab
;
6445 op
->fetch_after
= sync_new_ior_optab
;
6446 op
->no_result
= sync_ior_optab
;
6447 op
->reverse_code
= UNKNOWN
;
6450 op
->mem_fetch_before
= atomic_fetch_nand_optab
;
6451 op
->mem_fetch_after
= atomic_nand_fetch_optab
;
6452 op
->mem_no_result
= atomic_nand_optab
;
6453 op
->fetch_before
= sync_old_nand_optab
;
6454 op
->fetch_after
= sync_new_nand_optab
;
6455 op
->no_result
= sync_nand_optab
;
6456 op
->reverse_code
= UNKNOWN
;
6463 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
6464 using memory order MODEL. If AFTER is true the operation needs to return
6465 the value of *MEM after the operation, otherwise the previous value.
6466 TARGET is an optional place to place the result. The result is unused if
6468 Return the result if there is a better sequence, otherwise NULL_RTX. */
6471 maybe_optimize_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
6472 enum memmodel model
, bool after
)
6474 /* If the value is prefetched, or not used, it may be possible to replace
6475 the sequence with a native exchange operation. */
6476 if (!after
|| target
== const0_rtx
)
6478 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
6479 if (code
== AND
&& val
== const0_rtx
)
6481 if (target
== const0_rtx
)
6482 target
= gen_reg_rtx (GET_MODE (mem
));
6483 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
6486 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
6487 if (code
== IOR
&& val
== constm1_rtx
)
6489 if (target
== const0_rtx
)
6490 target
= gen_reg_rtx (GET_MODE (mem
));
6491 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
6498 /* Try to emit an instruction for a specific operation varaition.
6499 OPTAB contains the OP functions.
6500 TARGET is an optional place to return the result. const0_rtx means unused.
6501 MEM is the memory location to operate on.
6502 VAL is the value to use in the operation.
6503 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
6504 MODEL is the memory model, if used.
6505 AFTER is true if the returned result is the value after the operation. */
6508 maybe_emit_op (const struct atomic_op_functions
*optab
, rtx target
, rtx mem
,
6509 rtx val
, bool use_memmodel
, enum memmodel model
, bool after
)
6511 machine_mode mode
= GET_MODE (mem
);
6512 struct expand_operand ops
[4];
6513 enum insn_code icode
;
6517 /* Check to see if there is a result returned. */
6518 if (target
== const0_rtx
)
6522 icode
= direct_optab_handler (optab
->mem_no_result
, mode
);
6523 create_integer_operand (&ops
[2], model
);
6528 icode
= direct_optab_handler (optab
->no_result
, mode
);
6532 /* Otherwise, we need to generate a result. */
6537 icode
= direct_optab_handler (after
? optab
->mem_fetch_after
6538 : optab
->mem_fetch_before
, mode
);
6539 create_integer_operand (&ops
[3], model
);
6544 icode
= optab_handler (after
? optab
->fetch_after
6545 : optab
->fetch_before
, mode
);
6548 create_output_operand (&ops
[op_counter
++], target
, mode
);
6550 if (icode
== CODE_FOR_nothing
)
6553 create_fixed_operand (&ops
[op_counter
++], mem
);
6554 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6555 create_convert_operand_to (&ops
[op_counter
++], val
, mode
, true);
6557 if (maybe_expand_insn (icode
, num_ops
, ops
))
6558 return (target
== const0_rtx
? const0_rtx
: ops
[0].value
);
6564 /* This function expands an atomic fetch_OP or OP_fetch operation:
6565 TARGET is an option place to stick the return value. const0_rtx indicates
6566 the result is unused.
6567 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6568 CODE is the operation being performed (OP)
6569 MEMMODEL is the memory model variant to use.
6570 AFTER is true to return the result of the operation (OP_fetch).
6571 AFTER is false to return the value before the operation (fetch_OP).
6573 This function will *only* generate instructions if there is a direct
6574 optab. No compare and swap loops or libcalls will be generated. */
6577 expand_atomic_fetch_op_no_fallback (rtx target
, rtx mem
, rtx val
,
6578 enum rtx_code code
, enum memmodel model
,
6581 machine_mode mode
= GET_MODE (mem
);
6582 struct atomic_op_functions optab
;
6584 bool unused_result
= (target
== const0_rtx
);
6586 get_atomic_op_for_code (&optab
, code
);
6588 /* Check to see if there are any better instructions. */
6589 result
= maybe_optimize_fetch_op (target
, mem
, val
, code
, model
, after
);
6593 /* Check for the case where the result isn't used and try those patterns. */
6596 /* Try the memory model variant first. */
6597 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, true);
6601 /* Next try the old style withuot a memory model. */
6602 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, true);
6606 /* There is no no-result pattern, so try patterns with a result. */
6610 /* Try the __atomic version. */
6611 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, after
);
6615 /* Try the older __sync version. */
6616 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, after
);
6620 /* If the fetch value can be calculated from the other variation of fetch,
6621 try that operation. */
6622 if (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
)
6624 /* Try the __atomic version, then the older __sync version. */
6625 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, !after
);
6627 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, !after
);
6631 /* If the result isn't used, no need to do compensation code. */
6635 /* Issue compensation code. Fetch_after == fetch_before OP val.
6636 Fetch_before == after REVERSE_OP val. */
6638 code
= optab
.reverse_code
;
6641 result
= expand_simple_binop (mode
, AND
, result
, val
, NULL_RTX
,
6642 true, OPTAB_LIB_WIDEN
);
6643 result
= expand_simple_unop (mode
, NOT
, result
, target
, true);
6646 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
6647 true, OPTAB_LIB_WIDEN
);
6652 /* No direct opcode can be generated. */
6658 /* This function expands an atomic fetch_OP or OP_fetch operation:
6659 TARGET is an option place to stick the return value. const0_rtx indicates
6660 the result is unused.
6661 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6662 CODE is the operation being performed (OP)
6663 MEMMODEL is the memory model variant to use.
6664 AFTER is true to return the result of the operation (OP_fetch).
6665 AFTER is false to return the value before the operation (fetch_OP). */
6667 expand_atomic_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
6668 enum memmodel model
, bool after
)
6670 machine_mode mode
= GET_MODE (mem
);
6672 bool unused_result
= (target
== const0_rtx
);
6674 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, val
, code
, model
,
6680 /* Add/sub can be implemented by doing the reverse operation with -(val). */
6681 if (code
== PLUS
|| code
== MINUS
)
6684 enum rtx_code reverse
= (code
== PLUS
? MINUS
: PLUS
);
6687 tmp
= expand_simple_unop (mode
, NEG
, val
, NULL_RTX
, true);
6688 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, tmp
, reverse
,
6692 /* PLUS worked so emit the insns and return. */
6699 /* PLUS did not work, so throw away the negation code and continue. */
6703 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
6704 if (!can_compare_and_swap_p (mode
, false))
6708 enum rtx_code orig_code
= code
;
6709 struct atomic_op_functions optab
;
6711 get_atomic_op_for_code (&optab
, code
);
6712 libfunc
= optab_libfunc (after
? optab
.fetch_after
6713 : optab
.fetch_before
, mode
);
6715 && (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
))
6719 code
= optab
.reverse_code
;
6720 libfunc
= optab_libfunc (after
? optab
.fetch_before
6721 : optab
.fetch_after
, mode
);
6723 if (libfunc
!= NULL
)
6725 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
6726 result
= emit_library_call_value (libfunc
, NULL
, LCT_NORMAL
, mode
,
6727 2, addr
, ptr_mode
, val
, mode
);
6729 if (!unused_result
&& fixup
)
6730 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
6731 true, OPTAB_LIB_WIDEN
);
6735 /* We need the original code for any further attempts. */
6739 /* If nothing else has succeeded, default to a compare and swap loop. */
6740 if (can_compare_and_swap_p (mode
, true))
6743 rtx t0
= gen_reg_rtx (mode
), t1
;
6747 /* If the result is used, get a register for it. */
6750 if (!target
|| !register_operand (target
, mode
))
6751 target
= gen_reg_rtx (mode
);
6752 /* If fetch_before, copy the value now. */
6754 emit_move_insn (target
, t0
);
6757 target
= const0_rtx
;
6762 t1
= expand_simple_binop (mode
, AND
, t1
, val
, NULL_RTX
,
6763 true, OPTAB_LIB_WIDEN
);
6764 t1
= expand_simple_unop (mode
, code
, t1
, NULL_RTX
, true);
6767 t1
= expand_simple_binop (mode
, code
, t1
, val
, NULL_RTX
, true,
6770 /* For after, copy the value now. */
6771 if (!unused_result
&& after
)
6772 emit_move_insn (target
, t1
);
6773 insn
= get_insns ();
6776 if (t1
!= NULL
&& expand_compare_and_swap_loop (mem
, t0
, t1
, insn
))
6783 /* Return true if OPERAND is suitable for operand number OPNO of
6784 instruction ICODE. */
6787 insn_operand_matches (enum insn_code icode
, unsigned int opno
, rtx operand
)
6789 return (!insn_data
[(int) icode
].operand
[opno
].predicate
6790 || (insn_data
[(int) icode
].operand
[opno
].predicate
6791 (operand
, insn_data
[(int) icode
].operand
[opno
].mode
)));
6794 /* TARGET is a target of a multiword operation that we are going to
6795 implement as a series of word-mode operations. Return true if
6796 TARGET is suitable for this purpose. */
6799 valid_multiword_target_p (rtx target
)
6804 mode
= GET_MODE (target
);
6805 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
+= UNITS_PER_WORD
)
6806 if (!validate_subreg (word_mode
, mode
, target
, i
))
6811 /* Like maybe_legitimize_operand, but do not change the code of the
6812 current rtx value. */
6815 maybe_legitimize_operand_same_code (enum insn_code icode
, unsigned int opno
,
6816 struct expand_operand
*op
)
6818 /* See if the operand matches in its current form. */
6819 if (insn_operand_matches (icode
, opno
, op
->value
))
6822 /* If the operand is a memory whose address has no side effects,
6823 try forcing the address into a non-virtual pseudo register.
6824 The check for side effects is important because copy_to_mode_reg
6825 cannot handle things like auto-modified addresses. */
6826 if (insn_data
[(int) icode
].operand
[opno
].allows_mem
&& MEM_P (op
->value
))
6831 addr
= XEXP (mem
, 0);
6832 if (!(REG_P (addr
) && REGNO (addr
) > LAST_VIRTUAL_REGISTER
)
6833 && !side_effects_p (addr
))
6838 last
= get_last_insn ();
6839 mode
= get_address_mode (mem
);
6840 mem
= replace_equiv_address (mem
, copy_to_mode_reg (mode
, addr
));
6841 if (insn_operand_matches (icode
, opno
, mem
))
6846 delete_insns_since (last
);
6853 /* Try to make OP match operand OPNO of instruction ICODE. Return true
6854 on success, storing the new operand value back in OP. */
6857 maybe_legitimize_operand (enum insn_code icode
, unsigned int opno
,
6858 struct expand_operand
*op
)
6860 machine_mode mode
, imode
;
6861 bool old_volatile_ok
, result
;
6867 old_volatile_ok
= volatile_ok
;
6869 result
= maybe_legitimize_operand_same_code (icode
, opno
, op
);
6870 volatile_ok
= old_volatile_ok
;
6874 gcc_assert (mode
!= VOIDmode
);
6876 && op
->value
!= const0_rtx
6877 && GET_MODE (op
->value
) == mode
6878 && maybe_legitimize_operand_same_code (icode
, opno
, op
))
6881 op
->value
= gen_reg_rtx (mode
);
6886 gcc_assert (mode
!= VOIDmode
);
6887 gcc_assert (GET_MODE (op
->value
) == VOIDmode
6888 || GET_MODE (op
->value
) == mode
);
6889 if (maybe_legitimize_operand_same_code (icode
, opno
, op
))
6892 op
->value
= copy_to_mode_reg (mode
, op
->value
);
6895 case EXPAND_CONVERT_TO
:
6896 gcc_assert (mode
!= VOIDmode
);
6897 op
->value
= convert_to_mode (mode
, op
->value
, op
->unsigned_p
);
6900 case EXPAND_CONVERT_FROM
:
6901 if (GET_MODE (op
->value
) != VOIDmode
)
6902 mode
= GET_MODE (op
->value
);
6904 /* The caller must tell us what mode this value has. */
6905 gcc_assert (mode
!= VOIDmode
);
6907 imode
= insn_data
[(int) icode
].operand
[opno
].mode
;
6908 if (imode
!= VOIDmode
&& imode
!= mode
)
6910 op
->value
= convert_modes (imode
, mode
, op
->value
, op
->unsigned_p
);
6915 case EXPAND_ADDRESS
:
6916 gcc_assert (mode
!= VOIDmode
);
6917 op
->value
= convert_memory_address (mode
, op
->value
);
6920 case EXPAND_INTEGER
:
6921 mode
= insn_data
[(int) icode
].operand
[opno
].mode
;
6922 if (mode
!= VOIDmode
&& const_int_operand (op
->value
, mode
))
6926 return insn_operand_matches (icode
, opno
, op
->value
);
6929 /* Make OP describe an input operand that should have the same value
6930 as VALUE, after any mode conversion that the target might request.
6931 TYPE is the type of VALUE. */
6934 create_convert_operand_from_type (struct expand_operand
*op
,
6935 rtx value
, tree type
)
6937 create_convert_operand_from (op
, value
, TYPE_MODE (type
),
6938 TYPE_UNSIGNED (type
));
6941 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
6942 of instruction ICODE. Return true on success, leaving the new operand
6943 values in the OPS themselves. Emit no code on failure. */
6946 maybe_legitimize_operands (enum insn_code icode
, unsigned int opno
,
6947 unsigned int nops
, struct expand_operand
*ops
)
6952 last
= get_last_insn ();
6953 for (i
= 0; i
< nops
; i
++)
6954 if (!maybe_legitimize_operand (icode
, opno
+ i
, &ops
[i
]))
6956 delete_insns_since (last
);
6962 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
6963 as its operands. Return the instruction pattern on success,
6964 and emit any necessary set-up code. Return null and emit no
6968 maybe_gen_insn (enum insn_code icode
, unsigned int nops
,
6969 struct expand_operand
*ops
)
6971 gcc_assert (nops
== (unsigned int) insn_data
[(int) icode
].n_generator_args
);
6972 if (!maybe_legitimize_operands (icode
, 0, nops
, ops
))
6978 return GEN_FCN (icode
) (ops
[0].value
);
6980 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
);
6982 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
);
6984 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
6987 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
6988 ops
[3].value
, ops
[4].value
);
6990 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
6991 ops
[3].value
, ops
[4].value
, ops
[5].value
);
6993 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
6994 ops
[3].value
, ops
[4].value
, ops
[5].value
,
6997 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
6998 ops
[3].value
, ops
[4].value
, ops
[5].value
,
6999 ops
[6].value
, ops
[7].value
);
7001 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7002 ops
[3].value
, ops
[4].value
, ops
[5].value
,
7003 ops
[6].value
, ops
[7].value
, ops
[8].value
);
7008 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7009 as its operands. Return true on success and emit no code on failure. */
7012 maybe_expand_insn (enum insn_code icode
, unsigned int nops
,
7013 struct expand_operand
*ops
)
7015 rtx_insn
*pat
= maybe_gen_insn (icode
, nops
, ops
);
7024 /* Like maybe_expand_insn, but for jumps. */
7027 maybe_expand_jump_insn (enum insn_code icode
, unsigned int nops
,
7028 struct expand_operand
*ops
)
7030 rtx_insn
*pat
= maybe_gen_insn (icode
, nops
, ops
);
7033 emit_jump_insn (pat
);
7039 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
7043 expand_insn (enum insn_code icode
, unsigned int nops
,
7044 struct expand_operand
*ops
)
7046 if (!maybe_expand_insn (icode
, nops
, ops
))
7050 /* Like expand_insn, but for jumps. */
7053 expand_jump_insn (enum insn_code icode
, unsigned int nops
,
7054 struct expand_operand
*ops
)
7056 if (!maybe_expand_jump_insn (icode
, nops
, ops
))