1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2018 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
35 #include "diagnostic-core.h"
36 #include "rtx-vector-builder.h"
38 /* Include insn-config.h before expr.h so that HAVE_conditional_move
39 is properly defined. */
40 #include "stor-layout.h"
45 #include "optabs-tree.h"
48 static void prepare_float_lib_cmp (rtx
, rtx
, enum rtx_code
, rtx
*,
50 static rtx
expand_unop_direct (machine_mode
, optab
, rtx
, rtx
, int);
51 static void emit_libcall_block_1 (rtx_insn
*, rtx
, rtx
, rtx
, bool);
53 /* Debug facility for use in GDB. */
54 void debug_optab_libfuncs (void);
56 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
57 the result of operation CODE applied to OP0 (and OP1 if it is a binary
58 operation). OP0_MODE is OP0's mode.
60 If the last insn does not set TARGET, don't do anything, but return 1.
62 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
63 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
64 try again, ensuring that TARGET is not one of the operands. */
67 add_equal_note (rtx_insn
*insns
, rtx target
, enum rtx_code code
, rtx op0
,
68 rtx op1
, machine_mode op0_mode
)
74 gcc_assert (insns
&& INSN_P (insns
) && NEXT_INSN (insns
));
76 if (GET_RTX_CLASS (code
) != RTX_COMM_ARITH
77 && GET_RTX_CLASS (code
) != RTX_BIN_ARITH
78 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
79 && GET_RTX_CLASS (code
) != RTX_COMPARE
80 && GET_RTX_CLASS (code
) != RTX_UNARY
)
83 if (GET_CODE (target
) == ZERO_EXTRACT
)
86 for (last_insn
= insns
;
87 NEXT_INSN (last_insn
) != NULL_RTX
;
88 last_insn
= NEXT_INSN (last_insn
))
91 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
92 a value changing in the insn, so the note would be invalid for CSE. */
93 if (reg_overlap_mentioned_p (target
, op0
)
94 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
97 && (rtx_equal_p (target
, op0
)
98 || (op1
&& rtx_equal_p (target
, op1
))))
100 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
101 over expanding it as temp = MEM op X, MEM = temp. If the target
102 supports MEM = MEM op X instructions, it is sometimes too hard
103 to reconstruct that form later, especially if X is also a memory,
104 and due to multiple occurrences of addresses the address might
105 be forced into register unnecessarily.
106 Note that not emitting the REG_EQUIV note might inhibit
107 CSE in some cases. */
108 set
= single_set (last_insn
);
110 && GET_CODE (SET_SRC (set
)) == code
111 && MEM_P (SET_DEST (set
))
112 && (rtx_equal_p (SET_DEST (set
), XEXP (SET_SRC (set
), 0))
113 || (op1
&& rtx_equal_p (SET_DEST (set
),
114 XEXP (SET_SRC (set
), 1)))))
120 set
= set_for_reg_notes (last_insn
);
124 if (! rtx_equal_p (SET_DEST (set
), target
)
125 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
126 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
127 || ! rtx_equal_p (XEXP (SET_DEST (set
), 0), target
)))
130 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
140 if (op0_mode
!= VOIDmode
&& GET_MODE (target
) != op0_mode
)
142 note
= gen_rtx_fmt_e (code
, op0_mode
, copy_rtx (op0
));
143 if (GET_MODE_UNIT_SIZE (op0_mode
)
144 > GET_MODE_UNIT_SIZE (GET_MODE (target
)))
145 note
= simplify_gen_unary (TRUNCATE
, GET_MODE (target
),
148 note
= simplify_gen_unary (ZERO_EXTEND
, GET_MODE (target
),
154 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
158 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
160 set_unique_reg_note (last_insn
, REG_EQUAL
, note
);
165 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
166 for a widening operation would be. In most cases this would be OP0, but if
167 that's a constant it'll be VOIDmode, which isn't useful. */
170 widened_mode (machine_mode to_mode
, rtx op0
, rtx op1
)
172 machine_mode m0
= GET_MODE (op0
);
173 machine_mode m1
= GET_MODE (op1
);
176 if (m0
== VOIDmode
&& m1
== VOIDmode
)
178 else if (m0
== VOIDmode
|| GET_MODE_UNIT_SIZE (m0
) < GET_MODE_UNIT_SIZE (m1
))
183 if (GET_MODE_UNIT_SIZE (result
) > GET_MODE_UNIT_SIZE (to_mode
))
189 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
190 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
191 not actually do a sign-extend or zero-extend, but can leave the
192 higher-order bits of the result rtx undefined, for example, in the case
193 of logical operations, but not right shifts. */
196 widen_operand (rtx op
, machine_mode mode
, machine_mode oldmode
,
197 int unsignedp
, int no_extend
)
200 scalar_int_mode int_mode
;
202 /* If we don't have to extend and this is a constant, return it. */
203 if (no_extend
&& GET_MODE (op
) == VOIDmode
)
206 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
207 extend since it will be more efficient to do so unless the signedness of
208 a promoted object differs from our extension. */
210 || !is_a
<scalar_int_mode
> (mode
, &int_mode
)
211 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)
212 && SUBREG_CHECK_PROMOTED_SIGN (op
, unsignedp
)))
213 return convert_modes (mode
, oldmode
, op
, unsignedp
);
215 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
217 if (GET_MODE_SIZE (int_mode
) <= UNITS_PER_WORD
)
218 return gen_lowpart (int_mode
, force_reg (GET_MODE (op
), op
));
220 /* Otherwise, get an object of MODE, clobber it, and set the low-order
223 result
= gen_reg_rtx (int_mode
);
224 emit_clobber (result
);
225 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
229 /* Expand vector widening operations.
231 There are two different classes of operations handled here:
232 1) Operations whose result is wider than all the arguments to the operation.
233 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
234 In this case OP0 and optionally OP1 would be initialized,
235 but WIDE_OP wouldn't (not relevant for this case).
236 2) Operations whose result is of the same size as the last argument to the
237 operation, but wider than all the other arguments to the operation.
238 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
239 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
241 E.g, when called to expand the following operations, this is how
242 the arguments will be initialized:
244 widening-sum 2 oprnd0 - oprnd1
245 widening-dot-product 3 oprnd0 oprnd1 oprnd2
246 widening-mult 2 oprnd0 oprnd1 -
247 type-promotion (vec-unpack) 1 oprnd0 - - */
250 expand_widen_pattern_expr (sepops ops
, rtx op0
, rtx op1
, rtx wide_op
,
251 rtx target
, int unsignedp
)
253 struct expand_operand eops
[4];
254 tree oprnd0
, oprnd1
, oprnd2
;
255 machine_mode wmode
= VOIDmode
, tmode0
, tmode1
= VOIDmode
;
256 optab widen_pattern_optab
;
257 enum insn_code icode
;
258 int nops
= TREE_CODE_LENGTH (ops
->code
);
262 tmode0
= TYPE_MODE (TREE_TYPE (oprnd0
));
263 widen_pattern_optab
=
264 optab_for_tree_code (ops
->code
, TREE_TYPE (oprnd0
), optab_default
);
265 if (ops
->code
== WIDEN_MULT_PLUS_EXPR
266 || ops
->code
== WIDEN_MULT_MINUS_EXPR
)
267 icode
= find_widening_optab_handler (widen_pattern_optab
,
268 TYPE_MODE (TREE_TYPE (ops
->op2
)),
271 icode
= optab_handler (widen_pattern_optab
, tmode0
);
272 gcc_assert (icode
!= CODE_FOR_nothing
);
277 tmode1
= TYPE_MODE (TREE_TYPE (oprnd1
));
280 /* The last operand is of a wider mode than the rest of the operands. */
285 gcc_assert (tmode1
== tmode0
);
288 wmode
= TYPE_MODE (TREE_TYPE (oprnd2
));
292 create_output_operand (&eops
[op
++], target
, TYPE_MODE (ops
->type
));
293 create_convert_operand_from (&eops
[op
++], op0
, tmode0
, unsignedp
);
295 create_convert_operand_from (&eops
[op
++], op1
, tmode1
, unsignedp
);
297 create_convert_operand_from (&eops
[op
++], wide_op
, wmode
, unsignedp
);
298 expand_insn (icode
, op
, eops
);
299 return eops
[0].value
;
302 /* Generate code to perform an operation specified by TERNARY_OPTAB
303 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
305 UNSIGNEDP is for the case where we have to widen the operands
306 to perform the operation. It says to use zero-extension.
308 If TARGET is nonzero, the value
309 is generated there, if it is convenient to do so.
310 In all cases an rtx is returned for the locus of the value;
311 this may or may not be TARGET. */
314 expand_ternary_op (machine_mode mode
, optab ternary_optab
, rtx op0
,
315 rtx op1
, rtx op2
, rtx target
, int unsignedp
)
317 struct expand_operand ops
[4];
318 enum insn_code icode
= optab_handler (ternary_optab
, mode
);
320 gcc_assert (optab_handler (ternary_optab
, mode
) != CODE_FOR_nothing
);
322 create_output_operand (&ops
[0], target
, mode
);
323 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
324 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
325 create_convert_operand_from (&ops
[3], op2
, mode
, unsignedp
);
326 expand_insn (icode
, 4, ops
);
331 /* Like expand_binop, but return a constant rtx if the result can be
332 calculated at compile time. The arguments and return value are
333 otherwise the same as for expand_binop. */
336 simplify_expand_binop (machine_mode mode
, optab binoptab
,
337 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
338 enum optab_methods methods
)
340 if (CONSTANT_P (op0
) && CONSTANT_P (op1
))
342 rtx x
= simplify_binary_operation (optab_to_code (binoptab
),
348 return expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
);
351 /* Like simplify_expand_binop, but always put the result in TARGET.
352 Return true if the expansion succeeded. */
355 force_expand_binop (machine_mode mode
, optab binoptab
,
356 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
357 enum optab_methods methods
)
359 rtx x
= simplify_expand_binop (mode
, binoptab
, op0
, op1
,
360 target
, unsignedp
, methods
);
364 emit_move_insn (target
, x
);
368 /* Create a new vector value in VMODE with all elements set to OP. The
369 mode of OP must be the element mode of VMODE. If OP is a constant,
370 then the return value will be a constant. */
373 expand_vector_broadcast (machine_mode vmode
, rtx op
)
378 gcc_checking_assert (VECTOR_MODE_P (vmode
));
380 if (valid_for_const_vector_p (vmode
, op
))
381 return gen_const_vec_duplicate (vmode
, op
);
383 insn_code icode
= optab_handler (vec_duplicate_optab
, vmode
);
384 if (icode
!= CODE_FOR_nothing
)
386 struct expand_operand ops
[2];
387 create_output_operand (&ops
[0], NULL_RTX
, vmode
);
388 create_input_operand (&ops
[1], op
, GET_MODE (op
));
389 expand_insn (icode
, 2, ops
);
393 if (!GET_MODE_NUNITS (vmode
).is_constant (&n
))
396 /* ??? If the target doesn't have a vec_init, then we have no easy way
397 of performing this operation. Most of this sort of generic support
398 is hidden away in the vector lowering support in gimple. */
399 icode
= convert_optab_handler (vec_init_optab
, vmode
,
400 GET_MODE_INNER (vmode
));
401 if (icode
== CODE_FOR_nothing
)
404 vec
= rtvec_alloc (n
);
405 for (int i
= 0; i
< n
; ++i
)
406 RTVEC_ELT (vec
, i
) = op
;
407 rtx ret
= gen_reg_rtx (vmode
);
408 emit_insn (GEN_FCN (icode
) (ret
, gen_rtx_PARALLEL (vmode
, vec
)));
413 /* This subroutine of expand_doubleword_shift handles the cases in which
414 the effective shift value is >= BITS_PER_WORD. The arguments and return
415 value are the same as for the parent routine, except that SUPERWORD_OP1
416 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
417 INTO_TARGET may be null if the caller has decided to calculate it. */
420 expand_superword_shift (optab binoptab
, rtx outof_input
, rtx superword_op1
,
421 rtx outof_target
, rtx into_target
,
422 int unsignedp
, enum optab_methods methods
)
424 if (into_target
!= 0)
425 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, superword_op1
,
426 into_target
, unsignedp
, methods
))
429 if (outof_target
!= 0)
431 /* For a signed right shift, we must fill OUTOF_TARGET with copies
432 of the sign bit, otherwise we must fill it with zeros. */
433 if (binoptab
!= ashr_optab
)
434 emit_move_insn (outof_target
, CONST0_RTX (word_mode
));
436 if (!force_expand_binop (word_mode
, binoptab
, outof_input
,
437 gen_int_shift_amount (word_mode
,
439 outof_target
, unsignedp
, methods
))
445 /* This subroutine of expand_doubleword_shift handles the cases in which
446 the effective shift value is < BITS_PER_WORD. The arguments and return
447 value are the same as for the parent routine. */
450 expand_subword_shift (scalar_int_mode op1_mode
, optab binoptab
,
451 rtx outof_input
, rtx into_input
, rtx op1
,
452 rtx outof_target
, rtx into_target
,
453 int unsignedp
, enum optab_methods methods
,
454 unsigned HOST_WIDE_INT shift_mask
)
456 optab reverse_unsigned_shift
, unsigned_shift
;
459 reverse_unsigned_shift
= (binoptab
== ashl_optab
? lshr_optab
: ashl_optab
);
460 unsigned_shift
= (binoptab
== ashl_optab
? ashl_optab
: lshr_optab
);
462 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
463 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
464 the opposite direction to BINOPTAB. */
465 if (CONSTANT_P (op1
) || shift_mask
>= BITS_PER_WORD
)
467 carries
= outof_input
;
468 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
,
469 op1_mode
), op1_mode
);
470 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
475 /* We must avoid shifting by BITS_PER_WORD bits since that is either
476 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
477 has unknown behavior. Do a single shift first, then shift by the
478 remainder. It's OK to use ~OP1 as the remainder if shift counts
479 are truncated to the mode size. */
480 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
481 outof_input
, const1_rtx
, 0, unsignedp
, methods
);
482 if (shift_mask
== BITS_PER_WORD
- 1)
484 tmp
= immed_wide_int_const
485 (wi::minus_one (GET_MODE_PRECISION (op1_mode
)), op1_mode
);
486 tmp
= simplify_expand_binop (op1_mode
, xor_optab
, op1
, tmp
,
491 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
- 1,
492 op1_mode
), op1_mode
);
493 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
497 if (tmp
== 0 || carries
== 0)
499 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
500 carries
, tmp
, 0, unsignedp
, methods
);
504 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
505 so the result can go directly into INTO_TARGET if convenient. */
506 tmp
= expand_binop (word_mode
, unsigned_shift
, into_input
, op1
,
507 into_target
, unsignedp
, methods
);
511 /* Now OR in the bits carried over from OUTOF_INPUT. */
512 if (!force_expand_binop (word_mode
, ior_optab
, tmp
, carries
,
513 into_target
, unsignedp
, methods
))
516 /* Use a standard word_mode shift for the out-of half. */
517 if (outof_target
!= 0)
518 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
519 outof_target
, unsignedp
, methods
))
526 /* Try implementing expand_doubleword_shift using conditional moves.
527 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
528 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
529 are the shift counts to use in the former and latter case. All other
530 arguments are the same as the parent routine. */
533 expand_doubleword_shift_condmove (scalar_int_mode op1_mode
, optab binoptab
,
534 enum rtx_code cmp_code
, rtx cmp1
, rtx cmp2
,
535 rtx outof_input
, rtx into_input
,
536 rtx subword_op1
, rtx superword_op1
,
537 rtx outof_target
, rtx into_target
,
538 int unsignedp
, enum optab_methods methods
,
539 unsigned HOST_WIDE_INT shift_mask
)
541 rtx outof_superword
, into_superword
;
543 /* Put the superword version of the output into OUTOF_SUPERWORD and
545 outof_superword
= outof_target
!= 0 ? gen_reg_rtx (word_mode
) : 0;
546 if (outof_target
!= 0 && subword_op1
== superword_op1
)
548 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
549 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
550 into_superword
= outof_target
;
551 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
552 outof_superword
, 0, unsignedp
, methods
))
557 into_superword
= gen_reg_rtx (word_mode
);
558 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
559 outof_superword
, into_superword
,
564 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
565 if (!expand_subword_shift (op1_mode
, binoptab
,
566 outof_input
, into_input
, subword_op1
,
567 outof_target
, into_target
,
568 unsignedp
, methods
, shift_mask
))
571 /* Select between them. Do the INTO half first because INTO_SUPERWORD
572 might be the current value of OUTOF_TARGET. */
573 if (!emit_conditional_move (into_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
574 into_target
, into_superword
, word_mode
, false))
577 if (outof_target
!= 0)
578 if (!emit_conditional_move (outof_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
579 outof_target
, outof_superword
,
586 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
587 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
588 input operand; the shift moves bits in the direction OUTOF_INPUT->
589 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
590 of the target. OP1 is the shift count and OP1_MODE is its mode.
591 If OP1 is constant, it will have been truncated as appropriate
592 and is known to be nonzero.
594 If SHIFT_MASK is zero, the result of word shifts is undefined when the
595 shift count is outside the range [0, BITS_PER_WORD). This routine must
596 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
598 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
599 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
600 fill with zeros or sign bits as appropriate.
602 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
603 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
604 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
605 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
608 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
609 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
610 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
611 function wants to calculate it itself.
613 Return true if the shift could be successfully synthesized. */
616 expand_doubleword_shift (scalar_int_mode op1_mode
, optab binoptab
,
617 rtx outof_input
, rtx into_input
, rtx op1
,
618 rtx outof_target
, rtx into_target
,
619 int unsignedp
, enum optab_methods methods
,
620 unsigned HOST_WIDE_INT shift_mask
)
622 rtx superword_op1
, tmp
, cmp1
, cmp2
;
623 enum rtx_code cmp_code
;
625 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
626 fill the result with sign or zero bits as appropriate. If so, the value
627 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
628 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
629 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
631 This isn't worthwhile for constant shifts since the optimizers will
632 cope better with in-range shift counts. */
633 if (shift_mask
>= BITS_PER_WORD
635 && !CONSTANT_P (op1
))
637 if (!expand_doubleword_shift (op1_mode
, binoptab
,
638 outof_input
, into_input
, op1
,
640 unsignedp
, methods
, shift_mask
))
642 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
643 outof_target
, unsignedp
, methods
))
648 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
649 is true when the effective shift value is less than BITS_PER_WORD.
650 Set SUPERWORD_OP1 to the shift count that should be used to shift
651 OUTOF_INPUT into INTO_TARGET when the condition is false. */
652 tmp
= immed_wide_int_const (wi::shwi (BITS_PER_WORD
, op1_mode
), op1_mode
);
653 if (!CONSTANT_P (op1
) && shift_mask
== BITS_PER_WORD
- 1)
655 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
656 is a subword shift count. */
657 cmp1
= simplify_expand_binop (op1_mode
, and_optab
, op1
, tmp
,
659 cmp2
= CONST0_RTX (op1_mode
);
665 /* Set CMP1 to OP1 - BITS_PER_WORD. */
666 cmp1
= simplify_expand_binop (op1_mode
, sub_optab
, op1
, tmp
,
668 cmp2
= CONST0_RTX (op1_mode
);
670 superword_op1
= cmp1
;
675 /* If we can compute the condition at compile time, pick the
676 appropriate subroutine. */
677 tmp
= simplify_relational_operation (cmp_code
, SImode
, op1_mode
, cmp1
, cmp2
);
678 if (tmp
!= 0 && CONST_INT_P (tmp
))
680 if (tmp
== const0_rtx
)
681 return expand_superword_shift (binoptab
, outof_input
, superword_op1
,
682 outof_target
, into_target
,
685 return expand_subword_shift (op1_mode
, binoptab
,
686 outof_input
, into_input
, op1
,
687 outof_target
, into_target
,
688 unsignedp
, methods
, shift_mask
);
691 /* Try using conditional moves to generate straight-line code. */
692 if (HAVE_conditional_move
)
694 rtx_insn
*start
= get_last_insn ();
695 if (expand_doubleword_shift_condmove (op1_mode
, binoptab
,
696 cmp_code
, cmp1
, cmp2
,
697 outof_input
, into_input
,
699 outof_target
, into_target
,
700 unsignedp
, methods
, shift_mask
))
702 delete_insns_since (start
);
705 /* As a last resort, use branches to select the correct alternative. */
706 rtx_code_label
*subword_label
= gen_label_rtx ();
707 rtx_code_label
*done_label
= gen_label_rtx ();
710 do_compare_rtx_and_jump (cmp1
, cmp2
, cmp_code
, false, op1_mode
,
712 profile_probability::uninitialized ());
715 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
716 outof_target
, into_target
,
720 emit_jump_insn (targetm
.gen_jump (done_label
));
722 emit_label (subword_label
);
724 if (!expand_subword_shift (op1_mode
, binoptab
,
725 outof_input
, into_input
, op1
,
726 outof_target
, into_target
,
727 unsignedp
, methods
, shift_mask
))
730 emit_label (done_label
);
734 /* Subroutine of expand_binop. Perform a double word multiplication of
735 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
736 as the target's word_mode. This function return NULL_RTX if anything
737 goes wrong, in which case it may have already emitted instructions
738 which need to be deleted.
740 If we want to multiply two two-word values and have normal and widening
741 multiplies of single-word values, we can do this with three smaller
744 The multiplication proceeds as follows:
745 _______________________
746 [__op0_high_|__op0_low__]
747 _______________________
748 * [__op1_high_|__op1_low__]
749 _______________________________________________
750 _______________________
751 (1) [__op0_low__*__op1_low__]
752 _______________________
753 (2a) [__op0_low__*__op1_high_]
754 _______________________
755 (2b) [__op0_high_*__op1_low__]
756 _______________________
757 (3) [__op0_high_*__op1_high_]
760 This gives a 4-word result. Since we are only interested in the
761 lower 2 words, partial result (3) and the upper words of (2a) and
762 (2b) don't need to be calculated. Hence (2a) and (2b) can be
763 calculated using non-widening multiplication.
765 (1), however, needs to be calculated with an unsigned widening
766 multiplication. If this operation is not directly supported we
767 try using a signed widening multiplication and adjust the result.
768 This adjustment works as follows:
770 If both operands are positive then no adjustment is needed.
772 If the operands have different signs, for example op0_low < 0 and
773 op1_low >= 0, the instruction treats the most significant bit of
774 op0_low as a sign bit instead of a bit with significance
775 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
776 with 2**BITS_PER_WORD - op0_low, and two's complements the
777 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
780 Similarly, if both operands are negative, we need to add
781 (op0_low + op1_low) * 2**BITS_PER_WORD.
783 We use a trick to adjust quickly. We logically shift op0_low right
784 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
785 op0_high (op1_high) before it is used to calculate 2b (2a). If no
786 logical shift exists, we do an arithmetic right shift and subtract
790 expand_doubleword_mult (machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
791 bool umulp
, enum optab_methods methods
)
793 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
794 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
795 rtx wordm1
= (umulp
? NULL_RTX
796 : gen_int_shift_amount (word_mode
, BITS_PER_WORD
- 1));
797 rtx product
, adjust
, product_high
, temp
;
799 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
800 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
801 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
802 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
804 /* If we're using an unsigned multiply to directly compute the product
805 of the low-order words of the operands and perform any required
806 adjustments of the operands, we begin by trying two more multiplications
807 and then computing the appropriate sum.
809 We have checked above that the required addition is provided.
810 Full-word addition will normally always succeed, especially if
811 it is provided at all, so we don't worry about its failure. The
812 multiplication may well fail, however, so we do handle that. */
816 /* ??? This could be done with emit_store_flag where available. */
817 temp
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
818 NULL_RTX
, 1, methods
);
820 op0_high
= expand_binop (word_mode
, add_optab
, op0_high
, temp
,
821 NULL_RTX
, 0, OPTAB_DIRECT
);
824 temp
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
825 NULL_RTX
, 0, methods
);
828 op0_high
= expand_binop (word_mode
, sub_optab
, op0_high
, temp
,
829 NULL_RTX
, 0, OPTAB_DIRECT
);
836 adjust
= expand_binop (word_mode
, smul_optab
, op0_high
, op1_low
,
837 NULL_RTX
, 0, OPTAB_DIRECT
);
841 /* OP0_HIGH should now be dead. */
845 /* ??? This could be done with emit_store_flag where available. */
846 temp
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
847 NULL_RTX
, 1, methods
);
849 op1_high
= expand_binop (word_mode
, add_optab
, op1_high
, temp
,
850 NULL_RTX
, 0, OPTAB_DIRECT
);
853 temp
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
854 NULL_RTX
, 0, methods
);
857 op1_high
= expand_binop (word_mode
, sub_optab
, op1_high
, temp
,
858 NULL_RTX
, 0, OPTAB_DIRECT
);
865 temp
= expand_binop (word_mode
, smul_optab
, op1_high
, op0_low
,
866 NULL_RTX
, 0, OPTAB_DIRECT
);
870 /* OP1_HIGH should now be dead. */
872 adjust
= expand_binop (word_mode
, add_optab
, adjust
, temp
,
873 NULL_RTX
, 0, OPTAB_DIRECT
);
875 if (target
&& !REG_P (target
))
878 /* *_widen_optab needs to determine operand mode, make sure at least
879 one operand has non-VOID mode. */
880 if (GET_MODE (op0_low
) == VOIDmode
&& GET_MODE (op1_low
) == VOIDmode
)
881 op0_low
= force_reg (word_mode
, op0_low
);
884 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
885 target
, 1, OPTAB_DIRECT
);
887 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
888 target
, 1, OPTAB_DIRECT
);
893 product_high
= operand_subword (product
, high
, 1, mode
);
894 adjust
= expand_binop (word_mode
, add_optab
, product_high
, adjust
,
895 NULL_RTX
, 0, OPTAB_DIRECT
);
896 emit_move_insn (product_high
, adjust
);
900 /* Wrapper around expand_binop which takes an rtx code to specify
901 the operation to perform, not an optab pointer. All other
902 arguments are the same. */
904 expand_simple_binop (machine_mode mode
, enum rtx_code code
, rtx op0
,
905 rtx op1
, rtx target
, int unsignedp
,
906 enum optab_methods methods
)
908 optab binop
= code_to_optab (code
);
911 return expand_binop (mode
, binop
, op0
, op1
, target
, unsignedp
, methods
);
914 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
915 binop. Order them according to commutative_operand_precedence and, if
916 possible, try to put TARGET or a pseudo first. */
918 swap_commutative_operands_with_target (rtx target
, rtx op0
, rtx op1
)
920 int op0_prec
= commutative_operand_precedence (op0
);
921 int op1_prec
= commutative_operand_precedence (op1
);
923 if (op0_prec
< op1_prec
)
926 if (op0_prec
> op1_prec
)
929 /* With equal precedence, both orders are ok, but it is better if the
930 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
931 if (target
== 0 || REG_P (target
))
932 return (REG_P (op1
) && !REG_P (op0
)) || target
== op1
;
934 return rtx_equal_p (op1
, target
);
937 /* Return true if BINOPTAB implements a shift operation. */
940 shift_optab_p (optab binoptab
)
942 switch (optab_to_code (binoptab
))
958 /* Return true if BINOPTAB implements a commutative binary operation. */
961 commutative_optab_p (optab binoptab
)
963 return (GET_RTX_CLASS (optab_to_code (binoptab
)) == RTX_COMM_ARITH
964 || binoptab
== smul_widen_optab
965 || binoptab
== umul_widen_optab
966 || binoptab
== smul_highpart_optab
967 || binoptab
== umul_highpart_optab
);
970 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
971 optimizing, and if the operand is a constant that costs more than
972 1 instruction, force the constant into a register and return that
973 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
976 avoid_expensive_constant (machine_mode mode
, optab binoptab
,
977 int opn
, rtx x
, bool unsignedp
)
979 bool speed
= optimize_insn_for_speed_p ();
984 && (rtx_cost (x
, mode
, optab_to_code (binoptab
), opn
, speed
)
985 > set_src_cost (x
, mode
, speed
)))
989 HOST_WIDE_INT intval
= trunc_int_for_mode (INTVAL (x
), mode
);
990 if (intval
!= INTVAL (x
))
991 x
= GEN_INT (intval
);
994 x
= convert_modes (mode
, VOIDmode
, x
, unsignedp
);
995 x
= force_reg (mode
, x
);
1000 /* Helper function for expand_binop: handle the case where there
1001 is an insn ICODE that directly implements the indicated operation.
1002 Returns null if this is not possible. */
1004 expand_binop_directly (enum insn_code icode
, machine_mode mode
, optab binoptab
,
1006 rtx target
, int unsignedp
, enum optab_methods methods
,
1009 machine_mode xmode0
= insn_data
[(int) icode
].operand
[1].mode
;
1010 machine_mode xmode1
= insn_data
[(int) icode
].operand
[2].mode
;
1011 machine_mode mode0
, mode1
, tmp_mode
;
1012 struct expand_operand ops
[3];
1015 rtx xop0
= op0
, xop1
= op1
;
1016 bool canonicalize_op1
= false;
1018 /* If it is a commutative operator and the modes would match
1019 if we would swap the operands, we can save the conversions. */
1020 commutative_p
= commutative_optab_p (binoptab
);
1022 && GET_MODE (xop0
) != xmode0
&& GET_MODE (xop1
) != xmode1
1023 && GET_MODE (xop0
) == xmode1
&& GET_MODE (xop1
) == xmode1
)
1024 std::swap (xop0
, xop1
);
1026 /* If we are optimizing, force expensive constants into a register. */
1027 xop0
= avoid_expensive_constant (xmode0
, binoptab
, 0, xop0
, unsignedp
);
1028 if (!shift_optab_p (binoptab
))
1029 xop1
= avoid_expensive_constant (xmode1
, binoptab
, 1, xop1
, unsignedp
);
1031 /* Shifts and rotates often use a different mode for op1 from op0;
1032 for VOIDmode constants we don't know the mode, so force it
1033 to be canonicalized using convert_modes. */
1034 canonicalize_op1
= true;
1036 /* In case the insn wants input operands in modes different from
1037 those of the actual operands, convert the operands. It would
1038 seem that we don't need to convert CONST_INTs, but we do, so
1039 that they're properly zero-extended, sign-extended or truncated
1042 mode0
= GET_MODE (xop0
) != VOIDmode
? GET_MODE (xop0
) : mode
;
1043 if (xmode0
!= VOIDmode
&& xmode0
!= mode0
)
1045 xop0
= convert_modes (xmode0
, mode0
, xop0
, unsignedp
);
1049 mode1
= ((GET_MODE (xop1
) != VOIDmode
|| canonicalize_op1
)
1050 ? GET_MODE (xop1
) : mode
);
1051 if (xmode1
!= VOIDmode
&& xmode1
!= mode1
)
1053 xop1
= convert_modes (xmode1
, mode1
, xop1
, unsignedp
);
1057 /* If operation is commutative,
1058 try to make the first operand a register.
1059 Even better, try to make it the same as the target.
1060 Also try to make the last operand a constant. */
1062 && swap_commutative_operands_with_target (target
, xop0
, xop1
))
1063 std::swap (xop0
, xop1
);
1065 /* Now, if insn's predicates don't allow our operands, put them into
1068 if (binoptab
== vec_pack_trunc_optab
1069 || binoptab
== vec_pack_usat_optab
1070 || binoptab
== vec_pack_ssat_optab
1071 || binoptab
== vec_pack_ufix_trunc_optab
1072 || binoptab
== vec_pack_sfix_trunc_optab
)
1074 /* The mode of the result is different then the mode of the
1076 tmp_mode
= insn_data
[(int) icode
].operand
[0].mode
;
1077 if (VECTOR_MODE_P (mode
)
1078 && maybe_ne (GET_MODE_NUNITS (tmp_mode
), 2 * GET_MODE_NUNITS (mode
)))
1080 delete_insns_since (last
);
1087 create_output_operand (&ops
[0], target
, tmp_mode
);
1088 create_input_operand (&ops
[1], xop0
, mode0
);
1089 create_input_operand (&ops
[2], xop1
, mode1
);
1090 pat
= maybe_gen_insn (icode
, 3, ops
);
1093 /* If PAT is composed of more than one insn, try to add an appropriate
1094 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1095 operand, call expand_binop again, this time without a target. */
1096 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
1097 && ! add_equal_note (pat
, ops
[0].value
,
1098 optab_to_code (binoptab
),
1099 ops
[1].value
, ops
[2].value
, mode0
))
1101 delete_insns_since (last
);
1102 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
1103 unsignedp
, methods
);
1107 return ops
[0].value
;
1109 delete_insns_since (last
);
1113 /* Generate code to perform an operation specified by BINOPTAB
1114 on operands OP0 and OP1, with result having machine-mode MODE.
1116 UNSIGNEDP is for the case where we have to widen the operands
1117 to perform the operation. It says to use zero-extension.
1119 If TARGET is nonzero, the value
1120 is generated there, if it is convenient to do so.
1121 In all cases an rtx is returned for the locus of the value;
1122 this may or may not be TARGET. */
1125 expand_binop (machine_mode mode
, optab binoptab
, rtx op0
, rtx op1
,
1126 rtx target
, int unsignedp
, enum optab_methods methods
)
1128 enum optab_methods next_methods
1129 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
1130 ? OPTAB_WIDEN
: methods
);
1131 enum mode_class mclass
;
1132 enum insn_code icode
;
1133 machine_mode wider_mode
;
1134 scalar_int_mode int_mode
;
1137 rtx_insn
*entry_last
= get_last_insn ();
1140 mclass
= GET_MODE_CLASS (mode
);
1142 /* If subtracting an integer constant, convert this into an addition of
1143 the negated constant. */
1145 if (binoptab
== sub_optab
&& CONST_INT_P (op1
))
1147 op1
= negate_rtx (mode
, op1
);
1148 binoptab
= add_optab
;
1150 /* For shifts, constant invalid op1 might be expanded from different
1151 mode than MODE. As those are invalid, force them to a register
1152 to avoid further problems during expansion. */
1153 else if (CONST_INT_P (op1
)
1154 && shift_optab_p (binoptab
)
1155 && UINTVAL (op1
) >= GET_MODE_BITSIZE (GET_MODE_INNER (mode
)))
1157 op1
= gen_int_mode (INTVAL (op1
), GET_MODE_INNER (mode
));
1158 op1
= force_reg (GET_MODE_INNER (mode
), op1
);
1161 /* Record where to delete back to if we backtrack. */
1162 last
= get_last_insn ();
1164 /* If we can do it with a three-operand insn, do so. */
1166 if (methods
!= OPTAB_MUST_WIDEN
)
1168 if (convert_optab_p (binoptab
))
1170 machine_mode from_mode
= widened_mode (mode
, op0
, op1
);
1171 icode
= find_widening_optab_handler (binoptab
, mode
, from_mode
);
1174 icode
= optab_handler (binoptab
, mode
);
1175 if (icode
!= CODE_FOR_nothing
)
1177 temp
= expand_binop_directly (icode
, mode
, binoptab
, op0
, op1
,
1178 target
, unsignedp
, methods
, last
);
1184 /* If we were trying to rotate, and that didn't work, try rotating
1185 the other direction before falling back to shifts and bitwise-or. */
1186 if (((binoptab
== rotl_optab
1187 && (icode
= optab_handler (rotr_optab
, mode
)) != CODE_FOR_nothing
)
1188 || (binoptab
== rotr_optab
1189 && (icode
= optab_handler (rotl_optab
, mode
)) != CODE_FOR_nothing
))
1190 && is_int_mode (mode
, &int_mode
))
1192 optab otheroptab
= (binoptab
== rotl_optab
? rotr_optab
: rotl_optab
);
1194 unsigned int bits
= GET_MODE_PRECISION (int_mode
);
1196 if (CONST_INT_P (op1
))
1197 newop1
= gen_int_shift_amount (int_mode
, bits
- INTVAL (op1
));
1198 else if (targetm
.shift_truncation_mask (int_mode
) == bits
- 1)
1199 newop1
= negate_rtx (GET_MODE (op1
), op1
);
1201 newop1
= expand_binop (GET_MODE (op1
), sub_optab
,
1202 gen_int_mode (bits
, GET_MODE (op1
)), op1
,
1203 NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1205 temp
= expand_binop_directly (icode
, int_mode
, otheroptab
, op0
, newop1
,
1206 target
, unsignedp
, methods
, last
);
1211 /* If this is a multiply, see if we can do a widening operation that
1212 takes operands of this mode and makes a wider mode. */
1214 if (binoptab
== smul_optab
1215 && GET_MODE_2XWIDER_MODE (mode
).exists (&wider_mode
)
1216 && (convert_optab_handler ((unsignedp
1218 : smul_widen_optab
),
1219 wider_mode
, mode
) != CODE_FOR_nothing
))
1221 /* *_widen_optab needs to determine operand mode, make sure at least
1222 one operand has non-VOID mode. */
1223 if (GET_MODE (op0
) == VOIDmode
&& GET_MODE (op1
) == VOIDmode
)
1224 op0
= force_reg (mode
, op0
);
1225 temp
= expand_binop (wider_mode
,
1226 unsignedp
? umul_widen_optab
: smul_widen_optab
,
1227 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1231 if (GET_MODE_CLASS (mode
) == MODE_INT
1232 && TRULY_NOOP_TRUNCATION_MODES_P (mode
, GET_MODE (temp
)))
1233 return gen_lowpart (mode
, temp
);
1235 return convert_to_mode (mode
, temp
, unsignedp
);
1239 /* If this is a vector shift by a scalar, see if we can do a vector
1240 shift by a vector. If so, broadcast the scalar into a vector. */
1241 if (mclass
== MODE_VECTOR_INT
)
1243 optab otheroptab
= unknown_optab
;
1245 if (binoptab
== ashl_optab
)
1246 otheroptab
= vashl_optab
;
1247 else if (binoptab
== ashr_optab
)
1248 otheroptab
= vashr_optab
;
1249 else if (binoptab
== lshr_optab
)
1250 otheroptab
= vlshr_optab
;
1251 else if (binoptab
== rotl_optab
)
1252 otheroptab
= vrotl_optab
;
1253 else if (binoptab
== rotr_optab
)
1254 otheroptab
= vrotr_optab
;
1257 && (icode
= optab_handler (otheroptab
, mode
)) != CODE_FOR_nothing
)
1259 /* The scalar may have been extended to be too wide. Truncate
1260 it back to the proper size to fit in the broadcast vector. */
1261 scalar_mode inner_mode
= GET_MODE_INNER (mode
);
1262 if (!CONST_INT_P (op1
)
1263 && (GET_MODE_BITSIZE (as_a
<scalar_int_mode
> (GET_MODE (op1
)))
1264 > GET_MODE_BITSIZE (inner_mode
)))
1265 op1
= force_reg (inner_mode
,
1266 simplify_gen_unary (TRUNCATE
, inner_mode
, op1
,
1268 rtx vop1
= expand_vector_broadcast (mode
, op1
);
1271 temp
= expand_binop_directly (icode
, mode
, otheroptab
, op0
, vop1
,
1272 target
, unsignedp
, methods
, last
);
1279 /* Look for a wider mode of the same class for which we think we
1280 can open-code the operation. Check for a widening multiply at the
1281 wider mode as well. */
1283 if (CLASS_HAS_WIDER_MODES_P (mclass
)
1284 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
1285 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
1287 machine_mode next_mode
;
1288 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
1289 || (binoptab
== smul_optab
1290 && GET_MODE_WIDER_MODE (wider_mode
).exists (&next_mode
)
1291 && (find_widening_optab_handler ((unsignedp
1293 : smul_widen_optab
),
1295 != CODE_FOR_nothing
)))
1297 rtx xop0
= op0
, xop1
= op1
;
1300 /* For certain integer operations, we need not actually extend
1301 the narrow operands, as long as we will truncate
1302 the results to the same narrowness. */
1304 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1305 || binoptab
== xor_optab
1306 || binoptab
== add_optab
|| binoptab
== sub_optab
1307 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1308 && mclass
== MODE_INT
)
1311 xop0
= avoid_expensive_constant (mode
, binoptab
, 0,
1313 if (binoptab
!= ashl_optab
)
1314 xop1
= avoid_expensive_constant (mode
, binoptab
, 1,
1318 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
1320 /* The second operand of a shift must always be extended. */
1321 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1322 no_extend
&& binoptab
!= ashl_optab
);
1324 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1325 unsignedp
, OPTAB_DIRECT
);
1328 if (mclass
!= MODE_INT
1329 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
1332 target
= gen_reg_rtx (mode
);
1333 convert_move (target
, temp
, 0);
1337 return gen_lowpart (mode
, temp
);
1340 delete_insns_since (last
);
1344 /* If operation is commutative,
1345 try to make the first operand a register.
1346 Even better, try to make it the same as the target.
1347 Also try to make the last operand a constant. */
1348 if (commutative_optab_p (binoptab
)
1349 && swap_commutative_operands_with_target (target
, op0
, op1
))
1350 std::swap (op0
, op1
);
1352 /* These can be done a word at a time. */
1353 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
1354 && is_int_mode (mode
, &int_mode
)
1355 && GET_MODE_SIZE (int_mode
) > UNITS_PER_WORD
1356 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1361 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1362 won't be accurate, so use a new target. */
1366 || !valid_multiword_target_p (target
))
1367 target
= gen_reg_rtx (int_mode
);
1371 /* Do the actual arithmetic. */
1372 for (i
= 0; i
< GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
; i
++)
1374 rtx target_piece
= operand_subword (target
, i
, 1, int_mode
);
1375 rtx x
= expand_binop (word_mode
, binoptab
,
1376 operand_subword_force (op0
, i
, int_mode
),
1377 operand_subword_force (op1
, i
, int_mode
),
1378 target_piece
, unsignedp
, next_methods
);
1383 if (target_piece
!= x
)
1384 emit_move_insn (target_piece
, x
);
1387 insns
= get_insns ();
1390 if (i
== GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
)
1397 /* Synthesize double word shifts from single word shifts. */
1398 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
1399 || binoptab
== ashr_optab
)
1400 && is_int_mode (mode
, &int_mode
)
1401 && (CONST_INT_P (op1
) || optimize_insn_for_speed_p ())
1402 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
1403 && GET_MODE_PRECISION (int_mode
) == GET_MODE_BITSIZE (int_mode
)
1404 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
1405 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1406 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1408 unsigned HOST_WIDE_INT shift_mask
, double_shift_mask
;
1409 scalar_int_mode op1_mode
;
1411 double_shift_mask
= targetm
.shift_truncation_mask (int_mode
);
1412 shift_mask
= targetm
.shift_truncation_mask (word_mode
);
1413 op1_mode
= (GET_MODE (op1
) != VOIDmode
1414 ? as_a
<scalar_int_mode
> (GET_MODE (op1
))
1417 /* Apply the truncation to constant shifts. */
1418 if (double_shift_mask
> 0 && CONST_INT_P (op1
))
1419 op1
= gen_int_mode (INTVAL (op1
) & double_shift_mask
, op1_mode
);
1421 if (op1
== CONST0_RTX (op1_mode
))
1424 /* Make sure that this is a combination that expand_doubleword_shift
1425 can handle. See the comments there for details. */
1426 if (double_shift_mask
== 0
1427 || (shift_mask
== BITS_PER_WORD
- 1
1428 && double_shift_mask
== BITS_PER_WORD
* 2 - 1))
1431 rtx into_target
, outof_target
;
1432 rtx into_input
, outof_input
;
1433 int left_shift
, outof_word
;
1435 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1436 won't be accurate, so use a new target. */
1440 || !valid_multiword_target_p (target
))
1441 target
= gen_reg_rtx (int_mode
);
1445 /* OUTOF_* is the word we are shifting bits away from, and
1446 INTO_* is the word that we are shifting bits towards, thus
1447 they differ depending on the direction of the shift and
1448 WORDS_BIG_ENDIAN. */
1450 left_shift
= binoptab
== ashl_optab
;
1451 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1453 outof_target
= operand_subword (target
, outof_word
, 1, int_mode
);
1454 into_target
= operand_subword (target
, 1 - outof_word
, 1, int_mode
);
1456 outof_input
= operand_subword_force (op0
, outof_word
, int_mode
);
1457 into_input
= operand_subword_force (op0
, 1 - outof_word
, int_mode
);
1459 if (expand_doubleword_shift (op1_mode
, binoptab
,
1460 outof_input
, into_input
, op1
,
1461 outof_target
, into_target
,
1462 unsignedp
, next_methods
, shift_mask
))
1464 insns
= get_insns ();
1474 /* Synthesize double word rotates from single word shifts. */
1475 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
1476 && is_int_mode (mode
, &int_mode
)
1477 && CONST_INT_P (op1
)
1478 && GET_MODE_PRECISION (int_mode
) == 2 * BITS_PER_WORD
1479 && optab_handler (ashl_optab
, word_mode
) != CODE_FOR_nothing
1480 && optab_handler (lshr_optab
, word_mode
) != CODE_FOR_nothing
)
1483 rtx into_target
, outof_target
;
1484 rtx into_input
, outof_input
;
1486 int shift_count
, left_shift
, outof_word
;
1488 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1489 won't be accurate, so use a new target. Do this also if target is not
1490 a REG, first because having a register instead may open optimization
1491 opportunities, and second because if target and op0 happen to be MEMs
1492 designating the same location, we would risk clobbering it too early
1493 in the code sequence we generate below. */
1498 || !valid_multiword_target_p (target
))
1499 target
= gen_reg_rtx (int_mode
);
1503 shift_count
= INTVAL (op1
);
1505 /* OUTOF_* is the word we are shifting bits away from, and
1506 INTO_* is the word that we are shifting bits towards, thus
1507 they differ depending on the direction of the shift and
1508 WORDS_BIG_ENDIAN. */
1510 left_shift
= (binoptab
== rotl_optab
);
1511 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1513 outof_target
= operand_subword (target
, outof_word
, 1, int_mode
);
1514 into_target
= operand_subword (target
, 1 - outof_word
, 1, int_mode
);
1516 outof_input
= operand_subword_force (op0
, outof_word
, int_mode
);
1517 into_input
= operand_subword_force (op0
, 1 - outof_word
, int_mode
);
1519 if (shift_count
== BITS_PER_WORD
)
1521 /* This is just a word swap. */
1522 emit_move_insn (outof_target
, into_input
);
1523 emit_move_insn (into_target
, outof_input
);
1528 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1529 HOST_WIDE_INT first_shift_count
, second_shift_count
;
1530 optab reverse_unsigned_shift
, unsigned_shift
;
1532 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1533 ? lshr_optab
: ashl_optab
);
1535 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1536 ? ashl_optab
: lshr_optab
);
1538 if (shift_count
> BITS_PER_WORD
)
1540 first_shift_count
= shift_count
- BITS_PER_WORD
;
1541 second_shift_count
= 2 * BITS_PER_WORD
- shift_count
;
1545 first_shift_count
= BITS_PER_WORD
- shift_count
;
1546 second_shift_count
= shift_count
;
1548 rtx first_shift_count_rtx
1549 = gen_int_shift_amount (word_mode
, first_shift_count
);
1550 rtx second_shift_count_rtx
1551 = gen_int_shift_amount (word_mode
, second_shift_count
);
1553 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1554 outof_input
, first_shift_count_rtx
,
1555 NULL_RTX
, unsignedp
, next_methods
);
1556 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1557 into_input
, second_shift_count_rtx
,
1558 NULL_RTX
, unsignedp
, next_methods
);
1560 if (into_temp1
!= 0 && into_temp2
!= 0)
1561 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1562 into_target
, unsignedp
, next_methods
);
1566 if (inter
!= 0 && inter
!= into_target
)
1567 emit_move_insn (into_target
, inter
);
1569 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1570 into_input
, first_shift_count_rtx
,
1571 NULL_RTX
, unsignedp
, next_methods
);
1572 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1573 outof_input
, second_shift_count_rtx
,
1574 NULL_RTX
, unsignedp
, next_methods
);
1576 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1577 inter
= expand_binop (word_mode
, ior_optab
,
1578 outof_temp1
, outof_temp2
,
1579 outof_target
, unsignedp
, next_methods
);
1581 if (inter
!= 0 && inter
!= outof_target
)
1582 emit_move_insn (outof_target
, inter
);
1585 insns
= get_insns ();
1595 /* These can be done a word at a time by propagating carries. */
1596 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1597 && is_int_mode (mode
, &int_mode
)
1598 && GET_MODE_SIZE (int_mode
) >= 2 * UNITS_PER_WORD
1599 && optab_handler (binoptab
, word_mode
) != CODE_FOR_nothing
)
1602 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1603 const unsigned int nwords
= GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
;
1604 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1605 rtx xop0
, xop1
, xtarget
;
1607 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1608 value is one of those, use it. Otherwise, use 1 since it is the
1609 one easiest to get. */
1610 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1611 int normalizep
= STORE_FLAG_VALUE
;
1616 /* Prepare the operands. */
1617 xop0
= force_reg (int_mode
, op0
);
1618 xop1
= force_reg (int_mode
, op1
);
1620 xtarget
= gen_reg_rtx (int_mode
);
1622 if (target
== 0 || !REG_P (target
) || !valid_multiword_target_p (target
))
1625 /* Indicate for flow that the entire target reg is being set. */
1627 emit_clobber (xtarget
);
1629 /* Do the actual arithmetic. */
1630 for (i
= 0; i
< nwords
; i
++)
1632 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
1633 rtx target_piece
= operand_subword (xtarget
, index
, 1, int_mode
);
1634 rtx op0_piece
= operand_subword_force (xop0
, index
, int_mode
);
1635 rtx op1_piece
= operand_subword_force (xop1
, index
, int_mode
);
1638 /* Main add/subtract of the input operands. */
1639 x
= expand_binop (word_mode
, binoptab
,
1640 op0_piece
, op1_piece
,
1641 target_piece
, unsignedp
, next_methods
);
1647 /* Store carry from main add/subtract. */
1648 carry_out
= gen_reg_rtx (word_mode
);
1649 carry_out
= emit_store_flag_force (carry_out
,
1650 (binoptab
== add_optab
1653 word_mode
, 1, normalizep
);
1660 /* Add/subtract previous carry to main result. */
1661 newx
= expand_binop (word_mode
,
1662 normalizep
== 1 ? binoptab
: otheroptab
,
1664 NULL_RTX
, 1, next_methods
);
1668 /* Get out carry from adding/subtracting carry in. */
1669 rtx carry_tmp
= gen_reg_rtx (word_mode
);
1670 carry_tmp
= emit_store_flag_force (carry_tmp
,
1671 (binoptab
== add_optab
1674 word_mode
, 1, normalizep
);
1676 /* Logical-ior the two poss. carry together. */
1677 carry_out
= expand_binop (word_mode
, ior_optab
,
1678 carry_out
, carry_tmp
,
1679 carry_out
, 0, next_methods
);
1683 emit_move_insn (target_piece
, newx
);
1687 if (x
!= target_piece
)
1688 emit_move_insn (target_piece
, x
);
1691 carry_in
= carry_out
;
1694 if (i
== GET_MODE_BITSIZE (int_mode
) / (unsigned) BITS_PER_WORD
)
1696 if (optab_handler (mov_optab
, int_mode
) != CODE_FOR_nothing
1697 || ! rtx_equal_p (target
, xtarget
))
1699 rtx_insn
*temp
= emit_move_insn (target
, xtarget
);
1701 set_dst_reg_note (temp
, REG_EQUAL
,
1702 gen_rtx_fmt_ee (optab_to_code (binoptab
),
1703 int_mode
, copy_rtx (xop0
),
1714 delete_insns_since (last
);
1717 /* Attempt to synthesize double word multiplies using a sequence of word
1718 mode multiplications. We first attempt to generate a sequence using a
1719 more efficient unsigned widening multiply, and if that fails we then
1720 try using a signed widening multiply. */
1722 if (binoptab
== smul_optab
1723 && is_int_mode (mode
, &int_mode
)
1724 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
1725 && optab_handler (smul_optab
, word_mode
) != CODE_FOR_nothing
1726 && optab_handler (add_optab
, word_mode
) != CODE_FOR_nothing
)
1728 rtx product
= NULL_RTX
;
1729 if (convert_optab_handler (umul_widen_optab
, int_mode
, word_mode
)
1730 != CODE_FOR_nothing
)
1732 product
= expand_doubleword_mult (int_mode
, op0
, op1
, target
,
1735 delete_insns_since (last
);
1738 if (product
== NULL_RTX
1739 && (convert_optab_handler (smul_widen_optab
, int_mode
, word_mode
)
1740 != CODE_FOR_nothing
))
1742 product
= expand_doubleword_mult (int_mode
, op0
, op1
, target
,
1745 delete_insns_since (last
);
1748 if (product
!= NULL_RTX
)
1750 if (optab_handler (mov_optab
, int_mode
) != CODE_FOR_nothing
)
1752 rtx_insn
*move
= emit_move_insn (target
? target
: product
,
1754 set_dst_reg_note (move
,
1756 gen_rtx_fmt_ee (MULT
, int_mode
,
1759 target
? target
: product
);
1765 /* It can't be open-coded in this mode.
1766 Use a library call if one is available and caller says that's ok. */
1768 libfunc
= optab_libfunc (binoptab
, mode
);
1770 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1774 machine_mode op1_mode
= mode
;
1779 if (shift_optab_p (binoptab
))
1781 op1_mode
= targetm
.libgcc_shift_count_mode ();
1782 /* Specify unsigned here,
1783 since negative shift counts are meaningless. */
1784 op1x
= convert_to_mode (op1_mode
, op1
, 1);
1787 if (GET_MODE (op0
) != VOIDmode
1788 && GET_MODE (op0
) != mode
)
1789 op0
= convert_to_mode (mode
, op0
, unsignedp
);
1791 /* Pass 1 for NO_QUEUE so we don't lose any increments
1792 if the libcall is cse'd or moved. */
1793 value
= emit_library_call_value (libfunc
,
1794 NULL_RTX
, LCT_CONST
, mode
,
1795 op0
, mode
, op1x
, op1_mode
);
1797 insns
= get_insns ();
1800 bool trapv
= trapv_binoptab_p (binoptab
);
1801 target
= gen_reg_rtx (mode
);
1802 emit_libcall_block_1 (insns
, target
, value
,
1804 : gen_rtx_fmt_ee (optab_to_code (binoptab
),
1805 mode
, op0
, op1
), trapv
);
1810 delete_insns_since (last
);
1812 /* It can't be done in this mode. Can we do it in a wider mode? */
1814 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1815 || methods
== OPTAB_MUST_WIDEN
))
1817 /* Caller says, don't even try. */
1818 delete_insns_since (entry_last
);
1822 /* Compute the value of METHODS to pass to recursive calls.
1823 Don't allow widening to be tried recursively. */
1825 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1827 /* Look for a wider mode of the same class for which it appears we can do
1830 if (CLASS_HAS_WIDER_MODES_P (mclass
))
1832 /* This code doesn't make sense for conversion optabs, since we
1833 wouldn't then want to extend the operands to be the same size
1835 gcc_assert (!convert_optab_p (binoptab
));
1836 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
1838 if (optab_handler (binoptab
, wider_mode
)
1839 || (methods
== OPTAB_LIB
1840 && optab_libfunc (binoptab
, wider_mode
)))
1842 rtx xop0
= op0
, xop1
= op1
;
1845 /* For certain integer operations, we need not actually extend
1846 the narrow operands, as long as we will truncate
1847 the results to the same narrowness. */
1849 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1850 || binoptab
== xor_optab
1851 || binoptab
== add_optab
|| binoptab
== sub_optab
1852 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1853 && mclass
== MODE_INT
)
1856 xop0
= widen_operand (xop0
, wider_mode
, mode
,
1857 unsignedp
, no_extend
);
1859 /* The second operand of a shift must always be extended. */
1860 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1861 no_extend
&& binoptab
!= ashl_optab
);
1863 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1864 unsignedp
, methods
);
1867 if (mclass
!= MODE_INT
1868 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
1871 target
= gen_reg_rtx (mode
);
1872 convert_move (target
, temp
, 0);
1876 return gen_lowpart (mode
, temp
);
1879 delete_insns_since (last
);
1884 delete_insns_since (entry_last
);
1888 /* Expand a binary operator which has both signed and unsigned forms.
1889 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1892 If we widen unsigned operands, we may use a signed wider operation instead
1893 of an unsigned wider operation, since the result would be the same. */
1896 sign_expand_binop (machine_mode mode
, optab uoptab
, optab soptab
,
1897 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
1898 enum optab_methods methods
)
1901 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1904 /* Do it without widening, if possible. */
1905 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1906 unsignedp
, OPTAB_DIRECT
);
1907 if (temp
|| methods
== OPTAB_DIRECT
)
1910 /* Try widening to a signed int. Disable any direct use of any
1911 signed insn in the current mode. */
1912 save_enable
= swap_optab_enable (soptab
, mode
, false);
1914 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
1915 unsignedp
, OPTAB_WIDEN
);
1917 /* For unsigned operands, try widening to an unsigned int. */
1918 if (!temp
&& unsignedp
)
1919 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1920 unsignedp
, OPTAB_WIDEN
);
1921 if (temp
|| methods
== OPTAB_WIDEN
)
1924 /* Use the right width libcall if that exists. */
1925 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1926 unsignedp
, OPTAB_LIB
);
1927 if (temp
|| methods
== OPTAB_LIB
)
1930 /* Must widen and use a libcall, use either signed or unsigned. */
1931 temp
= expand_binop (mode
, soptab
, op0
, op1
, target
,
1932 unsignedp
, methods
);
1933 if (!temp
&& unsignedp
)
1934 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1935 unsignedp
, methods
);
1938 /* Undo the fiddling above. */
1940 swap_optab_enable (soptab
, mode
, true);
1944 /* Generate code to perform an operation specified by UNOPPTAB
1945 on operand OP0, with two results to TARG0 and TARG1.
1946 We assume that the order of the operands for the instruction
1947 is TARG0, TARG1, OP0.
1949 Either TARG0 or TARG1 may be zero, but what that means is that
1950 the result is not actually wanted. We will generate it into
1951 a dummy pseudo-reg and discard it. They may not both be zero.
1953 Returns 1 if this operation can be performed; 0 if not. */
1956 expand_twoval_unop (optab unoptab
, rtx op0
, rtx targ0
, rtx targ1
,
1959 machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1960 enum mode_class mclass
;
1961 machine_mode wider_mode
;
1962 rtx_insn
*entry_last
= get_last_insn ();
1965 mclass
= GET_MODE_CLASS (mode
);
1968 targ0
= gen_reg_rtx (mode
);
1970 targ1
= gen_reg_rtx (mode
);
1972 /* Record where to go back to if we fail. */
1973 last
= get_last_insn ();
1975 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
1977 struct expand_operand ops
[3];
1978 enum insn_code icode
= optab_handler (unoptab
, mode
);
1980 create_fixed_operand (&ops
[0], targ0
);
1981 create_fixed_operand (&ops
[1], targ1
);
1982 create_convert_operand_from (&ops
[2], op0
, mode
, unsignedp
);
1983 if (maybe_expand_insn (icode
, 3, ops
))
1987 /* It can't be done in this mode. Can we do it in a wider mode? */
1989 if (CLASS_HAS_WIDER_MODES_P (mclass
))
1991 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
1993 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
1995 rtx t0
= gen_reg_rtx (wider_mode
);
1996 rtx t1
= gen_reg_rtx (wider_mode
);
1997 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
1999 if (expand_twoval_unop (unoptab
, cop0
, t0
, t1
, unsignedp
))
2001 convert_move (targ0
, t0
, unsignedp
);
2002 convert_move (targ1
, t1
, unsignedp
);
2006 delete_insns_since (last
);
2011 delete_insns_since (entry_last
);
2015 /* Generate code to perform an operation specified by BINOPTAB
2016 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2017 We assume that the order of the operands for the instruction
2018 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2019 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2021 Either TARG0 or TARG1 may be zero, but what that means is that
2022 the result is not actually wanted. We will generate it into
2023 a dummy pseudo-reg and discard it. They may not both be zero.
2025 Returns 1 if this operation can be performed; 0 if not. */
2028 expand_twoval_binop (optab binoptab
, rtx op0
, rtx op1
, rtx targ0
, rtx targ1
,
2031 machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2032 enum mode_class mclass
;
2033 machine_mode wider_mode
;
2034 rtx_insn
*entry_last
= get_last_insn ();
2037 mclass
= GET_MODE_CLASS (mode
);
2040 targ0
= gen_reg_rtx (mode
);
2042 targ1
= gen_reg_rtx (mode
);
2044 /* Record where to go back to if we fail. */
2045 last
= get_last_insn ();
2047 if (optab_handler (binoptab
, mode
) != CODE_FOR_nothing
)
2049 struct expand_operand ops
[4];
2050 enum insn_code icode
= optab_handler (binoptab
, mode
);
2051 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2052 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2053 rtx xop0
= op0
, xop1
= op1
;
2055 /* If we are optimizing, force expensive constants into a register. */
2056 xop0
= avoid_expensive_constant (mode0
, binoptab
, 0, xop0
, unsignedp
);
2057 xop1
= avoid_expensive_constant (mode1
, binoptab
, 1, xop1
, unsignedp
);
2059 create_fixed_operand (&ops
[0], targ0
);
2060 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
2061 create_convert_operand_from (&ops
[2], op1
, mode
, unsignedp
);
2062 create_fixed_operand (&ops
[3], targ1
);
2063 if (maybe_expand_insn (icode
, 4, ops
))
2065 delete_insns_since (last
);
2068 /* It can't be done in this mode. Can we do it in a wider mode? */
2070 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2072 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
2074 if (optab_handler (binoptab
, wider_mode
) != CODE_FOR_nothing
)
2076 rtx t0
= gen_reg_rtx (wider_mode
);
2077 rtx t1
= gen_reg_rtx (wider_mode
);
2078 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2079 rtx cop1
= convert_modes (wider_mode
, mode
, op1
, unsignedp
);
2081 if (expand_twoval_binop (binoptab
, cop0
, cop1
,
2084 convert_move (targ0
, t0
, unsignedp
);
2085 convert_move (targ1
, t1
, unsignedp
);
2089 delete_insns_since (last
);
2094 delete_insns_since (entry_last
);
2098 /* Expand the two-valued library call indicated by BINOPTAB, but
2099 preserve only one of the values. If TARG0 is non-NULL, the first
2100 value is placed into TARG0; otherwise the second value is placed
2101 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2102 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2103 This routine assumes that the value returned by the library call is
2104 as if the return value was of an integral mode twice as wide as the
2105 mode of OP0. Returns 1 if the call was successful. */
2108 expand_twoval_binop_libfunc (optab binoptab
, rtx op0
, rtx op1
,
2109 rtx targ0
, rtx targ1
, enum rtx_code code
)
2112 machine_mode libval_mode
;
2117 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2118 gcc_assert (!targ0
!= !targ1
);
2120 mode
= GET_MODE (op0
);
2121 libfunc
= optab_libfunc (binoptab
, mode
);
2125 /* The value returned by the library function will have twice as
2126 many bits as the nominal MODE. */
2127 libval_mode
= smallest_int_mode_for_size (2 * GET_MODE_BITSIZE (mode
));
2129 libval
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
2133 /* Get the part of VAL containing the value that we want. */
2134 libval
= simplify_gen_subreg (mode
, libval
, libval_mode
,
2135 targ0
? 0 : GET_MODE_SIZE (mode
));
2136 insns
= get_insns ();
2138 /* Move the into the desired location. */
2139 emit_libcall_block (insns
, targ0
? targ0
: targ1
, libval
,
2140 gen_rtx_fmt_ee (code
, mode
, op0
, op1
));
2146 /* Wrapper around expand_unop which takes an rtx code to specify
2147 the operation to perform, not an optab pointer. All other
2148 arguments are the same. */
2150 expand_simple_unop (machine_mode mode
, enum rtx_code code
, rtx op0
,
2151 rtx target
, int unsignedp
)
2153 optab unop
= code_to_optab (code
);
2156 return expand_unop (mode
, unop
, op0
, target
, unsignedp
);
2162 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2164 A similar operation can be used for clrsb. UNOPTAB says which operation
2165 we are trying to expand. */
2167 widen_leading (scalar_int_mode mode
, rtx op0
, rtx target
, optab unoptab
)
2169 opt_scalar_int_mode wider_mode_iter
;
2170 FOR_EACH_WIDER_MODE (wider_mode_iter
, mode
)
2172 scalar_int_mode wider_mode
= wider_mode_iter
.require ();
2173 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2178 last
= get_last_insn ();
2181 target
= gen_reg_rtx (mode
);
2182 xop0
= widen_operand (op0
, wider_mode
, mode
,
2183 unoptab
!= clrsb_optab
, false);
2184 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2185 unoptab
!= clrsb_optab
);
2188 (wider_mode
, sub_optab
, temp
,
2189 gen_int_mode (GET_MODE_PRECISION (wider_mode
)
2190 - GET_MODE_PRECISION (mode
),
2192 target
, true, OPTAB_DIRECT
);
2194 delete_insns_since (last
);
2202 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2203 quantities, choosing which based on whether the high word is nonzero. */
2205 expand_doubleword_clz (scalar_int_mode mode
, rtx op0
, rtx target
)
2207 rtx xop0
= force_reg (mode
, op0
);
2208 rtx subhi
= gen_highpart (word_mode
, xop0
);
2209 rtx sublo
= gen_lowpart (word_mode
, xop0
);
2210 rtx_code_label
*hi0_label
= gen_label_rtx ();
2211 rtx_code_label
*after_label
= gen_label_rtx ();
2215 /* If we were not given a target, use a word_mode register, not a
2216 'mode' register. The result will fit, and nobody is expecting
2217 anything bigger (the return type of __builtin_clz* is int). */
2219 target
= gen_reg_rtx (word_mode
);
2221 /* In any case, write to a word_mode scratch in both branches of the
2222 conditional, so we can ensure there is a single move insn setting
2223 'target' to tag a REG_EQUAL note on. */
2224 result
= gen_reg_rtx (word_mode
);
2228 /* If the high word is not equal to zero,
2229 then clz of the full value is clz of the high word. */
2230 emit_cmp_and_jump_insns (subhi
, CONST0_RTX (word_mode
), EQ
, 0,
2231 word_mode
, true, hi0_label
);
2233 temp
= expand_unop_direct (word_mode
, clz_optab
, subhi
, result
, true);
2238 convert_move (result
, temp
, true);
2240 emit_jump_insn (targetm
.gen_jump (after_label
));
2243 /* Else clz of the full value is clz of the low word plus the number
2244 of bits in the high word. */
2245 emit_label (hi0_label
);
2247 temp
= expand_unop_direct (word_mode
, clz_optab
, sublo
, 0, true);
2250 temp
= expand_binop (word_mode
, add_optab
, temp
,
2251 gen_int_mode (GET_MODE_BITSIZE (word_mode
), word_mode
),
2252 result
, true, OPTAB_DIRECT
);
2256 convert_move (result
, temp
, true);
2258 emit_label (after_label
);
2259 convert_move (target
, result
, true);
2264 add_equal_note (seq
, target
, CLZ
, xop0
, NULL_RTX
, mode
);
2273 /* Try calculating popcount of a double-word quantity as two popcount's of
2274 word-sized quantities and summing up the results. */
2276 expand_doubleword_popcount (scalar_int_mode mode
, rtx op0
, rtx target
)
2283 t0
= expand_unop_direct (word_mode
, popcount_optab
,
2284 operand_subword_force (op0
, 0, mode
), NULL_RTX
,
2286 t1
= expand_unop_direct (word_mode
, popcount_optab
,
2287 operand_subword_force (op0
, 1, mode
), NULL_RTX
,
2295 /* If we were not given a target, use a word_mode register, not a
2296 'mode' register. The result will fit, and nobody is expecting
2297 anything bigger (the return type of __builtin_popcount* is int). */
2299 target
= gen_reg_rtx (word_mode
);
2301 t
= expand_binop (word_mode
, add_optab
, t0
, t1
, target
, 0, OPTAB_DIRECT
);
2306 add_equal_note (seq
, t
, POPCOUNT
, op0
, NULL_RTX
, mode
);
2314 (parity:narrow (low (x) ^ high (x))) */
2316 expand_doubleword_parity (scalar_int_mode mode
, rtx op0
, rtx target
)
2318 rtx t
= expand_binop (word_mode
, xor_optab
,
2319 operand_subword_force (op0
, 0, mode
),
2320 operand_subword_force (op0
, 1, mode
),
2321 NULL_RTX
, 0, OPTAB_DIRECT
);
2322 return expand_unop (word_mode
, parity_optab
, t
, target
, true);
2328 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2330 widen_bswap (scalar_int_mode mode
, rtx op0
, rtx target
)
2334 opt_scalar_int_mode wider_mode_iter
;
2336 FOR_EACH_WIDER_MODE (wider_mode_iter
, mode
)
2337 if (optab_handler (bswap_optab
, wider_mode_iter
.require ())
2338 != CODE_FOR_nothing
)
2341 if (!wider_mode_iter
.exists ())
2344 scalar_int_mode wider_mode
= wider_mode_iter
.require ();
2345 last
= get_last_insn ();
2347 x
= widen_operand (op0
, wider_mode
, mode
, true, true);
2348 x
= expand_unop (wider_mode
, bswap_optab
, x
, NULL_RTX
, true);
2350 gcc_assert (GET_MODE_PRECISION (wider_mode
) == GET_MODE_BITSIZE (wider_mode
)
2351 && GET_MODE_PRECISION (mode
) == GET_MODE_BITSIZE (mode
));
2353 x
= expand_shift (RSHIFT_EXPR
, wider_mode
, x
,
2354 GET_MODE_BITSIZE (wider_mode
)
2355 - GET_MODE_BITSIZE (mode
),
2361 target
= gen_reg_rtx (mode
);
2362 emit_move_insn (target
, gen_lowpart (mode
, x
));
2365 delete_insns_since (last
);
2370 /* Try calculating bswap as two bswaps of two word-sized operands. */
2373 expand_doubleword_bswap (machine_mode mode
, rtx op
, rtx target
)
2377 t1
= expand_unop (word_mode
, bswap_optab
,
2378 operand_subword_force (op
, 0, mode
), NULL_RTX
, true);
2379 t0
= expand_unop (word_mode
, bswap_optab
,
2380 operand_subword_force (op
, 1, mode
), NULL_RTX
, true);
2382 if (target
== 0 || !valid_multiword_target_p (target
))
2383 target
= gen_reg_rtx (mode
);
2385 emit_clobber (target
);
2386 emit_move_insn (operand_subword (target
, 0, 1, mode
), t0
);
2387 emit_move_insn (operand_subword (target
, 1, 1, mode
), t1
);
2392 /* Try calculating (parity x) as (and (popcount x) 1), where
2393 popcount can also be done in a wider mode. */
2395 expand_parity (scalar_int_mode mode
, rtx op0
, rtx target
)
2397 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2398 opt_scalar_int_mode wider_mode_iter
;
2399 FOR_EACH_MODE_FROM (wider_mode_iter
, mode
)
2401 scalar_int_mode wider_mode
= wider_mode_iter
.require ();
2402 if (optab_handler (popcount_optab
, wider_mode
) != CODE_FOR_nothing
)
2407 last
= get_last_insn ();
2409 if (target
== 0 || GET_MODE (target
) != wider_mode
)
2410 target
= gen_reg_rtx (wider_mode
);
2412 xop0
= widen_operand (op0
, wider_mode
, mode
, true, false);
2413 temp
= expand_unop (wider_mode
, popcount_optab
, xop0
, NULL_RTX
,
2416 temp
= expand_binop (wider_mode
, and_optab
, temp
, const1_rtx
,
2417 target
, true, OPTAB_DIRECT
);
2421 if (mclass
!= MODE_INT
2422 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
2423 return convert_to_mode (mode
, temp
, 0);
2425 return gen_lowpart (mode
, temp
);
2428 delete_insns_since (last
);
2434 /* Try calculating ctz(x) as K - clz(x & -x) ,
2435 where K is GET_MODE_PRECISION(mode) - 1.
2437 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2438 don't have to worry about what the hardware does in that case. (If
2439 the clz instruction produces the usual value at 0, which is K, the
2440 result of this code sequence will be -1; expand_ffs, below, relies
2441 on this. It might be nice to have it be K instead, for consistency
2442 with the (very few) processors that provide a ctz with a defined
2443 value, but that would take one more instruction, and it would be
2444 less convenient for expand_ffs anyway. */
2447 expand_ctz (scalar_int_mode mode
, rtx op0
, rtx target
)
2452 if (optab_handler (clz_optab
, mode
) == CODE_FOR_nothing
)
2457 temp
= expand_unop_direct (mode
, neg_optab
, op0
, NULL_RTX
, true);
2459 temp
= expand_binop (mode
, and_optab
, op0
, temp
, NULL_RTX
,
2460 true, OPTAB_DIRECT
);
2462 temp
= expand_unop_direct (mode
, clz_optab
, temp
, NULL_RTX
, true);
2464 temp
= expand_binop (mode
, sub_optab
,
2465 gen_int_mode (GET_MODE_PRECISION (mode
) - 1, mode
),
2467 true, OPTAB_DIRECT
);
2477 add_equal_note (seq
, temp
, CTZ
, op0
, NULL_RTX
, mode
);
2483 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2484 else with the sequence used by expand_clz.
2486 The ffs builtin promises to return zero for a zero value and ctz/clz
2487 may have an undefined value in that case. If they do not give us a
2488 convenient value, we have to generate a test and branch. */
2490 expand_ffs (scalar_int_mode mode
, rtx op0
, rtx target
)
2492 HOST_WIDE_INT val
= 0;
2493 bool defined_at_zero
= false;
2497 if (optab_handler (ctz_optab
, mode
) != CODE_FOR_nothing
)
2501 temp
= expand_unop_direct (mode
, ctz_optab
, op0
, 0, true);
2505 defined_at_zero
= (CTZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2);
2507 else if (optab_handler (clz_optab
, mode
) != CODE_FOR_nothing
)
2510 temp
= expand_ctz (mode
, op0
, 0);
2514 if (CLZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2)
2516 defined_at_zero
= true;
2517 val
= (GET_MODE_PRECISION (mode
) - 1) - val
;
2523 if (defined_at_zero
&& val
== -1)
2524 /* No correction needed at zero. */;
2527 /* We don't try to do anything clever with the situation found
2528 on some processors (eg Alpha) where ctz(0:mode) ==
2529 bitsize(mode). If someone can think of a way to send N to -1
2530 and leave alone all values in the range 0..N-1 (where N is a
2531 power of two), cheaper than this test-and-branch, please add it.
2533 The test-and-branch is done after the operation itself, in case
2534 the operation sets condition codes that can be recycled for this.
2535 (This is true on i386, for instance.) */
2537 rtx_code_label
*nonzero_label
= gen_label_rtx ();
2538 emit_cmp_and_jump_insns (op0
, CONST0_RTX (mode
), NE
, 0,
2539 mode
, true, nonzero_label
);
2541 convert_move (temp
, GEN_INT (-1), false);
2542 emit_label (nonzero_label
);
2545 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2546 to produce a value in the range 0..bitsize. */
2547 temp
= expand_binop (mode
, add_optab
, temp
, gen_int_mode (1, mode
),
2548 target
, false, OPTAB_DIRECT
);
2555 add_equal_note (seq
, temp
, FFS
, op0
, NULL_RTX
, mode
);
2564 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2565 conditions, VAL may already be a SUBREG against which we cannot generate
2566 a further SUBREG. In this case, we expect forcing the value into a
2567 register will work around the situation. */
2570 lowpart_subreg_maybe_copy (machine_mode omode
, rtx val
,
2574 ret
= lowpart_subreg (omode
, val
, imode
);
2577 val
= force_reg (imode
, val
);
2578 ret
= lowpart_subreg (omode
, val
, imode
);
2579 gcc_assert (ret
!= NULL
);
2584 /* Expand a floating point absolute value or negation operation via a
2585 logical operation on the sign bit. */
2588 expand_absneg_bit (enum rtx_code code
, scalar_float_mode mode
,
2589 rtx op0
, rtx target
)
2591 const struct real_format
*fmt
;
2592 int bitpos
, word
, nwords
, i
;
2593 scalar_int_mode imode
;
2597 /* The format has to have a simple sign bit. */
2598 fmt
= REAL_MODE_FORMAT (mode
);
2602 bitpos
= fmt
->signbit_rw
;
2606 /* Don't create negative zeros if the format doesn't support them. */
2607 if (code
== NEG
&& !fmt
->has_signed_zero
)
2610 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
2612 if (!int_mode_for_mode (mode
).exists (&imode
))
2621 if (FLOAT_WORDS_BIG_ENDIAN
)
2622 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
2624 word
= bitpos
/ BITS_PER_WORD
;
2625 bitpos
= bitpos
% BITS_PER_WORD
;
2626 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
2629 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
2635 || (nwords
> 1 && !valid_multiword_target_p (target
)))
2636 target
= gen_reg_rtx (mode
);
2642 for (i
= 0; i
< nwords
; ++i
)
2644 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
2645 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
2649 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2651 immed_wide_int_const (mask
, imode
),
2652 targ_piece
, 1, OPTAB_LIB_WIDEN
);
2653 if (temp
!= targ_piece
)
2654 emit_move_insn (targ_piece
, temp
);
2657 emit_move_insn (targ_piece
, op0_piece
);
2660 insns
= get_insns ();
2667 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2668 gen_lowpart (imode
, op0
),
2669 immed_wide_int_const (mask
, imode
),
2670 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
2671 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
2673 set_dst_reg_note (get_last_insn (), REG_EQUAL
,
2674 gen_rtx_fmt_e (code
, mode
, copy_rtx (op0
)),
2681 /* As expand_unop, but will fail rather than attempt the operation in a
2682 different mode or with a libcall. */
2684 expand_unop_direct (machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
2687 if (optab_handler (unoptab
, mode
) != CODE_FOR_nothing
)
2689 struct expand_operand ops
[2];
2690 enum insn_code icode
= optab_handler (unoptab
, mode
);
2691 rtx_insn
*last
= get_last_insn ();
2694 create_output_operand (&ops
[0], target
, mode
);
2695 create_convert_operand_from (&ops
[1], op0
, mode
, unsignedp
);
2696 pat
= maybe_gen_insn (icode
, 2, ops
);
2699 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
2700 && ! add_equal_note (pat
, ops
[0].value
,
2701 optab_to_code (unoptab
),
2702 ops
[1].value
, NULL_RTX
, mode
))
2704 delete_insns_since (last
);
2705 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
2710 return ops
[0].value
;
2716 /* Generate code to perform an operation specified by UNOPTAB
2717 on operand OP0, with result having machine-mode MODE.
2719 UNSIGNEDP is for the case where we have to widen the operands
2720 to perform the operation. It says to use zero-extension.
2722 If TARGET is nonzero, the value
2723 is generated there, if it is convenient to do so.
2724 In all cases an rtx is returned for the locus of the value;
2725 this may or may not be TARGET. */
2728 expand_unop (machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
2731 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2732 machine_mode wider_mode
;
2733 scalar_int_mode int_mode
;
2734 scalar_float_mode float_mode
;
2738 temp
= expand_unop_direct (mode
, unoptab
, op0
, target
, unsignedp
);
2742 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2744 /* Widening (or narrowing) clz needs special treatment. */
2745 if (unoptab
== clz_optab
)
2747 if (is_a
<scalar_int_mode
> (mode
, &int_mode
))
2749 temp
= widen_leading (int_mode
, op0
, target
, unoptab
);
2753 if (GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
2754 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
2756 temp
= expand_doubleword_clz (int_mode
, op0
, target
);
2765 if (unoptab
== clrsb_optab
)
2767 if (is_a
<scalar_int_mode
> (mode
, &int_mode
))
2769 temp
= widen_leading (int_mode
, op0
, target
, unoptab
);
2776 if (unoptab
== popcount_optab
2777 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
2778 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
2779 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
2780 && optimize_insn_for_speed_p ())
2782 temp
= expand_doubleword_popcount (int_mode
, op0
, target
);
2787 if (unoptab
== parity_optab
2788 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
2789 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
2790 && (optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
2791 || optab_handler (popcount_optab
, word_mode
) != CODE_FOR_nothing
)
2792 && optimize_insn_for_speed_p ())
2794 temp
= expand_doubleword_parity (int_mode
, op0
, target
);
2799 /* Widening (or narrowing) bswap needs special treatment. */
2800 if (unoptab
== bswap_optab
)
2802 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
2803 or ROTATERT. First try these directly; if this fails, then try the
2804 obvious pair of shifts with allowed widening, as this will probably
2805 be always more efficient than the other fallback methods. */
2811 if (optab_handler (rotl_optab
, mode
) != CODE_FOR_nothing
)
2813 temp
= expand_binop (mode
, rotl_optab
, op0
,
2814 gen_int_shift_amount (mode
, 8),
2815 target
, unsignedp
, OPTAB_DIRECT
);
2820 if (optab_handler (rotr_optab
, mode
) != CODE_FOR_nothing
)
2822 temp
= expand_binop (mode
, rotr_optab
, op0
,
2823 gen_int_shift_amount (mode
, 8),
2824 target
, unsignedp
, OPTAB_DIRECT
);
2829 last
= get_last_insn ();
2831 temp1
= expand_binop (mode
, ashl_optab
, op0
,
2832 gen_int_shift_amount (mode
, 8), NULL_RTX
,
2833 unsignedp
, OPTAB_WIDEN
);
2834 temp2
= expand_binop (mode
, lshr_optab
, op0
,
2835 gen_int_shift_amount (mode
, 8), NULL_RTX
,
2836 unsignedp
, OPTAB_WIDEN
);
2839 temp
= expand_binop (mode
, ior_optab
, temp1
, temp2
, target
,
2840 unsignedp
, OPTAB_WIDEN
);
2845 delete_insns_since (last
);
2848 if (is_a
<scalar_int_mode
> (mode
, &int_mode
))
2850 temp
= widen_bswap (int_mode
, op0
, target
);
2854 if (GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
2855 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
2857 temp
= expand_doubleword_bswap (mode
, op0
, target
);
2866 if (CLASS_HAS_WIDER_MODES_P (mclass
))
2867 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
2869 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
)
2872 rtx_insn
*last
= get_last_insn ();
2874 /* For certain operations, we need not actually extend
2875 the narrow operand, as long as we will truncate the
2876 results to the same narrowness. */
2878 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2879 (unoptab
== neg_optab
2880 || unoptab
== one_cmpl_optab
)
2881 && mclass
== MODE_INT
);
2883 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2888 if (mclass
!= MODE_INT
2889 || !TRULY_NOOP_TRUNCATION_MODES_P (mode
, wider_mode
))
2892 target
= gen_reg_rtx (mode
);
2893 convert_move (target
, temp
, 0);
2897 return gen_lowpart (mode
, temp
);
2900 delete_insns_since (last
);
2904 /* These can be done a word at a time. */
2905 if (unoptab
== one_cmpl_optab
2906 && is_int_mode (mode
, &int_mode
)
2907 && GET_MODE_SIZE (int_mode
) > UNITS_PER_WORD
2908 && optab_handler (unoptab
, word_mode
) != CODE_FOR_nothing
)
2913 if (target
== 0 || target
== op0
|| !valid_multiword_target_p (target
))
2914 target
= gen_reg_rtx (int_mode
);
2918 /* Do the actual arithmetic. */
2919 for (i
= 0; i
< GET_MODE_BITSIZE (int_mode
) / BITS_PER_WORD
; i
++)
2921 rtx target_piece
= operand_subword (target
, i
, 1, int_mode
);
2922 rtx x
= expand_unop (word_mode
, unoptab
,
2923 operand_subword_force (op0
, i
, int_mode
),
2924 target_piece
, unsignedp
);
2926 if (target_piece
!= x
)
2927 emit_move_insn (target_piece
, x
);
2930 insns
= get_insns ();
2937 if (optab_to_code (unoptab
) == NEG
)
2939 /* Try negating floating point values by flipping the sign bit. */
2940 if (is_a
<scalar_float_mode
> (mode
, &float_mode
))
2942 temp
= expand_absneg_bit (NEG
, float_mode
, op0
, target
);
2947 /* If there is no negation pattern, and we have no negative zero,
2948 try subtracting from zero. */
2949 if (!HONOR_SIGNED_ZEROS (mode
))
2951 temp
= expand_binop (mode
, (unoptab
== negv_optab
2952 ? subv_optab
: sub_optab
),
2953 CONST0_RTX (mode
), op0
, target
,
2954 unsignedp
, OPTAB_DIRECT
);
2960 /* Try calculating parity (x) as popcount (x) % 2. */
2961 if (unoptab
== parity_optab
&& is_a
<scalar_int_mode
> (mode
, &int_mode
))
2963 temp
= expand_parity (int_mode
, op0
, target
);
2968 /* Try implementing ffs (x) in terms of clz (x). */
2969 if (unoptab
== ffs_optab
&& is_a
<scalar_int_mode
> (mode
, &int_mode
))
2971 temp
= expand_ffs (int_mode
, op0
, target
);
2976 /* Try implementing ctz (x) in terms of clz (x). */
2977 if (unoptab
== ctz_optab
&& is_a
<scalar_int_mode
> (mode
, &int_mode
))
2979 temp
= expand_ctz (int_mode
, op0
, target
);
2985 /* Now try a library call in this mode. */
2986 libfunc
= optab_libfunc (unoptab
, mode
);
2992 machine_mode outmode
= mode
;
2994 /* All of these functions return small values. Thus we choose to
2995 have them return something that isn't a double-word. */
2996 if (unoptab
== ffs_optab
|| unoptab
== clz_optab
|| unoptab
== ctz_optab
2997 || unoptab
== clrsb_optab
|| unoptab
== popcount_optab
2998 || unoptab
== parity_optab
)
3000 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node
),
3001 optab_libfunc (unoptab
, mode
)));
3005 /* Pass 1 for NO_QUEUE so we don't lose any increments
3006 if the libcall is cse'd or moved. */
3007 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, outmode
,
3009 insns
= get_insns ();
3012 target
= gen_reg_rtx (outmode
);
3013 bool trapv
= trapv_unoptab_p (unoptab
);
3015 eq_value
= NULL_RTX
;
3018 eq_value
= gen_rtx_fmt_e (optab_to_code (unoptab
), mode
, op0
);
3019 if (GET_MODE_UNIT_SIZE (outmode
) < GET_MODE_UNIT_SIZE (mode
))
3020 eq_value
= simplify_gen_unary (TRUNCATE
, outmode
, eq_value
, mode
);
3021 else if (GET_MODE_UNIT_SIZE (outmode
) > GET_MODE_UNIT_SIZE (mode
))
3022 eq_value
= simplify_gen_unary (ZERO_EXTEND
,
3023 outmode
, eq_value
, mode
);
3025 emit_libcall_block_1 (insns
, target
, value
, eq_value
, trapv
);
3030 /* It can't be done in this mode. Can we do it in a wider mode? */
3032 if (CLASS_HAS_WIDER_MODES_P (mclass
))
3034 FOR_EACH_WIDER_MODE (wider_mode
, mode
)
3036 if (optab_handler (unoptab
, wider_mode
) != CODE_FOR_nothing
3037 || optab_libfunc (unoptab
, wider_mode
))
3040 rtx_insn
*last
= get_last_insn ();
3042 /* For certain operations, we need not actually extend
3043 the narrow operand, as long as we will truncate the
3044 results to the same narrowness. */
3045 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3046 (unoptab
== neg_optab
3047 || unoptab
== one_cmpl_optab
3048 || unoptab
== bswap_optab
)
3049 && mclass
== MODE_INT
);
3051 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3054 /* If we are generating clz using wider mode, adjust the
3055 result. Similarly for clrsb. */
3056 if ((unoptab
== clz_optab
|| unoptab
== clrsb_optab
)
3059 scalar_int_mode wider_int_mode
3060 = as_a
<scalar_int_mode
> (wider_mode
);
3061 int_mode
= as_a
<scalar_int_mode
> (mode
);
3063 (wider_mode
, sub_optab
, temp
,
3064 gen_int_mode (GET_MODE_PRECISION (wider_int_mode
)
3065 - GET_MODE_PRECISION (int_mode
),
3067 target
, true, OPTAB_DIRECT
);
3070 /* Likewise for bswap. */
3071 if (unoptab
== bswap_optab
&& temp
!= 0)
3073 scalar_int_mode wider_int_mode
3074 = as_a
<scalar_int_mode
> (wider_mode
);
3075 int_mode
= as_a
<scalar_int_mode
> (mode
);
3076 gcc_assert (GET_MODE_PRECISION (wider_int_mode
)
3077 == GET_MODE_BITSIZE (wider_int_mode
)
3078 && GET_MODE_PRECISION (int_mode
)
3079 == GET_MODE_BITSIZE (int_mode
));
3081 temp
= expand_shift (RSHIFT_EXPR
, wider_int_mode
, temp
,
3082 GET_MODE_BITSIZE (wider_int_mode
)
3083 - GET_MODE_BITSIZE (int_mode
),
3089 if (mclass
!= MODE_INT
)
3092 target
= gen_reg_rtx (mode
);
3093 convert_move (target
, temp
, 0);
3097 return gen_lowpart (mode
, temp
);
3100 delete_insns_since (last
);
3105 /* One final attempt at implementing negation via subtraction,
3106 this time allowing widening of the operand. */
3107 if (optab_to_code (unoptab
) == NEG
&& !HONOR_SIGNED_ZEROS (mode
))
3110 temp
= expand_binop (mode
,
3111 unoptab
== negv_optab
? subv_optab
: sub_optab
,
3112 CONST0_RTX (mode
), op0
,
3113 target
, unsignedp
, OPTAB_LIB_WIDEN
);
3121 /* Emit code to compute the absolute value of OP0, with result to
3122 TARGET if convenient. (TARGET may be 0.) The return value says
3123 where the result actually is to be found.
3125 MODE is the mode of the operand; the mode of the result is
3126 different but can be deduced from MODE.
3131 expand_abs_nojump (machine_mode mode
, rtx op0
, rtx target
,
3132 int result_unsignedp
)
3136 if (GET_MODE_CLASS (mode
) != MODE_INT
3138 result_unsignedp
= 1;
3140 /* First try to do it with a special abs instruction. */
3141 temp
= expand_unop (mode
, result_unsignedp
? abs_optab
: absv_optab
,
3146 /* For floating point modes, try clearing the sign bit. */
3147 scalar_float_mode float_mode
;
3148 if (is_a
<scalar_float_mode
> (mode
, &float_mode
))
3150 temp
= expand_absneg_bit (ABS
, float_mode
, op0
, target
);
3155 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3156 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
3157 && !HONOR_SIGNED_ZEROS (mode
))
3159 rtx_insn
*last
= get_last_insn ();
3161 temp
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3164 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3170 delete_insns_since (last
);
3173 /* If this machine has expensive jumps, we can do integer absolute
3174 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3175 where W is the width of MODE. */
3177 scalar_int_mode int_mode
;
3178 if (is_int_mode (mode
, &int_mode
)
3179 && BRANCH_COST (optimize_insn_for_speed_p (),
3182 rtx extended
= expand_shift (RSHIFT_EXPR
, int_mode
, op0
,
3183 GET_MODE_PRECISION (int_mode
) - 1,
3186 temp
= expand_binop (int_mode
, xor_optab
, extended
, op0
, target
, 0,
3189 temp
= expand_binop (int_mode
,
3190 result_unsignedp
? sub_optab
: subv_optab
,
3191 temp
, extended
, target
, 0, OPTAB_LIB_WIDEN
);
3201 expand_abs (machine_mode mode
, rtx op0
, rtx target
,
3202 int result_unsignedp
, int safe
)
3205 rtx_code_label
*op1
;
3207 if (GET_MODE_CLASS (mode
) != MODE_INT
3209 result_unsignedp
= 1;
3211 temp
= expand_abs_nojump (mode
, op0
, target
, result_unsignedp
);
3215 /* If that does not win, use conditional jump and negate. */
3217 /* It is safe to use the target if it is the same
3218 as the source if this is also a pseudo register */
3219 if (op0
== target
&& REG_P (op0
)
3220 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
3223 op1
= gen_label_rtx ();
3224 if (target
== 0 || ! safe
3225 || GET_MODE (target
) != mode
3226 || (MEM_P (target
) && MEM_VOLATILE_P (target
))
3228 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
3229 target
= gen_reg_rtx (mode
);
3231 emit_move_insn (target
, op0
);
3234 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
3235 NULL_RTX
, NULL
, op1
,
3236 profile_probability::uninitialized ());
3238 op0
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3241 emit_move_insn (target
, op0
);
3247 /* Emit code to compute the one's complement absolute value of OP0
3248 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3249 (TARGET may be NULL_RTX.) The return value says where the result
3250 actually is to be found.
3252 MODE is the mode of the operand; the mode of the result is
3253 different but can be deduced from MODE. */
3256 expand_one_cmpl_abs_nojump (machine_mode mode
, rtx op0
, rtx target
)
3260 /* Not applicable for floating point modes. */
3261 if (FLOAT_MODE_P (mode
))
3264 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3265 if (optab_handler (smax_optab
, mode
) != CODE_FOR_nothing
)
3267 rtx_insn
*last
= get_last_insn ();
3269 temp
= expand_unop (mode
, one_cmpl_optab
, op0
, NULL_RTX
, 0);
3271 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3277 delete_insns_since (last
);
3280 /* If this machine has expensive jumps, we can do one's complement
3281 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3283 scalar_int_mode int_mode
;
3284 if (is_int_mode (mode
, &int_mode
)
3285 && BRANCH_COST (optimize_insn_for_speed_p (),
3288 rtx extended
= expand_shift (RSHIFT_EXPR
, int_mode
, op0
,
3289 GET_MODE_PRECISION (int_mode
) - 1,
3292 temp
= expand_binop (int_mode
, xor_optab
, extended
, op0
, target
, 0,
3302 /* A subroutine of expand_copysign, perform the copysign operation using the
3303 abs and neg primitives advertised to exist on the target. The assumption
3304 is that we have a split register file, and leaving op0 in fp registers,
3305 and not playing with subregs so much, will help the register allocator. */
3308 expand_copysign_absneg (scalar_float_mode mode
, rtx op0
, rtx op1
, rtx target
,
3309 int bitpos
, bool op0_is_abs
)
3311 scalar_int_mode imode
;
3312 enum insn_code icode
;
3314 rtx_code_label
*label
;
3319 /* Check if the back end provides an insn that handles signbit for the
3321 icode
= optab_handler (signbit_optab
, mode
);
3322 if (icode
!= CODE_FOR_nothing
)
3324 imode
= as_a
<scalar_int_mode
> (insn_data
[(int) icode
].operand
[0].mode
);
3325 sign
= gen_reg_rtx (imode
);
3326 emit_unop_insn (icode
, sign
, op1
, UNKNOWN
);
3330 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3332 if (!int_mode_for_mode (mode
).exists (&imode
))
3334 op1
= gen_lowpart (imode
, op1
);
3341 if (FLOAT_WORDS_BIG_ENDIAN
)
3342 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3344 word
= bitpos
/ BITS_PER_WORD
;
3345 bitpos
= bitpos
% BITS_PER_WORD
;
3346 op1
= operand_subword_force (op1
, word
, mode
);
3349 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3350 sign
= expand_binop (imode
, and_optab
, op1
,
3351 immed_wide_int_const (mask
, imode
),
3352 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3357 op0
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
3364 if (target
== NULL_RTX
)
3365 target
= copy_to_reg (op0
);
3367 emit_move_insn (target
, op0
);
3370 label
= gen_label_rtx ();
3371 emit_cmp_and_jump_insns (sign
, const0_rtx
, EQ
, NULL_RTX
, imode
, 1, label
);
3373 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3374 op0
= simplify_unary_operation (NEG
, mode
, op0
, mode
);
3376 op0
= expand_unop (mode
, neg_optab
, op0
, target
, 0);
3378 emit_move_insn (target
, op0
);
3386 /* A subroutine of expand_copysign, perform the entire copysign operation
3387 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3388 is true if op0 is known to have its sign bit clear. */
3391 expand_copysign_bit (scalar_float_mode mode
, rtx op0
, rtx op1
, rtx target
,
3392 int bitpos
, bool op0_is_abs
)
3394 scalar_int_mode imode
;
3395 int word
, nwords
, i
;
3399 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3401 if (!int_mode_for_mode (mode
).exists (&imode
))
3410 if (FLOAT_WORDS_BIG_ENDIAN
)
3411 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3413 word
= bitpos
/ BITS_PER_WORD
;
3414 bitpos
= bitpos
% BITS_PER_WORD
;
3415 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
3418 wide_int mask
= wi::set_bit_in_zero (bitpos
, GET_MODE_PRECISION (imode
));
3423 || (nwords
> 1 && !valid_multiword_target_p (target
)))
3424 target
= gen_reg_rtx (mode
);
3430 for (i
= 0; i
< nwords
; ++i
)
3432 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
3433 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
3439 = expand_binop (imode
, and_optab
, op0_piece
,
3440 immed_wide_int_const (~mask
, imode
),
3441 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3442 op1
= expand_binop (imode
, and_optab
,
3443 operand_subword_force (op1
, i
, mode
),
3444 immed_wide_int_const (mask
, imode
),
3445 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3447 temp
= expand_binop (imode
, ior_optab
, op0_piece
, op1
,
3448 targ_piece
, 1, OPTAB_LIB_WIDEN
);
3449 if (temp
!= targ_piece
)
3450 emit_move_insn (targ_piece
, temp
);
3453 emit_move_insn (targ_piece
, op0_piece
);
3456 insns
= get_insns ();
3463 op1
= expand_binop (imode
, and_optab
, gen_lowpart (imode
, op1
),
3464 immed_wide_int_const (mask
, imode
),
3465 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3467 op0
= gen_lowpart (imode
, op0
);
3469 op0
= expand_binop (imode
, and_optab
, op0
,
3470 immed_wide_int_const (~mask
, imode
),
3471 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3473 temp
= expand_binop (imode
, ior_optab
, op0
, op1
,
3474 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3475 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3481 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3482 scalar floating point mode. Return NULL if we do not know how to
3483 expand the operation inline. */
3486 expand_copysign (rtx op0
, rtx op1
, rtx target
)
3488 scalar_float_mode mode
;
3489 const struct real_format
*fmt
;
3493 mode
= as_a
<scalar_float_mode
> (GET_MODE (op0
));
3494 gcc_assert (GET_MODE (op1
) == mode
);
3496 /* First try to do it with a special instruction. */
3497 temp
= expand_binop (mode
, copysign_optab
, op0
, op1
,
3498 target
, 0, OPTAB_DIRECT
);
3502 fmt
= REAL_MODE_FORMAT (mode
);
3503 if (fmt
== NULL
|| !fmt
->has_signed_zero
)
3507 if (CONST_DOUBLE_AS_FLOAT_P (op0
))
3509 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0
)))
3510 op0
= simplify_unary_operation (ABS
, mode
, op0
, mode
);
3514 if (fmt
->signbit_ro
>= 0
3515 && (CONST_DOUBLE_AS_FLOAT_P (op0
)
3516 || (optab_handler (neg_optab
, mode
) != CODE_FOR_nothing
3517 && optab_handler (abs_optab
, mode
) != CODE_FOR_nothing
)))
3519 temp
= expand_copysign_absneg (mode
, op0
, op1
, target
,
3520 fmt
->signbit_ro
, op0_is_abs
);
3525 if (fmt
->signbit_rw
< 0)
3527 return expand_copysign_bit (mode
, op0
, op1
, target
,
3528 fmt
->signbit_rw
, op0_is_abs
);
3531 /* Generate an instruction whose insn-code is INSN_CODE,
3532 with two operands: an output TARGET and an input OP0.
3533 TARGET *must* be nonzero, and the output is always stored there.
3534 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3535 the value that is stored into TARGET.
3537 Return false if expansion failed. */
3540 maybe_emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
,
3543 struct expand_operand ops
[2];
3546 create_output_operand (&ops
[0], target
, GET_MODE (target
));
3547 create_input_operand (&ops
[1], op0
, GET_MODE (op0
));
3548 pat
= maybe_gen_insn (icode
, 2, ops
);
3552 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
3554 add_equal_note (pat
, ops
[0].value
, code
, ops
[1].value
, NULL_RTX
,
3559 if (ops
[0].value
!= target
)
3560 emit_move_insn (target
, ops
[0].value
);
3563 /* Generate an instruction whose insn-code is INSN_CODE,
3564 with two operands: an output TARGET and an input OP0.
3565 TARGET *must* be nonzero, and the output is always stored there.
3566 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3567 the value that is stored into TARGET. */
3570 emit_unop_insn (enum insn_code icode
, rtx target
, rtx op0
, enum rtx_code code
)
3572 bool ok
= maybe_emit_unop_insn (icode
, target
, op0
, code
);
3576 struct no_conflict_data
3579 rtx_insn
*first
, *insn
;
3583 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3584 the currently examined clobber / store has to stay in the list of
3585 insns that constitute the actual libcall block. */
3587 no_conflict_move_test (rtx dest
, const_rtx set
, void *p0
)
3589 struct no_conflict_data
*p
= (struct no_conflict_data
*) p0
;
3591 /* If this inns directly contributes to setting the target, it must stay. */
3592 if (reg_overlap_mentioned_p (p
->target
, dest
))
3593 p
->must_stay
= true;
3594 /* If we haven't committed to keeping any other insns in the list yet,
3595 there is nothing more to check. */
3596 else if (p
->insn
== p
->first
)
3598 /* If this insn sets / clobbers a register that feeds one of the insns
3599 already in the list, this insn has to stay too. */
3600 else if (reg_overlap_mentioned_p (dest
, PATTERN (p
->first
))
3601 || (CALL_P (p
->first
) && (find_reg_fusage (p
->first
, USE
, dest
)))
3602 || reg_used_between_p (dest
, p
->first
, p
->insn
)
3603 /* Likewise if this insn depends on a register set by a previous
3604 insn in the list, or if it sets a result (presumably a hard
3605 register) that is set or clobbered by a previous insn.
3606 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3607 SET_DEST perform the former check on the address, and the latter
3608 check on the MEM. */
3609 || (GET_CODE (set
) == SET
3610 && (modified_in_p (SET_SRC (set
), p
->first
)
3611 || modified_in_p (SET_DEST (set
), p
->first
)
3612 || modified_between_p (SET_SRC (set
), p
->first
, p
->insn
)
3613 || modified_between_p (SET_DEST (set
), p
->first
, p
->insn
))))
3614 p
->must_stay
= true;
3618 /* Emit code to make a call to a constant function or a library call.
3620 INSNS is a list containing all insns emitted in the call.
3621 These insns leave the result in RESULT. Our block is to copy RESULT
3622 to TARGET, which is logically equivalent to EQUIV.
3624 We first emit any insns that set a pseudo on the assumption that these are
3625 loading constants into registers; doing so allows them to be safely cse'ed
3626 between blocks. Then we emit all the other insns in the block, followed by
3627 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3628 note with an operand of EQUIV. */
3631 emit_libcall_block_1 (rtx_insn
*insns
, rtx target
, rtx result
, rtx equiv
,
3632 bool equiv_may_trap
)
3634 rtx final_dest
= target
;
3635 rtx_insn
*next
, *last
, *insn
;
3637 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3638 into a MEM later. Protect the libcall block from this change. */
3639 if (! REG_P (target
) || REG_USERVAR_P (target
))
3640 target
= gen_reg_rtx (GET_MODE (target
));
3642 /* If we're using non-call exceptions, a libcall corresponding to an
3643 operation that may trap may also trap. */
3644 /* ??? See the comment in front of make_reg_eh_region_note. */
3645 if (cfun
->can_throw_non_call_exceptions
3646 && (equiv_may_trap
|| may_trap_p (equiv
)))
3648 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3651 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
3654 int lp_nr
= INTVAL (XEXP (note
, 0));
3655 if (lp_nr
== 0 || lp_nr
== INT_MIN
)
3656 remove_note (insn
, note
);
3662 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3663 reg note to indicate that this call cannot throw or execute a nonlocal
3664 goto (unless there is already a REG_EH_REGION note, in which case
3666 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3668 make_reg_eh_region_note_nothrow_nononlocal (insn
);
3671 /* First emit all insns that set pseudos. Remove them from the list as
3672 we go. Avoid insns that set pseudos which were referenced in previous
3673 insns. These can be generated by move_by_pieces, for example,
3674 to update an address. Similarly, avoid insns that reference things
3675 set in previous insns. */
3677 for (insn
= insns
; insn
; insn
= next
)
3679 rtx set
= single_set (insn
);
3681 next
= NEXT_INSN (insn
);
3683 if (set
!= 0 && REG_P (SET_DEST (set
))
3684 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
)
3686 struct no_conflict_data data
;
3688 data
.target
= const0_rtx
;
3692 note_stores (PATTERN (insn
), no_conflict_move_test
, &data
);
3693 if (! data
.must_stay
)
3695 if (PREV_INSN (insn
))
3696 SET_NEXT_INSN (PREV_INSN (insn
)) = next
;
3701 SET_PREV_INSN (next
) = PREV_INSN (insn
);
3707 /* Some ports use a loop to copy large arguments onto the stack.
3708 Don't move anything outside such a loop. */
3713 /* Write the remaining insns followed by the final copy. */
3714 for (insn
= insns
; insn
; insn
= next
)
3716 next
= NEXT_INSN (insn
);
3721 last
= emit_move_insn (target
, result
);
3723 set_dst_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
), target
);
3725 if (final_dest
!= target
)
3726 emit_move_insn (final_dest
, target
);
3730 emit_libcall_block (rtx_insn
*insns
, rtx target
, rtx result
, rtx equiv
)
3732 emit_libcall_block_1 (insns
, target
, result
, equiv
, false);
3735 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3736 PURPOSE describes how this comparison will be used. CODE is the rtx
3737 comparison code we will be using.
3739 ??? Actually, CODE is slightly weaker than that. A target is still
3740 required to implement all of the normal bcc operations, but not
3741 required to implement all (or any) of the unordered bcc operations. */
3744 can_compare_p (enum rtx_code code
, machine_mode mode
,
3745 enum can_compare_purpose purpose
)
3748 test
= gen_rtx_fmt_ee (code
, mode
, const0_rtx
, const0_rtx
);
3751 enum insn_code icode
;
3753 if (purpose
== ccp_jump
3754 && (icode
= optab_handler (cbranch_optab
, mode
)) != CODE_FOR_nothing
3755 && insn_operand_matches (icode
, 0, test
))
3757 if (purpose
== ccp_store_flag
3758 && (icode
= optab_handler (cstore_optab
, mode
)) != CODE_FOR_nothing
3759 && insn_operand_matches (icode
, 1, test
))
3761 if (purpose
== ccp_cmov
3762 && optab_handler (cmov_optab
, mode
) != CODE_FOR_nothing
)
3765 mode
= GET_MODE_WIDER_MODE (mode
).else_void ();
3766 PUT_MODE (test
, mode
);
3768 while (mode
!= VOIDmode
);
3773 /* This function is called when we are going to emit a compare instruction that
3774 compares the values found in X and Y, using the rtl operator COMPARISON.
3776 If they have mode BLKmode, then SIZE specifies the size of both operands.
3778 UNSIGNEDP nonzero says that the operands are unsigned;
3779 this matters if they need to be widened (as given by METHODS).
3781 *PTEST is where the resulting comparison RTX is returned or NULL_RTX
3782 if we failed to produce one.
3784 *PMODE is the mode of the inputs (in case they are const_int).
3786 This function performs all the setup necessary so that the caller only has
3787 to emit a single comparison insn. This setup can involve doing a BLKmode
3788 comparison or emitting a library call to perform the comparison if no insn
3789 is available to handle it.
3790 The values which are passed in through pointers can be modified; the caller
3791 should perform the comparison on the modified values. Constant
3792 comparisons must have already been folded. */
3795 prepare_cmp_insn (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
3796 int unsignedp
, enum optab_methods methods
,
3797 rtx
*ptest
, machine_mode
*pmode
)
3799 machine_mode mode
= *pmode
;
3801 machine_mode cmp_mode
;
3802 enum mode_class mclass
;
3804 /* The other methods are not needed. */
3805 gcc_assert (methods
== OPTAB_DIRECT
|| methods
== OPTAB_WIDEN
3806 || methods
== OPTAB_LIB_WIDEN
);
3808 /* If we are optimizing, force expensive constants into a register. */
3809 if (CONSTANT_P (x
) && optimize
3810 && (rtx_cost (x
, mode
, COMPARE
, 0, optimize_insn_for_speed_p ())
3811 > COSTS_N_INSNS (1)))
3812 x
= force_reg (mode
, x
);
3814 if (CONSTANT_P (y
) && optimize
3815 && (rtx_cost (y
, mode
, COMPARE
, 1, optimize_insn_for_speed_p ())
3816 > COSTS_N_INSNS (1)))
3817 y
= force_reg (mode
, y
);
3820 /* Make sure if we have a canonical comparison. The RTL
3821 documentation states that canonical comparisons are required only
3822 for targets which have cc0. */
3823 gcc_assert (!CONSTANT_P (x
) || CONSTANT_P (y
));
3826 /* Don't let both operands fail to indicate the mode. */
3827 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
3828 x
= force_reg (mode
, x
);
3829 if (mode
== VOIDmode
)
3830 mode
= GET_MODE (x
) != VOIDmode
? GET_MODE (x
) : GET_MODE (y
);
3832 /* Handle all BLKmode compares. */
3834 if (mode
== BLKmode
)
3836 machine_mode result_mode
;
3837 enum insn_code cmp_code
;
3840 = GEN_INT (MIN (MEM_ALIGN (x
), MEM_ALIGN (y
)) / BITS_PER_UNIT
);
3844 /* Try to use a memory block compare insn - either cmpstr
3845 or cmpmem will do. */
3846 opt_scalar_int_mode cmp_mode_iter
;
3847 FOR_EACH_MODE_IN_CLASS (cmp_mode_iter
, MODE_INT
)
3849 scalar_int_mode cmp_mode
= cmp_mode_iter
.require ();
3850 cmp_code
= direct_optab_handler (cmpmem_optab
, cmp_mode
);
3851 if (cmp_code
== CODE_FOR_nothing
)
3852 cmp_code
= direct_optab_handler (cmpstr_optab
, cmp_mode
);
3853 if (cmp_code
== CODE_FOR_nothing
)
3854 cmp_code
= direct_optab_handler (cmpstrn_optab
, cmp_mode
);
3855 if (cmp_code
== CODE_FOR_nothing
)
3858 /* Must make sure the size fits the insn's mode. */
3859 if (CONST_INT_P (size
)
3860 ? UINTVAL (size
) > GET_MODE_MASK (cmp_mode
)
3861 : (GET_MODE_BITSIZE (as_a
<scalar_int_mode
> (GET_MODE (size
)))
3862 > GET_MODE_BITSIZE (cmp_mode
)))
3865 result_mode
= insn_data
[cmp_code
].operand
[0].mode
;
3866 result
= gen_reg_rtx (result_mode
);
3867 size
= convert_to_mode (cmp_mode
, size
, 1);
3868 emit_insn (GEN_FCN (cmp_code
) (result
, x
, y
, size
, opalign
));
3870 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, result
, const0_rtx
);
3871 *pmode
= result_mode
;
3875 if (methods
!= OPTAB_LIB
&& methods
!= OPTAB_LIB_WIDEN
)
3878 /* Otherwise call a library function. */
3879 result
= emit_block_comp_via_libcall (x
, y
, size
);
3883 mode
= TYPE_MODE (integer_type_node
);
3884 methods
= OPTAB_LIB_WIDEN
;
3888 /* Don't allow operands to the compare to trap, as that can put the
3889 compare and branch in different basic blocks. */
3890 if (cfun
->can_throw_non_call_exceptions
)
3893 x
= copy_to_reg (x
);
3895 y
= copy_to_reg (y
);
3898 if (GET_MODE_CLASS (mode
) == MODE_CC
)
3900 enum insn_code icode
= optab_handler (cbranch_optab
, CCmode
);
3901 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
3902 gcc_assert (icode
!= CODE_FOR_nothing
3903 && insn_operand_matches (icode
, 0, test
));
3908 mclass
= GET_MODE_CLASS (mode
);
3909 test
= gen_rtx_fmt_ee (comparison
, VOIDmode
, x
, y
);
3910 FOR_EACH_MODE_FROM (cmp_mode
, mode
)
3912 enum insn_code icode
;
3913 icode
= optab_handler (cbranch_optab
, cmp_mode
);
3914 if (icode
!= CODE_FOR_nothing
3915 && insn_operand_matches (icode
, 0, test
))
3917 rtx_insn
*last
= get_last_insn ();
3918 rtx op0
= prepare_operand (icode
, x
, 1, mode
, cmp_mode
, unsignedp
);
3919 rtx op1
= prepare_operand (icode
, y
, 2, mode
, cmp_mode
, unsignedp
);
3921 && insn_operand_matches (icode
, 1, op0
)
3922 && insn_operand_matches (icode
, 2, op1
))
3924 XEXP (test
, 0) = op0
;
3925 XEXP (test
, 1) = op1
;
3930 delete_insns_since (last
);
3933 if (methods
== OPTAB_DIRECT
|| !CLASS_HAS_WIDER_MODES_P (mclass
))
3937 if (methods
!= OPTAB_LIB_WIDEN
)
3940 if (SCALAR_FLOAT_MODE_P (mode
))
3942 /* Small trick if UNORDERED isn't implemented by the hardware. */
3943 if (comparison
== UNORDERED
&& rtx_equal_p (x
, y
))
3945 prepare_cmp_insn (x
, y
, UNLT
, NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
3951 prepare_float_lib_cmp (x
, y
, comparison
, ptest
, pmode
);
3956 machine_mode ret_mode
;
3958 /* Handle a libcall just for the mode we are using. */
3959 libfunc
= optab_libfunc (cmp_optab
, mode
);
3960 gcc_assert (libfunc
);
3962 /* If we want unsigned, and this mode has a distinct unsigned
3963 comparison routine, use that. */
3966 rtx ulibfunc
= optab_libfunc (ucmp_optab
, mode
);
3971 ret_mode
= targetm
.libgcc_cmp_return_mode ();
3972 result
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
3973 ret_mode
, x
, mode
, y
, mode
);
3975 /* There are two kinds of comparison routines. Biased routines
3976 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3977 of gcc expect that the comparison operation is equivalent
3978 to the modified comparison. For signed comparisons compare the
3979 result against 1 in the biased case, and zero in the unbiased
3980 case. For unsigned comparisons always compare against 1 after
3981 biasing the unbiased result by adding 1. This gives us a way to
3983 The comparisons in the fixed-point helper library are always
3988 if (!TARGET_LIB_INT_CMP_BIASED
&& !ALL_FIXED_POINT_MODE_P (mode
))
3991 x
= plus_constant (ret_mode
, result
, 1);
3997 prepare_cmp_insn (x
, y
, comparison
, NULL_RTX
, unsignedp
, methods
,
4007 /* Before emitting an insn with code ICODE, make sure that X, which is going
4008 to be used for operand OPNUM of the insn, is converted from mode MODE to
4009 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4010 that it is accepted by the operand predicate. Return the new value. */
4013 prepare_operand (enum insn_code icode
, rtx x
, int opnum
, machine_mode mode
,
4014 machine_mode wider_mode
, int unsignedp
)
4016 if (mode
!= wider_mode
)
4017 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
4019 if (!insn_operand_matches (icode
, opnum
, x
))
4021 machine_mode op_mode
= insn_data
[(int) icode
].operand
[opnum
].mode
;
4022 if (reload_completed
)
4024 if (GET_MODE (x
) != op_mode
&& GET_MODE (x
) != VOIDmode
)
4026 x
= copy_to_mode_reg (op_mode
, x
);
4032 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4033 we can do the branch. */
4036 emit_cmp_and_jump_insn_1 (rtx test
, machine_mode mode
, rtx label
,
4037 profile_probability prob
)
4039 machine_mode optab_mode
;
4040 enum mode_class mclass
;
4041 enum insn_code icode
;
4044 mclass
= GET_MODE_CLASS (mode
);
4045 optab_mode
= (mclass
== MODE_CC
) ? CCmode
: mode
;
4046 icode
= optab_handler (cbranch_optab
, optab_mode
);
4048 gcc_assert (icode
!= CODE_FOR_nothing
);
4049 gcc_assert (insn_operand_matches (icode
, 0, test
));
4050 insn
= emit_jump_insn (GEN_FCN (icode
) (test
, XEXP (test
, 0),
4051 XEXP (test
, 1), label
));
4052 if (prob
.initialized_p ()
4053 && profile_status_for_fn (cfun
) != PROFILE_ABSENT
4056 && any_condjump_p (insn
)
4057 && !find_reg_note (insn
, REG_BR_PROB
, 0))
4058 add_reg_br_prob_note (insn
, prob
);
4061 /* Generate code to compare X with Y so that the condition codes are
4062 set and to jump to LABEL if the condition is true. If X is a
4063 constant and Y is not a constant, then the comparison is swapped to
4064 ensure that the comparison RTL has the canonical form.
4066 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4067 need to be widened. UNSIGNEDP is also used to select the proper
4068 branch condition code.
4070 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4072 MODE is the mode of the inputs (in case they are const_int).
4074 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4075 It will be potentially converted into an unsigned variant based on
4076 UNSIGNEDP to select a proper jump instruction.
4078 PROB is the probability of jumping to LABEL. */
4081 emit_cmp_and_jump_insns (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4082 machine_mode mode
, int unsignedp
, rtx label
,
4083 profile_probability prob
)
4085 rtx op0
= x
, op1
= y
;
4088 /* Swap operands and condition to ensure canonical RTL. */
4089 if (swap_commutative_operands_p (x
, y
)
4090 && can_compare_p (swap_condition (comparison
), mode
, ccp_jump
))
4093 comparison
= swap_condition (comparison
);
4096 /* If OP0 is still a constant, then both X and Y must be constants
4097 or the opposite comparison is not supported. Force X into a register
4098 to create canonical RTL. */
4099 if (CONSTANT_P (op0
))
4100 op0
= force_reg (mode
, op0
);
4103 comparison
= unsigned_condition (comparison
);
4105 prepare_cmp_insn (op0
, op1
, comparison
, size
, unsignedp
, OPTAB_LIB_WIDEN
,
4107 emit_cmp_and_jump_insn_1 (test
, mode
, label
, prob
);
4111 /* Emit a library call comparison between floating point X and Y.
4112 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4115 prepare_float_lib_cmp (rtx x
, rtx y
, enum rtx_code comparison
,
4116 rtx
*ptest
, machine_mode
*pmode
)
4118 enum rtx_code swapped
= swap_condition (comparison
);
4119 enum rtx_code reversed
= reverse_condition_maybe_unordered (comparison
);
4120 machine_mode orig_mode
= GET_MODE (x
);
4122 rtx true_rtx
, false_rtx
;
4123 rtx value
, target
, equiv
;
4126 bool reversed_p
= false;
4127 scalar_int_mode cmp_mode
= targetm
.libgcc_cmp_return_mode ();
4129 FOR_EACH_MODE_FROM (mode
, orig_mode
)
4131 if (code_to_optab (comparison
)
4132 && (libfunc
= optab_libfunc (code_to_optab (comparison
), mode
)))
4135 if (code_to_optab (swapped
)
4136 && (libfunc
= optab_libfunc (code_to_optab (swapped
), mode
)))
4139 comparison
= swapped
;
4143 if (code_to_optab (reversed
)
4144 && (libfunc
= optab_libfunc (code_to_optab (reversed
), mode
)))
4146 comparison
= reversed
;
4152 gcc_assert (mode
!= VOIDmode
);
4154 if (mode
!= orig_mode
)
4156 x
= convert_to_mode (mode
, x
, 0);
4157 y
= convert_to_mode (mode
, y
, 0);
4160 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4161 the RTL. The allows the RTL optimizers to delete the libcall if the
4162 condition can be determined at compile-time. */
4163 if (comparison
== UNORDERED
4164 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4166 true_rtx
= const_true_rtx
;
4167 false_rtx
= const0_rtx
;
4174 true_rtx
= const0_rtx
;
4175 false_rtx
= const_true_rtx
;
4179 true_rtx
= const_true_rtx
;
4180 false_rtx
= const0_rtx
;
4184 true_rtx
= const1_rtx
;
4185 false_rtx
= const0_rtx
;
4189 true_rtx
= const0_rtx
;
4190 false_rtx
= constm1_rtx
;
4194 true_rtx
= constm1_rtx
;
4195 false_rtx
= const0_rtx
;
4199 true_rtx
= const0_rtx
;
4200 false_rtx
= const1_rtx
;
4208 if (comparison
== UNORDERED
)
4210 rtx temp
= simplify_gen_relational (NE
, cmp_mode
, mode
, x
, x
);
4211 equiv
= simplify_gen_relational (NE
, cmp_mode
, mode
, y
, y
);
4212 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4213 temp
, const_true_rtx
, equiv
);
4217 equiv
= simplify_gen_relational (comparison
, cmp_mode
, mode
, x
, y
);
4218 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4219 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4220 equiv
, true_rtx
, false_rtx
);
4224 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4225 cmp_mode
, x
, mode
, y
, mode
);
4226 insns
= get_insns ();
4229 target
= gen_reg_rtx (cmp_mode
);
4230 emit_libcall_block (insns
, target
, value
, equiv
);
4232 if (comparison
== UNORDERED
4233 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
)
4235 *ptest
= gen_rtx_fmt_ee (reversed_p
? EQ
: NE
, VOIDmode
, target
, false_rtx
);
4237 *ptest
= gen_rtx_fmt_ee (comparison
, VOIDmode
, target
, const0_rtx
);
4242 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4245 emit_indirect_jump (rtx loc
)
4247 if (!targetm
.have_indirect_jump ())
4248 sorry ("indirect jumps are not available on this target");
4251 struct expand_operand ops
[1];
4252 create_address_operand (&ops
[0], loc
);
4253 expand_jump_insn (targetm
.code_for_indirect_jump
, 1, ops
);
4259 /* Emit a conditional move instruction if the machine supports one for that
4260 condition and machine mode.
4262 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4263 the mode to use should they be constants. If it is VOIDmode, they cannot
4266 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4267 should be stored there. MODE is the mode to use should they be constants.
4268 If it is VOIDmode, they cannot both be constants.
4270 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4271 is not supported. */
4274 emit_conditional_move (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4275 machine_mode cmode
, rtx op2
, rtx op3
,
4276 machine_mode mode
, int unsignedp
)
4280 enum insn_code icode
;
4281 enum rtx_code reversed
;
4283 /* If the two source operands are identical, that's just a move. */
4285 if (rtx_equal_p (op2
, op3
))
4288 target
= gen_reg_rtx (mode
);
4290 emit_move_insn (target
, op3
);
4294 /* If one operand is constant, make it the second one. Only do this
4295 if the other operand is not constant as well. */
4297 if (swap_commutative_operands_p (op0
, op1
))
4299 std::swap (op0
, op1
);
4300 code
= swap_condition (code
);
4303 /* get_condition will prefer to generate LT and GT even if the old
4304 comparison was against zero, so undo that canonicalization here since
4305 comparisons against zero are cheaper. */
4306 if (code
== LT
&& op1
== const1_rtx
)
4307 code
= LE
, op1
= const0_rtx
;
4308 else if (code
== GT
&& op1
== constm1_rtx
)
4309 code
= GE
, op1
= const0_rtx
;
4311 if (cmode
== VOIDmode
)
4312 cmode
= GET_MODE (op0
);
4314 enum rtx_code orig_code
= code
;
4315 bool swapped
= false;
4316 if (swap_commutative_operands_p (op2
, op3
)
4317 && ((reversed
= reversed_comparison_code_parts (code
, op0
, op1
, NULL
))
4320 std::swap (op2
, op3
);
4325 if (mode
== VOIDmode
)
4326 mode
= GET_MODE (op2
);
4328 icode
= direct_optab_handler (movcc_optab
, mode
);
4330 if (icode
== CODE_FOR_nothing
)
4334 target
= gen_reg_rtx (mode
);
4336 for (int pass
= 0; ; pass
++)
4338 code
= unsignedp
? unsigned_condition (code
) : code
;
4339 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4341 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4342 punt and let the caller figure out how best to deal with this
4344 if (COMPARISON_P (comparison
))
4346 saved_pending_stack_adjust save
;
4347 save_pending_stack_adjust (&save
);
4348 last
= get_last_insn ();
4349 do_pending_stack_adjust ();
4350 machine_mode cmpmode
= cmode
;
4351 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4352 GET_CODE (comparison
), NULL_RTX
, unsignedp
,
4353 OPTAB_WIDEN
, &comparison
, &cmpmode
);
4356 struct expand_operand ops
[4];
4358 create_output_operand (&ops
[0], target
, mode
);
4359 create_fixed_operand (&ops
[1], comparison
);
4360 create_input_operand (&ops
[2], op2
, mode
);
4361 create_input_operand (&ops
[3], op3
, mode
);
4362 if (maybe_expand_insn (icode
, 4, ops
))
4364 if (ops
[0].value
!= target
)
4365 convert_move (target
, ops
[0].value
, false);
4369 delete_insns_since (last
);
4370 restore_pending_stack_adjust (&save
);
4376 /* If the preferred op2/op3 order is not usable, retry with other
4377 operand order, perhaps it will expand successfully. */
4380 else if ((reversed
= reversed_comparison_code_parts (orig_code
, op0
, op1
,
4386 std::swap (op2
, op3
);
4391 /* Emit a conditional negate or bitwise complement using the
4392 negcc or notcc optabs if available. Return NULL_RTX if such operations
4393 are not available. Otherwise return the RTX holding the result.
4394 TARGET is the desired destination of the result. COMP is the comparison
4395 on which to negate. If COND is true move into TARGET the negation
4396 or bitwise complement of OP1. Otherwise move OP2 into TARGET.
4397 CODE is either NEG or NOT. MODE is the machine mode in which the
4398 operation is performed. */
4401 emit_conditional_neg_or_complement (rtx target
, rtx_code code
,
4402 machine_mode mode
, rtx cond
, rtx op1
,
4405 optab op
= unknown_optab
;
4408 else if (code
== NOT
)
4413 insn_code icode
= direct_optab_handler (op
, mode
);
4415 if (icode
== CODE_FOR_nothing
)
4419 target
= gen_reg_rtx (mode
);
4421 rtx_insn
*last
= get_last_insn ();
4422 struct expand_operand ops
[4];
4424 create_output_operand (&ops
[0], target
, mode
);
4425 create_fixed_operand (&ops
[1], cond
);
4426 create_input_operand (&ops
[2], op1
, mode
);
4427 create_input_operand (&ops
[3], op2
, mode
);
4429 if (maybe_expand_insn (icode
, 4, ops
))
4431 if (ops
[0].value
!= target
)
4432 convert_move (target
, ops
[0].value
, false);
4436 delete_insns_since (last
);
4440 /* Emit a conditional addition instruction if the machine supports one for that
4441 condition and machine mode.
4443 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4444 the mode to use should they be constants. If it is VOIDmode, they cannot
4447 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4448 should be stored there. MODE is the mode to use should they be constants.
4449 If it is VOIDmode, they cannot both be constants.
4451 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4452 is not supported. */
4455 emit_conditional_add (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4456 machine_mode cmode
, rtx op2
, rtx op3
,
4457 machine_mode mode
, int unsignedp
)
4461 enum insn_code icode
;
4463 /* If one operand is constant, make it the second one. Only do this
4464 if the other operand is not constant as well. */
4466 if (swap_commutative_operands_p (op0
, op1
))
4468 std::swap (op0
, op1
);
4469 code
= swap_condition (code
);
4472 /* get_condition will prefer to generate LT and GT even if the old
4473 comparison was against zero, so undo that canonicalization here since
4474 comparisons against zero are cheaper. */
4475 if (code
== LT
&& op1
== const1_rtx
)
4476 code
= LE
, op1
= const0_rtx
;
4477 else if (code
== GT
&& op1
== constm1_rtx
)
4478 code
= GE
, op1
= const0_rtx
;
4480 if (cmode
== VOIDmode
)
4481 cmode
= GET_MODE (op0
);
4483 if (mode
== VOIDmode
)
4484 mode
= GET_MODE (op2
);
4486 icode
= optab_handler (addcc_optab
, mode
);
4488 if (icode
== CODE_FOR_nothing
)
4492 target
= gen_reg_rtx (mode
);
4494 code
= unsignedp
? unsigned_condition (code
) : code
;
4495 comparison
= simplify_gen_relational (code
, VOIDmode
, cmode
, op0
, op1
);
4497 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4498 return NULL and let the caller figure out how best to deal with this
4500 if (!COMPARISON_P (comparison
))
4503 do_pending_stack_adjust ();
4504 last
= get_last_insn ();
4505 prepare_cmp_insn (XEXP (comparison
, 0), XEXP (comparison
, 1),
4506 GET_CODE (comparison
), NULL_RTX
, unsignedp
, OPTAB_WIDEN
,
4507 &comparison
, &cmode
);
4510 struct expand_operand ops
[4];
4512 create_output_operand (&ops
[0], target
, mode
);
4513 create_fixed_operand (&ops
[1], comparison
);
4514 create_input_operand (&ops
[2], op2
, mode
);
4515 create_input_operand (&ops
[3], op3
, mode
);
4516 if (maybe_expand_insn (icode
, 4, ops
))
4518 if (ops
[0].value
!= target
)
4519 convert_move (target
, ops
[0].value
, false);
4523 delete_insns_since (last
);
4527 /* These functions attempt to generate an insn body, rather than
4528 emitting the insn, but if the gen function already emits them, we
4529 make no attempt to turn them back into naked patterns. */
4531 /* Generate and return an insn body to add Y to X. */
4534 gen_add2_insn (rtx x
, rtx y
)
4536 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (x
));
4538 gcc_assert (insn_operand_matches (icode
, 0, x
));
4539 gcc_assert (insn_operand_matches (icode
, 1, x
));
4540 gcc_assert (insn_operand_matches (icode
, 2, y
));
4542 return GEN_FCN (icode
) (x
, x
, y
);
4545 /* Generate and return an insn body to add r1 and c,
4546 storing the result in r0. */
4549 gen_add3_insn (rtx r0
, rtx r1
, rtx c
)
4551 enum insn_code icode
= optab_handler (add_optab
, GET_MODE (r0
));
4553 if (icode
== CODE_FOR_nothing
4554 || !insn_operand_matches (icode
, 0, r0
)
4555 || !insn_operand_matches (icode
, 1, r1
)
4556 || !insn_operand_matches (icode
, 2, c
))
4559 return GEN_FCN (icode
) (r0
, r1
, c
);
4563 have_add2_insn (rtx x
, rtx y
)
4565 enum insn_code icode
;
4567 gcc_assert (GET_MODE (x
) != VOIDmode
);
4569 icode
= optab_handler (add_optab
, GET_MODE (x
));
4571 if (icode
== CODE_FOR_nothing
)
4574 if (!insn_operand_matches (icode
, 0, x
)
4575 || !insn_operand_matches (icode
, 1, x
)
4576 || !insn_operand_matches (icode
, 2, y
))
4582 /* Generate and return an insn body to add Y to X. */
4585 gen_addptr3_insn (rtx x
, rtx y
, rtx z
)
4587 enum insn_code icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
4589 gcc_assert (insn_operand_matches (icode
, 0, x
));
4590 gcc_assert (insn_operand_matches (icode
, 1, y
));
4591 gcc_assert (insn_operand_matches (icode
, 2, z
));
4593 return GEN_FCN (icode
) (x
, y
, z
);
4596 /* Return true if the target implements an addptr pattern and X, Y,
4597 and Z are valid for the pattern predicates. */
4600 have_addptr3_insn (rtx x
, rtx y
, rtx z
)
4602 enum insn_code icode
;
4604 gcc_assert (GET_MODE (x
) != VOIDmode
);
4606 icode
= optab_handler (addptr3_optab
, GET_MODE (x
));
4608 if (icode
== CODE_FOR_nothing
)
4611 if (!insn_operand_matches (icode
, 0, x
)
4612 || !insn_operand_matches (icode
, 1, y
)
4613 || !insn_operand_matches (icode
, 2, z
))
4619 /* Generate and return an insn body to subtract Y from X. */
4622 gen_sub2_insn (rtx x
, rtx y
)
4624 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (x
));
4626 gcc_assert (insn_operand_matches (icode
, 0, x
));
4627 gcc_assert (insn_operand_matches (icode
, 1, x
));
4628 gcc_assert (insn_operand_matches (icode
, 2, y
));
4630 return GEN_FCN (icode
) (x
, x
, y
);
4633 /* Generate and return an insn body to subtract r1 and c,
4634 storing the result in r0. */
4637 gen_sub3_insn (rtx r0
, rtx r1
, rtx c
)
4639 enum insn_code icode
= optab_handler (sub_optab
, GET_MODE (r0
));
4641 if (icode
== CODE_FOR_nothing
4642 || !insn_operand_matches (icode
, 0, r0
)
4643 || !insn_operand_matches (icode
, 1, r1
)
4644 || !insn_operand_matches (icode
, 2, c
))
4647 return GEN_FCN (icode
) (r0
, r1
, c
);
4651 have_sub2_insn (rtx x
, rtx y
)
4653 enum insn_code icode
;
4655 gcc_assert (GET_MODE (x
) != VOIDmode
);
4657 icode
= optab_handler (sub_optab
, GET_MODE (x
));
4659 if (icode
== CODE_FOR_nothing
)
4662 if (!insn_operand_matches (icode
, 0, x
)
4663 || !insn_operand_matches (icode
, 1, x
)
4664 || !insn_operand_matches (icode
, 2, y
))
4670 /* Generate the body of an insn to extend Y (with mode MFROM)
4671 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4674 gen_extend_insn (rtx x
, rtx y
, machine_mode mto
,
4675 machine_mode mfrom
, int unsignedp
)
4677 enum insn_code icode
= can_extend_p (mto
, mfrom
, unsignedp
);
4678 return GEN_FCN (icode
) (x
, y
);
4681 /* Generate code to convert FROM to floating point
4682 and store in TO. FROM must be fixed point and not VOIDmode.
4683 UNSIGNEDP nonzero means regard FROM as unsigned.
4684 Normally this is done by correcting the final value
4685 if it is negative. */
4688 expand_float (rtx to
, rtx from
, int unsignedp
)
4690 enum insn_code icode
;
4692 scalar_mode from_mode
, to_mode
;
4693 machine_mode fmode
, imode
;
4694 bool can_do_signed
= false;
4696 /* Crash now, because we won't be able to decide which mode to use. */
4697 gcc_assert (GET_MODE (from
) != VOIDmode
);
4699 /* Look for an insn to do the conversion. Do it in the specified
4700 modes if possible; otherwise convert either input, output or both to
4701 wider mode. If the integer mode is wider than the mode of FROM,
4702 we can do the conversion signed even if the input is unsigned. */
4704 FOR_EACH_MODE_FROM (fmode
, GET_MODE (to
))
4705 FOR_EACH_MODE_FROM (imode
, GET_MODE (from
))
4707 int doing_unsigned
= unsignedp
;
4709 if (fmode
!= GET_MODE (to
)
4710 && (significand_size (fmode
)
4711 < GET_MODE_UNIT_PRECISION (GET_MODE (from
))))
4714 icode
= can_float_p (fmode
, imode
, unsignedp
);
4715 if (icode
== CODE_FOR_nothing
&& unsignedp
)
4717 enum insn_code scode
= can_float_p (fmode
, imode
, 0);
4718 if (scode
!= CODE_FOR_nothing
)
4719 can_do_signed
= true;
4720 if (imode
!= GET_MODE (from
))
4721 icode
= scode
, doing_unsigned
= 0;
4724 if (icode
!= CODE_FOR_nothing
)
4726 if (imode
!= GET_MODE (from
))
4727 from
= convert_to_mode (imode
, from
, unsignedp
);
4729 if (fmode
!= GET_MODE (to
))
4730 target
= gen_reg_rtx (fmode
);
4732 emit_unop_insn (icode
, target
, from
,
4733 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
4736 convert_move (to
, target
, 0);
4741 /* Unsigned integer, and no way to convert directly. Convert as signed,
4742 then unconditionally adjust the result. */
4745 && is_a
<scalar_mode
> (GET_MODE (to
), &to_mode
)
4746 && is_a
<scalar_mode
> (GET_MODE (from
), &from_mode
))
4748 opt_scalar_mode fmode_iter
;
4749 rtx_code_label
*label
= gen_label_rtx ();
4751 REAL_VALUE_TYPE offset
;
4753 /* Look for a usable floating mode FMODE wider than the source and at
4754 least as wide as the target. Using FMODE will avoid rounding woes
4755 with unsigned values greater than the signed maximum value. */
4757 FOR_EACH_MODE_FROM (fmode_iter
, to_mode
)
4759 scalar_mode fmode
= fmode_iter
.require ();
4760 if (GET_MODE_PRECISION (from_mode
) < GET_MODE_BITSIZE (fmode
)
4761 && can_float_p (fmode
, from_mode
, 0) != CODE_FOR_nothing
)
4765 if (!fmode_iter
.exists (&fmode
))
4767 /* There is no such mode. Pretend the target is wide enough. */
4770 /* Avoid double-rounding when TO is narrower than FROM. */
4771 if ((significand_size (fmode
) + 1)
4772 < GET_MODE_PRECISION (from_mode
))
4775 rtx_code_label
*neglabel
= gen_label_rtx ();
4777 /* Don't use TARGET if it isn't a register, is a hard register,
4778 or is the wrong mode. */
4780 || REGNO (target
) < FIRST_PSEUDO_REGISTER
4781 || GET_MODE (target
) != fmode
)
4782 target
= gen_reg_rtx (fmode
);
4785 do_pending_stack_adjust ();
4787 /* Test whether the sign bit is set. */
4788 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
4791 /* The sign bit is not set. Convert as signed. */
4792 expand_float (target
, from
, 0);
4793 emit_jump_insn (targetm
.gen_jump (label
));
4796 /* The sign bit is set.
4797 Convert to a usable (positive signed) value by shifting right
4798 one bit, while remembering if a nonzero bit was shifted
4799 out; i.e., compute (from & 1) | (from >> 1). */
4801 emit_label (neglabel
);
4802 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
4803 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
4804 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, 1, NULL_RTX
, 1);
4805 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
4807 expand_float (target
, temp
, 0);
4809 /* Multiply by 2 to undo the shift above. */
4810 temp
= expand_binop (fmode
, add_optab
, target
, target
,
4811 target
, 0, OPTAB_LIB_WIDEN
);
4813 emit_move_insn (target
, temp
);
4815 do_pending_stack_adjust ();
4821 /* If we are about to do some arithmetic to correct for an
4822 unsigned operand, do it in a pseudo-register. */
4824 if (to_mode
!= fmode
4825 || !REG_P (to
) || REGNO (to
) < FIRST_PSEUDO_REGISTER
)
4826 target
= gen_reg_rtx (fmode
);
4828 /* Convert as signed integer to floating. */
4829 expand_float (target
, from
, 0);
4831 /* If FROM is negative (and therefore TO is negative),
4832 correct its value by 2**bitwidth. */
4834 do_pending_stack_adjust ();
4835 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, from_mode
,
4839 real_2expN (&offset
, GET_MODE_PRECISION (from_mode
), fmode
);
4840 temp
= expand_binop (fmode
, add_optab
, target
,
4841 const_double_from_real_value (offset
, fmode
),
4842 target
, 0, OPTAB_LIB_WIDEN
);
4844 emit_move_insn (target
, temp
);
4846 do_pending_stack_adjust ();
4851 /* No hardware instruction available; call a library routine. */
4856 convert_optab tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
4858 if (is_narrower_int_mode (GET_MODE (from
), SImode
))
4859 from
= convert_to_mode (SImode
, from
, unsignedp
);
4861 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
4862 gcc_assert (libfunc
);
4866 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4867 GET_MODE (to
), from
, GET_MODE (from
));
4868 insns
= get_insns ();
4871 emit_libcall_block (insns
, target
, value
,
4872 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FLOAT
: FLOAT
,
4873 GET_MODE (to
), from
));
4878 /* Copy result to requested destination
4879 if we have been computing in a temp location. */
4883 if (GET_MODE (target
) == GET_MODE (to
))
4884 emit_move_insn (to
, target
);
4886 convert_move (to
, target
, 0);
4890 /* Generate code to convert FROM to fixed point and store in TO. FROM
4891 must be floating point. */
4894 expand_fix (rtx to
, rtx from
, int unsignedp
)
4896 enum insn_code icode
;
4898 machine_mode fmode
, imode
;
4899 opt_scalar_mode fmode_iter
;
4900 bool must_trunc
= false;
4902 /* We first try to find a pair of modes, one real and one integer, at
4903 least as wide as FROM and TO, respectively, in which we can open-code
4904 this conversion. If the integer mode is wider than the mode of TO,
4905 we can do the conversion either signed or unsigned. */
4907 FOR_EACH_MODE_FROM (fmode
, GET_MODE (from
))
4908 FOR_EACH_MODE_FROM (imode
, GET_MODE (to
))
4910 int doing_unsigned
= unsignedp
;
4912 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
4913 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
4914 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
4916 if (icode
!= CODE_FOR_nothing
)
4918 rtx_insn
*last
= get_last_insn ();
4919 if (fmode
!= GET_MODE (from
))
4920 from
= convert_to_mode (fmode
, from
, 0);
4924 rtx temp
= gen_reg_rtx (GET_MODE (from
));
4925 from
= expand_unop (GET_MODE (from
), ftrunc_optab
, from
,
4929 if (imode
!= GET_MODE (to
))
4930 target
= gen_reg_rtx (imode
);
4932 if (maybe_emit_unop_insn (icode
, target
, from
,
4933 doing_unsigned
? UNSIGNED_FIX
: FIX
))
4936 convert_move (to
, target
, unsignedp
);
4939 delete_insns_since (last
);
4943 /* For an unsigned conversion, there is one more way to do it.
4944 If we have a signed conversion, we generate code that compares
4945 the real value to the largest representable positive number. If if
4946 is smaller, the conversion is done normally. Otherwise, subtract
4947 one plus the highest signed number, convert, and add it back.
4949 We only need to check all real modes, since we know we didn't find
4950 anything with a wider integer mode.
4952 This code used to extend FP value into mode wider than the destination.
4953 This is needed for decimal float modes which cannot accurately
4954 represent one plus the highest signed number of the same size, but
4955 not for binary modes. Consider, for instance conversion from SFmode
4958 The hot path through the code is dealing with inputs smaller than 2^63
4959 and doing just the conversion, so there is no bits to lose.
4961 In the other path we know the value is positive in the range 2^63..2^64-1
4962 inclusive. (as for other input overflow happens and result is undefined)
4963 So we know that the most important bit set in mantissa corresponds to
4964 2^63. The subtraction of 2^63 should not generate any rounding as it
4965 simply clears out that bit. The rest is trivial. */
4967 scalar_int_mode to_mode
;
4969 && is_a
<scalar_int_mode
> (GET_MODE (to
), &to_mode
)
4970 && HWI_COMPUTABLE_MODE_P (to_mode
))
4971 FOR_EACH_MODE_FROM (fmode_iter
, as_a
<scalar_mode
> (GET_MODE (from
)))
4973 scalar_mode fmode
= fmode_iter
.require ();
4974 if (CODE_FOR_nothing
!= can_fix_p (to_mode
, fmode
,
4976 && (!DECIMAL_FLOAT_MODE_P (fmode
)
4977 || (GET_MODE_BITSIZE (fmode
) > GET_MODE_PRECISION (to_mode
))))
4980 REAL_VALUE_TYPE offset
;
4982 rtx_code_label
*lab1
, *lab2
;
4985 bitsize
= GET_MODE_PRECISION (to_mode
);
4986 real_2expN (&offset
, bitsize
- 1, fmode
);
4987 limit
= const_double_from_real_value (offset
, fmode
);
4988 lab1
= gen_label_rtx ();
4989 lab2
= gen_label_rtx ();
4991 if (fmode
!= GET_MODE (from
))
4992 from
= convert_to_mode (fmode
, from
, 0);
4994 /* See if we need to do the subtraction. */
4995 do_pending_stack_adjust ();
4996 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
,
4997 GET_MODE (from
), 0, lab1
);
4999 /* If not, do the signed "fix" and branch around fixup code. */
5000 expand_fix (to
, from
, 0);
5001 emit_jump_insn (targetm
.gen_jump (lab2
));
5004 /* Otherwise, subtract 2**(N-1), convert to signed number,
5005 then add 2**(N-1). Do the addition using XOR since this
5006 will often generate better code. */
5008 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
5009 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
5010 expand_fix (to
, target
, 0);
5011 target
= expand_binop (to_mode
, xor_optab
, to
,
5013 (HOST_WIDE_INT_1
<< (bitsize
- 1),
5015 to
, 1, OPTAB_LIB_WIDEN
);
5018 emit_move_insn (to
, target
);
5022 if (optab_handler (mov_optab
, to_mode
) != CODE_FOR_nothing
)
5024 /* Make a place for a REG_NOTE and add it. */
5025 insn
= emit_move_insn (to
, to
);
5026 set_dst_reg_note (insn
, REG_EQUAL
,
5027 gen_rtx_fmt_e (UNSIGNED_FIX
, to_mode
,
5036 /* We can't do it with an insn, so use a library call. But first ensure
5037 that the mode of TO is at least as wide as SImode, since those are the
5038 only library calls we know about. */
5040 if (is_narrower_int_mode (GET_MODE (to
), SImode
))
5042 target
= gen_reg_rtx (SImode
);
5044 expand_fix (target
, from
, unsignedp
);
5052 convert_optab tab
= unsignedp
? ufix_optab
: sfix_optab
;
5053 libfunc
= convert_optab_libfunc (tab
, GET_MODE (to
), GET_MODE (from
));
5054 gcc_assert (libfunc
);
5058 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5059 GET_MODE (to
), from
, GET_MODE (from
));
5060 insns
= get_insns ();
5063 emit_libcall_block (insns
, target
, value
,
5064 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
5065 GET_MODE (to
), from
));
5070 if (GET_MODE (to
) == GET_MODE (target
))
5071 emit_move_insn (to
, target
);
5073 convert_move (to
, target
, 0);
5078 /* Promote integer arguments for a libcall if necessary.
5079 emit_library_call_value cannot do the promotion because it does not
5080 know if it should do a signed or unsigned promotion. This is because
5081 there are no tree types defined for libcalls. */
5084 prepare_libcall_arg (rtx arg
, int uintp
)
5086 scalar_int_mode mode
;
5087 machine_mode arg_mode
;
5088 if (is_a
<scalar_int_mode
> (GET_MODE (arg
), &mode
))
5090 /* If we need to promote the integer function argument we need to do
5091 it here instead of inside emit_library_call_value because in
5092 emit_library_call_value we don't know if we should do a signed or
5093 unsigned promotion. */
5096 arg_mode
= promote_function_mode (NULL_TREE
, mode
,
5097 &unsigned_p
, NULL_TREE
, 0);
5098 if (arg_mode
!= mode
)
5099 return convert_to_mode (arg_mode
, arg
, uintp
);
5104 /* Generate code to convert FROM or TO a fixed-point.
5105 If UINTP is true, either TO or FROM is an unsigned integer.
5106 If SATP is true, we need to saturate the result. */
5109 expand_fixed_convert (rtx to
, rtx from
, int uintp
, int satp
)
5111 machine_mode to_mode
= GET_MODE (to
);
5112 machine_mode from_mode
= GET_MODE (from
);
5114 enum rtx_code this_code
;
5115 enum insn_code code
;
5120 if (to_mode
== from_mode
)
5122 emit_move_insn (to
, from
);
5128 tab
= satp
? satfractuns_optab
: fractuns_optab
;
5129 this_code
= satp
? UNSIGNED_SAT_FRACT
: UNSIGNED_FRACT_CONVERT
;
5133 tab
= satp
? satfract_optab
: fract_optab
;
5134 this_code
= satp
? SAT_FRACT
: FRACT_CONVERT
;
5136 code
= convert_optab_handler (tab
, to_mode
, from_mode
);
5137 if (code
!= CODE_FOR_nothing
)
5139 emit_unop_insn (code
, to
, from
, this_code
);
5143 libfunc
= convert_optab_libfunc (tab
, to_mode
, from_mode
);
5144 gcc_assert (libfunc
);
5146 from
= prepare_libcall_arg (from
, uintp
);
5147 from_mode
= GET_MODE (from
);
5150 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
, to_mode
,
5152 insns
= get_insns ();
5155 emit_libcall_block (insns
, to
, value
,
5156 gen_rtx_fmt_e (optab_to_code (tab
), to_mode
, from
));
5159 /* Generate code to convert FROM to fixed point and store in TO. FROM
5160 must be floating point, TO must be signed. Use the conversion optab
5161 TAB to do the conversion. */
5164 expand_sfix_optab (rtx to
, rtx from
, convert_optab tab
)
5166 enum insn_code icode
;
5168 machine_mode fmode
, imode
;
5170 /* We first try to find a pair of modes, one real and one integer, at
5171 least as wide as FROM and TO, respectively, in which we can open-code
5172 this conversion. If the integer mode is wider than the mode of TO,
5173 we can do the conversion either signed or unsigned. */
5175 FOR_EACH_MODE_FROM (fmode
, GET_MODE (from
))
5176 FOR_EACH_MODE_FROM (imode
, GET_MODE (to
))
5178 icode
= convert_optab_handler (tab
, imode
, fmode
);
5179 if (icode
!= CODE_FOR_nothing
)
5181 rtx_insn
*last
= get_last_insn ();
5182 if (fmode
!= GET_MODE (from
))
5183 from
= convert_to_mode (fmode
, from
, 0);
5185 if (imode
!= GET_MODE (to
))
5186 target
= gen_reg_rtx (imode
);
5188 if (!maybe_emit_unop_insn (icode
, target
, from
, UNKNOWN
))
5190 delete_insns_since (last
);
5194 convert_move (to
, target
, 0);
5202 /* Report whether we have an instruction to perform the operation
5203 specified by CODE on operands of mode MODE. */
5205 have_insn_for (enum rtx_code code
, machine_mode mode
)
5207 return (code_to_optab (code
)
5208 && (optab_handler (code_to_optab (code
), mode
)
5209 != CODE_FOR_nothing
));
5212 /* Print information about the current contents of the optabs on
5216 debug_optab_libfuncs (void)
5220 /* Dump the arithmetic optabs. */
5221 for (i
= FIRST_NORM_OPTAB
; i
<= LAST_NORMLIB_OPTAB
; ++i
)
5222 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
5224 rtx l
= optab_libfunc ((optab
) i
, (machine_mode
) j
);
5227 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
5228 fprintf (stderr
, "%s\t%s:\t%s\n",
5229 GET_RTX_NAME (optab_to_code ((optab
) i
)),
5235 /* Dump the conversion optabs. */
5236 for (i
= FIRST_CONV_OPTAB
; i
<= LAST_CONVLIB_OPTAB
; ++i
)
5237 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
5238 for (k
= 0; k
< NUM_MACHINE_MODES
; ++k
)
5240 rtx l
= convert_optab_libfunc ((optab
) i
, (machine_mode
) j
,
5244 gcc_assert (GET_CODE (l
) == SYMBOL_REF
);
5245 fprintf (stderr
, "%s\t%s\t%s:\t%s\n",
5246 GET_RTX_NAME (optab_to_code ((optab
) i
)),
5254 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5255 CODE. Return 0 on failure. */
5258 gen_cond_trap (enum rtx_code code
, rtx op1
, rtx op2
, rtx tcode
)
5260 machine_mode mode
= GET_MODE (op1
);
5261 enum insn_code icode
;
5265 if (mode
== VOIDmode
)
5268 icode
= optab_handler (ctrap_optab
, mode
);
5269 if (icode
== CODE_FOR_nothing
)
5272 /* Some targets only accept a zero trap code. */
5273 if (!insn_operand_matches (icode
, 3, tcode
))
5276 do_pending_stack_adjust ();
5278 prepare_cmp_insn (op1
, op2
, code
, NULL_RTX
, false, OPTAB_DIRECT
,
5283 insn
= GEN_FCN (icode
) (trap_rtx
, XEXP (trap_rtx
, 0), XEXP (trap_rtx
, 1),
5286 /* If that failed, then give up. */
5294 insn
= get_insns ();
5299 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5300 or unsigned operation code. */
5303 get_rtx_code (enum tree_code tcode
, bool unsignedp
)
5315 code
= unsignedp
? LTU
: LT
;
5318 code
= unsignedp
? LEU
: LE
;
5321 code
= unsignedp
? GTU
: GT
;
5324 code
= unsignedp
? GEU
: GE
;
5327 case UNORDERED_EXPR
:
5366 /* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to
5367 select signed or unsigned operators. OPNO holds the index of the
5368 first comparison operand for insn ICODE. Do not generate the
5369 compare instruction itself. */
5372 vector_compare_rtx (machine_mode cmp_mode
, enum tree_code tcode
,
5373 tree t_op0
, tree t_op1
, bool unsignedp
,
5374 enum insn_code icode
, unsigned int opno
)
5376 struct expand_operand ops
[2];
5377 rtx rtx_op0
, rtx_op1
;
5378 machine_mode m0
, m1
;
5379 enum rtx_code rcode
= get_rtx_code (tcode
, unsignedp
);
5381 gcc_assert (TREE_CODE_CLASS (tcode
) == tcc_comparison
);
5383 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
5384 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
5385 cases, use the original mode. */
5386 rtx_op0
= expand_expr (t_op0
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op0
)),
5388 m0
= GET_MODE (rtx_op0
);
5390 m0
= TYPE_MODE (TREE_TYPE (t_op0
));
5392 rtx_op1
= expand_expr (t_op1
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op1
)),
5394 m1
= GET_MODE (rtx_op1
);
5396 m1
= TYPE_MODE (TREE_TYPE (t_op1
));
5398 create_input_operand (&ops
[0], rtx_op0
, m0
);
5399 create_input_operand (&ops
[1], rtx_op1
, m1
);
5400 if (!maybe_legitimize_operands (icode
, opno
, 2, ops
))
5402 return gen_rtx_fmt_ee (rcode
, cmp_mode
, ops
[0].value
, ops
[1].value
);
5405 /* Check if vec_perm mask SEL is a constant equivalent to a shift of
5406 the first vec_perm operand, assuming the second operand is a constant
5407 vector of zeros. Return the shift distance in bits if so, or NULL_RTX
5408 if the vec_perm is not a shift. MODE is the mode of the value being
5411 shift_amt_for_vec_perm_mask (machine_mode mode
, const vec_perm_indices
&sel
)
5413 unsigned int bitsize
= GET_MODE_UNIT_BITSIZE (mode
);
5414 poly_int64 first
= sel
[0];
5415 if (maybe_ge (sel
[0], GET_MODE_NUNITS (mode
)))
5418 if (!sel
.series_p (0, 1, first
, 1))
5421 if (!GET_MODE_NUNITS (mode
).is_constant (&nelt
))
5423 for (unsigned int i
= 1; i
< nelt
; i
++)
5425 poly_int64 expected
= i
+ first
;
5426 /* Indices into the second vector are all equivalent. */
5427 if (maybe_lt (sel
[i
], nelt
)
5428 ? maybe_ne (sel
[i
], expected
)
5429 : maybe_lt (expected
, nelt
))
5434 return gen_int_shift_amount (mode
, first
* bitsize
);
5437 /* A subroutine of expand_vec_perm_var for expanding one vec_perm insn. */
5440 expand_vec_perm_1 (enum insn_code icode
, rtx target
,
5441 rtx v0
, rtx v1
, rtx sel
)
5443 machine_mode tmode
= GET_MODE (target
);
5444 machine_mode smode
= GET_MODE (sel
);
5445 struct expand_operand ops
[4];
5447 gcc_assert (GET_MODE_CLASS (smode
) == MODE_VECTOR_INT
5448 || mode_for_int_vector (tmode
).require () == smode
);
5449 create_output_operand (&ops
[0], target
, tmode
);
5450 create_input_operand (&ops
[3], sel
, smode
);
5452 /* Make an effort to preserve v0 == v1. The target expander is able to
5453 rely on this to determine if we're permuting a single input operand. */
5454 if (rtx_equal_p (v0
, v1
))
5456 if (!insn_operand_matches (icode
, 1, v0
))
5457 v0
= force_reg (tmode
, v0
);
5458 gcc_checking_assert (insn_operand_matches (icode
, 1, v0
));
5459 gcc_checking_assert (insn_operand_matches (icode
, 2, v0
));
5461 create_fixed_operand (&ops
[1], v0
);
5462 create_fixed_operand (&ops
[2], v0
);
5466 create_input_operand (&ops
[1], v0
, tmode
);
5467 create_input_operand (&ops
[2], v1
, tmode
);
5470 if (maybe_expand_insn (icode
, 4, ops
))
5471 return ops
[0].value
;
5475 /* Implement a permutation of vectors v0 and v1 using the permutation
5476 vector in SEL and return the result. Use TARGET to hold the result
5477 if nonnull and convenient.
5479 MODE is the mode of the vectors being permuted (V0 and V1). SEL_MODE
5480 is the TYPE_MODE associated with SEL, or BLKmode if SEL isn't known
5481 to have a particular mode. */
5484 expand_vec_perm_const (machine_mode mode
, rtx v0
, rtx v1
,
5485 const vec_perm_builder
&sel
, machine_mode sel_mode
,
5488 if (!target
|| !register_operand (target
, mode
))
5489 target
= gen_reg_rtx (mode
);
5491 /* Set QIMODE to a different vector mode with byte elements.
5492 If no such mode, or if MODE already has byte elements, use VOIDmode. */
5493 machine_mode qimode
;
5494 if (!qimode_for_vec_perm (mode
).exists (&qimode
))
5497 rtx_insn
*last
= get_last_insn ();
5499 bool single_arg_p
= rtx_equal_p (v0
, v1
);
5500 /* Always specify two input vectors here and leave the target to handle
5501 cases in which the inputs are equal. Not all backends can cope with
5502 the single-input representation when testing for a double-input
5503 target instruction. */
5504 vec_perm_indices
indices (sel
, 2, GET_MODE_NUNITS (mode
));
5506 /* See if this can be handled with a vec_shr. We only do this if the
5507 second vector is all zeroes. */
5508 insn_code shift_code
= optab_handler (vec_shr_optab
, mode
);
5509 insn_code shift_code_qi
= ((qimode
!= VOIDmode
&& qimode
!= mode
)
5510 ? optab_handler (vec_shr_optab
, qimode
)
5511 : CODE_FOR_nothing
);
5513 if (v1
== CONST0_RTX (GET_MODE (v1
))
5514 && (shift_code
!= CODE_FOR_nothing
5515 || shift_code_qi
!= CODE_FOR_nothing
))
5517 rtx shift_amt
= shift_amt_for_vec_perm_mask (mode
, indices
);
5520 struct expand_operand ops
[3];
5521 if (shift_code
!= CODE_FOR_nothing
)
5523 create_output_operand (&ops
[0], target
, mode
);
5524 create_input_operand (&ops
[1], v0
, mode
);
5525 create_convert_operand_from_type (&ops
[2], shift_amt
, sizetype
);
5526 if (maybe_expand_insn (shift_code
, 3, ops
))
5527 return ops
[0].value
;
5529 if (shift_code_qi
!= CODE_FOR_nothing
)
5531 rtx tmp
= gen_reg_rtx (qimode
);
5532 create_output_operand (&ops
[0], tmp
, qimode
);
5533 create_input_operand (&ops
[1], gen_lowpart (qimode
, v0
), qimode
);
5534 create_convert_operand_from_type (&ops
[2], shift_amt
, sizetype
);
5535 if (maybe_expand_insn (shift_code_qi
, 3, ops
))
5536 return gen_lowpart (mode
, ops
[0].value
);
5541 if (targetm
.vectorize
.vec_perm_const
!= NULL
)
5543 v0
= force_reg (mode
, v0
);
5547 v1
= force_reg (mode
, v1
);
5549 if (targetm
.vectorize
.vec_perm_const (mode
, target
, v0
, v1
, indices
))
5553 /* Fall back to a constant byte-based permutation. */
5554 vec_perm_indices qimode_indices
;
5555 rtx target_qi
= NULL_RTX
, v0_qi
= NULL_RTX
, v1_qi
= NULL_RTX
;
5556 if (qimode
!= VOIDmode
)
5558 qimode_indices
.new_expanded_vector (indices
, GET_MODE_UNIT_SIZE (mode
));
5559 target_qi
= gen_reg_rtx (qimode
);
5560 v0_qi
= gen_lowpart (qimode
, v0
);
5561 v1_qi
= gen_lowpart (qimode
, v1
);
5562 if (targetm
.vectorize
.vec_perm_const
!= NULL
5563 && targetm
.vectorize
.vec_perm_const (qimode
, target_qi
, v0_qi
,
5564 v1_qi
, qimode_indices
))
5565 return gen_lowpart (mode
, target_qi
);
5568 /* Otherwise expand as a fully variable permuation. */
5570 /* The optabs are only defined for selectors with the same width
5571 as the values being permuted. */
5572 machine_mode required_sel_mode
;
5573 if (!mode_for_int_vector (mode
).exists (&required_sel_mode
)
5574 || !VECTOR_MODE_P (required_sel_mode
))
5576 delete_insns_since (last
);
5580 /* We know that it is semantically valid to treat SEL as having SEL_MODE.
5581 If that isn't the mode we want then we need to prove that using
5582 REQUIRED_SEL_MODE is OK. */
5583 if (sel_mode
!= required_sel_mode
)
5585 if (!selector_fits_mode_p (required_sel_mode
, indices
))
5587 delete_insns_since (last
);
5590 sel_mode
= required_sel_mode
;
5593 insn_code icode
= direct_optab_handler (vec_perm_optab
, mode
);
5594 if (icode
!= CODE_FOR_nothing
)
5596 rtx sel_rtx
= vec_perm_indices_to_rtx (sel_mode
, indices
);
5597 rtx tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel_rtx
);
5602 if (qimode
!= VOIDmode
5603 && selector_fits_mode_p (qimode
, qimode_indices
))
5605 icode
= direct_optab_handler (vec_perm_optab
, qimode
);
5606 if (icode
!= CODE_FOR_nothing
)
5608 rtx sel_qi
= vec_perm_indices_to_rtx (qimode
, qimode_indices
);
5609 rtx tmp
= expand_vec_perm_1 (icode
, target_qi
, v0_qi
, v1_qi
, sel_qi
);
5611 return gen_lowpart (mode
, tmp
);
5615 delete_insns_since (last
);
5619 /* Implement a permutation of vectors v0 and v1 using the permutation
5620 vector in SEL and return the result. Use TARGET to hold the result
5621 if nonnull and convenient.
5623 MODE is the mode of the vectors being permuted (V0 and V1).
5624 SEL must have the integer equivalent of MODE and is known to be
5625 unsuitable for permutes with a constant permutation vector. */
5628 expand_vec_perm_var (machine_mode mode
, rtx v0
, rtx v1
, rtx sel
, rtx target
)
5630 enum insn_code icode
;
5634 u
= GET_MODE_UNIT_SIZE (mode
);
5636 if (!target
|| GET_MODE (target
) != mode
)
5637 target
= gen_reg_rtx (mode
);
5639 icode
= direct_optab_handler (vec_perm_optab
, mode
);
5640 if (icode
!= CODE_FOR_nothing
)
5642 tmp
= expand_vec_perm_1 (icode
, target
, v0
, v1
, sel
);
5647 /* As a special case to aid several targets, lower the element-based
5648 permutation to a byte-based permutation and try again. */
5649 machine_mode qimode
;
5650 if (!qimode_for_vec_perm (mode
).exists (&qimode
)
5651 || maybe_gt (GET_MODE_NUNITS (qimode
), GET_MODE_MASK (QImode
) + 1))
5653 icode
= direct_optab_handler (vec_perm_optab
, qimode
);
5654 if (icode
== CODE_FOR_nothing
)
5657 /* Multiply each element by its byte size. */
5658 machine_mode selmode
= GET_MODE (sel
);
5660 sel
= expand_simple_binop (selmode
, PLUS
, sel
, sel
,
5661 NULL
, 0, OPTAB_DIRECT
);
5663 sel
= expand_simple_binop (selmode
, ASHIFT
, sel
,
5664 gen_int_shift_amount (selmode
, exact_log2 (u
)),
5665 NULL
, 0, OPTAB_DIRECT
);
5666 gcc_assert (sel
!= NULL
);
5668 /* Broadcast the low byte each element into each of its bytes.
5669 The encoding has U interleaved stepped patterns, one for each
5670 byte of an element. */
5671 vec_perm_builder
const_sel (GET_MODE_SIZE (mode
), u
, 3);
5672 unsigned int low_byte_in_u
= BYTES_BIG_ENDIAN
? u
- 1 : 0;
5673 for (i
= 0; i
< 3; ++i
)
5674 for (unsigned int j
= 0; j
< u
; ++j
)
5675 const_sel
.quick_push (i
* u
+ low_byte_in_u
);
5676 sel
= gen_lowpart (qimode
, sel
);
5677 sel
= expand_vec_perm_const (qimode
, sel
, sel
, const_sel
, qimode
, NULL
);
5678 gcc_assert (sel
!= NULL
);
5680 /* Add the byte offset to each byte element. */
5681 /* Note that the definition of the indicies here is memory ordering,
5682 so there should be no difference between big and little endian. */
5683 rtx_vector_builder
byte_indices (qimode
, u
, 1);
5684 for (i
= 0; i
< u
; ++i
)
5685 byte_indices
.quick_push (GEN_INT (i
));
5686 tmp
= byte_indices
.build ();
5687 sel_qi
= expand_simple_binop (qimode
, PLUS
, sel
, tmp
,
5688 sel
, 0, OPTAB_DIRECT
);
5689 gcc_assert (sel_qi
!= NULL
);
5691 tmp
= mode
!= qimode
? gen_reg_rtx (qimode
) : target
;
5692 tmp
= expand_vec_perm_1 (icode
, tmp
, gen_lowpart (qimode
, v0
),
5693 gen_lowpart (qimode
, v1
), sel_qi
);
5695 tmp
= gen_lowpart (mode
, tmp
);
5699 /* Generate insns for a VEC_COND_EXPR with mask, given its TYPE and its
5703 expand_vec_cond_mask_expr (tree vec_cond_type
, tree op0
, tree op1
, tree op2
,
5706 struct expand_operand ops
[4];
5707 machine_mode mode
= TYPE_MODE (vec_cond_type
);
5708 machine_mode mask_mode
= TYPE_MODE (TREE_TYPE (op0
));
5709 enum insn_code icode
= get_vcond_mask_icode (mode
, mask_mode
);
5710 rtx mask
, rtx_op1
, rtx_op2
;
5712 if (icode
== CODE_FOR_nothing
)
5715 mask
= expand_normal (op0
);
5716 rtx_op1
= expand_normal (op1
);
5717 rtx_op2
= expand_normal (op2
);
5719 mask
= force_reg (mask_mode
, mask
);
5720 rtx_op1
= force_reg (GET_MODE (rtx_op1
), rtx_op1
);
5722 create_output_operand (&ops
[0], target
, mode
);
5723 create_input_operand (&ops
[1], rtx_op1
, mode
);
5724 create_input_operand (&ops
[2], rtx_op2
, mode
);
5725 create_input_operand (&ops
[3], mask
, mask_mode
);
5726 expand_insn (icode
, 4, ops
);
5728 return ops
[0].value
;
5731 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
5735 expand_vec_cond_expr (tree vec_cond_type
, tree op0
, tree op1
, tree op2
,
5738 struct expand_operand ops
[6];
5739 enum insn_code icode
;
5740 rtx comparison
, rtx_op1
, rtx_op2
;
5741 machine_mode mode
= TYPE_MODE (vec_cond_type
);
5742 machine_mode cmp_op_mode
;
5745 enum tree_code tcode
;
5747 if (COMPARISON_CLASS_P (op0
))
5749 op0a
= TREE_OPERAND (op0
, 0);
5750 op0b
= TREE_OPERAND (op0
, 1);
5751 tcode
= TREE_CODE (op0
);
5755 gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0
)));
5756 if (get_vcond_mask_icode (mode
, TYPE_MODE (TREE_TYPE (op0
)))
5757 != CODE_FOR_nothing
)
5758 return expand_vec_cond_mask_expr (vec_cond_type
, op0
, op1
,
5763 gcc_assert (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (op0
)))
5764 == MODE_VECTOR_INT
);
5766 op0b
= build_zero_cst (TREE_TYPE (op0
));
5770 cmp_op_mode
= TYPE_MODE (TREE_TYPE (op0a
));
5771 unsignedp
= TYPE_UNSIGNED (TREE_TYPE (op0a
));
5774 gcc_assert (known_eq (GET_MODE_SIZE (mode
), GET_MODE_SIZE (cmp_op_mode
))
5775 && known_eq (GET_MODE_NUNITS (mode
),
5776 GET_MODE_NUNITS (cmp_op_mode
)));
5778 icode
= get_vcond_icode (mode
, cmp_op_mode
, unsignedp
);
5779 if (icode
== CODE_FOR_nothing
)
5781 if (tcode
== EQ_EXPR
|| tcode
== NE_EXPR
)
5782 icode
= get_vcond_eq_icode (mode
, cmp_op_mode
);
5783 if (icode
== CODE_FOR_nothing
)
5787 comparison
= vector_compare_rtx (VOIDmode
, tcode
, op0a
, op0b
, unsignedp
,
5789 rtx_op1
= expand_normal (op1
);
5790 rtx_op2
= expand_normal (op2
);
5792 create_output_operand (&ops
[0], target
, mode
);
5793 create_input_operand (&ops
[1], rtx_op1
, mode
);
5794 create_input_operand (&ops
[2], rtx_op2
, mode
);
5795 create_fixed_operand (&ops
[3], comparison
);
5796 create_fixed_operand (&ops
[4], XEXP (comparison
, 0));
5797 create_fixed_operand (&ops
[5], XEXP (comparison
, 1));
5798 expand_insn (icode
, 6, ops
);
5799 return ops
[0].value
;
5802 /* Generate VEC_SERIES_EXPR <OP0, OP1>, returning a value of mode VMODE.
5803 Use TARGET for the result if nonnull and convenient. */
5806 expand_vec_series_expr (machine_mode vmode
, rtx op0
, rtx op1
, rtx target
)
5808 struct expand_operand ops
[3];
5809 enum insn_code icode
;
5810 machine_mode emode
= GET_MODE_INNER (vmode
);
5812 icode
= direct_optab_handler (vec_series_optab
, vmode
);
5813 gcc_assert (icode
!= CODE_FOR_nothing
);
5815 create_output_operand (&ops
[0], target
, vmode
);
5816 create_input_operand (&ops
[1], op0
, emode
);
5817 create_input_operand (&ops
[2], op1
, emode
);
5819 expand_insn (icode
, 3, ops
);
5820 return ops
[0].value
;
5823 /* Generate insns for a vector comparison into a mask. */
5826 expand_vec_cmp_expr (tree type
, tree exp
, rtx target
)
5828 struct expand_operand ops
[4];
5829 enum insn_code icode
;
5831 machine_mode mask_mode
= TYPE_MODE (type
);
5835 enum tree_code tcode
;
5837 op0a
= TREE_OPERAND (exp
, 0);
5838 op0b
= TREE_OPERAND (exp
, 1);
5839 tcode
= TREE_CODE (exp
);
5841 unsignedp
= TYPE_UNSIGNED (TREE_TYPE (op0a
));
5842 vmode
= TYPE_MODE (TREE_TYPE (op0a
));
5844 icode
= get_vec_cmp_icode (vmode
, mask_mode
, unsignedp
);
5845 if (icode
== CODE_FOR_nothing
)
5847 if (tcode
== EQ_EXPR
|| tcode
== NE_EXPR
)
5848 icode
= get_vec_cmp_eq_icode (vmode
, mask_mode
);
5849 if (icode
== CODE_FOR_nothing
)
5853 comparison
= vector_compare_rtx (mask_mode
, tcode
, op0a
, op0b
,
5854 unsignedp
, icode
, 2);
5855 create_output_operand (&ops
[0], target
, mask_mode
);
5856 create_fixed_operand (&ops
[1], comparison
);
5857 create_fixed_operand (&ops
[2], XEXP (comparison
, 0));
5858 create_fixed_operand (&ops
[3], XEXP (comparison
, 1));
5859 expand_insn (icode
, 4, ops
);
5860 return ops
[0].value
;
5863 /* Expand a highpart multiply. */
5866 expand_mult_highpart (machine_mode mode
, rtx op0
, rtx op1
,
5867 rtx target
, bool uns_p
)
5869 struct expand_operand eops
[3];
5870 enum insn_code icode
;
5876 method
= can_mult_highpart_p (mode
, uns_p
);
5882 tab1
= uns_p
? umul_highpart_optab
: smul_highpart_optab
;
5883 return expand_binop (mode
, tab1
, op0
, op1
, target
, uns_p
,
5886 tab1
= uns_p
? vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
5887 tab2
= uns_p
? vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
5890 tab1
= uns_p
? vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
5891 tab2
= uns_p
? vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
5892 if (BYTES_BIG_ENDIAN
)
5893 std::swap (tab1
, tab2
);
5899 icode
= optab_handler (tab1
, mode
);
5900 wmode
= insn_data
[icode
].operand
[0].mode
;
5901 gcc_checking_assert (known_eq (2 * GET_MODE_NUNITS (wmode
),
5902 GET_MODE_NUNITS (mode
)));
5903 gcc_checking_assert (known_eq (GET_MODE_SIZE (wmode
), GET_MODE_SIZE (mode
)));
5905 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
5906 create_input_operand (&eops
[1], op0
, mode
);
5907 create_input_operand (&eops
[2], op1
, mode
);
5908 expand_insn (icode
, 3, eops
);
5909 m1
= gen_lowpart (mode
, eops
[0].value
);
5911 create_output_operand (&eops
[0], gen_reg_rtx (wmode
), wmode
);
5912 create_input_operand (&eops
[1], op0
, mode
);
5913 create_input_operand (&eops
[2], op1
, mode
);
5914 expand_insn (optab_handler (tab2
, mode
), 3, eops
);
5915 m2
= gen_lowpart (mode
, eops
[0].value
);
5917 vec_perm_builder sel
;
5920 /* The encoding has 2 interleaved stepped patterns. */
5921 sel
.new_vector (GET_MODE_NUNITS (mode
), 2, 3);
5922 for (i
= 0; i
< 6; ++i
)
5923 sel
.quick_push (!BYTES_BIG_ENDIAN
+ (i
& ~1)
5924 + ((i
& 1) ? GET_MODE_NUNITS (mode
) : 0));
5928 /* The encoding has a single interleaved stepped pattern. */
5929 sel
.new_vector (GET_MODE_NUNITS (mode
), 1, 3);
5930 for (i
= 0; i
< 3; ++i
)
5931 sel
.quick_push (2 * i
+ (BYTES_BIG_ENDIAN
? 0 : 1));
5934 return expand_vec_perm_const (mode
, m1
, m2
, sel
, BLKmode
, target
);
5937 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
5941 find_cc_set (rtx x
, const_rtx pat
, void *data
)
5943 if (REG_P (x
) && GET_MODE_CLASS (GET_MODE (x
)) == MODE_CC
5944 && GET_CODE (pat
) == SET
)
5946 rtx
*p_cc_reg
= (rtx
*) data
;
5947 gcc_assert (!*p_cc_reg
);
5952 /* This is a helper function for the other atomic operations. This function
5953 emits a loop that contains SEQ that iterates until a compare-and-swap
5954 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5955 a set of instructions that takes a value from OLD_REG as an input and
5956 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5957 set to the current contents of MEM. After SEQ, a compare-and-swap will
5958 attempt to update MEM with NEW_REG. The function returns true when the
5959 loop was generated successfully. */
5962 expand_compare_and_swap_loop (rtx mem
, rtx old_reg
, rtx new_reg
, rtx seq
)
5964 machine_mode mode
= GET_MODE (mem
);
5965 rtx_code_label
*label
;
5966 rtx cmp_reg
, success
, oldval
;
5968 /* The loop we want to generate looks like
5974 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
5978 Note that we only do the plain load from memory once. Subsequent
5979 iterations use the value loaded by the compare-and-swap pattern. */
5981 label
= gen_label_rtx ();
5982 cmp_reg
= gen_reg_rtx (mode
);
5984 emit_move_insn (cmp_reg
, mem
);
5986 emit_move_insn (old_reg
, cmp_reg
);
5992 if (!expand_atomic_compare_and_swap (&success
, &oldval
, mem
, old_reg
,
5993 new_reg
, false, MEMMODEL_SYNC_SEQ_CST
,
5997 if (oldval
!= cmp_reg
)
5998 emit_move_insn (cmp_reg
, oldval
);
6000 /* Mark this jump predicted not taken. */
6001 emit_cmp_and_jump_insns (success
, const0_rtx
, EQ
, const0_rtx
,
6002 GET_MODE (success
), 1, label
,
6003 profile_probability::guessed_never ());
6008 /* This function tries to emit an atomic_exchange intruction. VAL is written
6009 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
6010 using TARGET if possible. */
6013 maybe_emit_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
6015 machine_mode mode
= GET_MODE (mem
);
6016 enum insn_code icode
;
6018 /* If the target supports the exchange directly, great. */
6019 icode
= direct_optab_handler (atomic_exchange_optab
, mode
);
6020 if (icode
!= CODE_FOR_nothing
)
6022 struct expand_operand ops
[4];
6024 create_output_operand (&ops
[0], target
, mode
);
6025 create_fixed_operand (&ops
[1], mem
);
6026 create_input_operand (&ops
[2], val
, mode
);
6027 create_integer_operand (&ops
[3], model
);
6028 if (maybe_expand_insn (icode
, 4, ops
))
6029 return ops
[0].value
;
6035 /* This function tries to implement an atomic exchange operation using
6036 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
6037 The previous contents of *MEM are returned, using TARGET if possible.
6038 Since this instructionn is an acquire barrier only, stronger memory
6039 models may require additional barriers to be emitted. */
6042 maybe_emit_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
,
6043 enum memmodel model
)
6045 machine_mode mode
= GET_MODE (mem
);
6046 enum insn_code icode
;
6047 rtx_insn
*last_insn
= get_last_insn ();
6049 icode
= optab_handler (sync_lock_test_and_set_optab
, mode
);
6051 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
6052 exists, and the memory model is stronger than acquire, add a release
6053 barrier before the instruction. */
6055 if (is_mm_seq_cst (model
) || is_mm_release (model
) || is_mm_acq_rel (model
))
6056 expand_mem_thread_fence (model
);
6058 if (icode
!= CODE_FOR_nothing
)
6060 struct expand_operand ops
[3];
6061 create_output_operand (&ops
[0], target
, mode
);
6062 create_fixed_operand (&ops
[1], mem
);
6063 create_input_operand (&ops
[2], val
, mode
);
6064 if (maybe_expand_insn (icode
, 3, ops
))
6065 return ops
[0].value
;
6068 /* If an external test-and-set libcall is provided, use that instead of
6069 any external compare-and-swap that we might get from the compare-and-
6070 swap-loop expansion later. */
6071 if (!can_compare_and_swap_p (mode
, false))
6073 rtx libfunc
= optab_libfunc (sync_lock_test_and_set_optab
, mode
);
6074 if (libfunc
!= NULL
)
6078 addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
6079 return emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
6080 mode
, addr
, ptr_mode
,
6085 /* If the test_and_set can't be emitted, eliminate any barrier that might
6086 have been emitted. */
6087 delete_insns_since (last_insn
);
6091 /* This function tries to implement an atomic exchange operation using a
6092 compare_and_swap loop. VAL is written to *MEM. The previous contents of
6093 *MEM are returned, using TARGET if possible. No memory model is required
6094 since a compare_and_swap loop is seq-cst. */
6097 maybe_emit_compare_and_swap_exchange_loop (rtx target
, rtx mem
, rtx val
)
6099 machine_mode mode
= GET_MODE (mem
);
6101 if (can_compare_and_swap_p (mode
, true))
6103 if (!target
|| !register_operand (target
, mode
))
6104 target
= gen_reg_rtx (mode
);
6105 if (expand_compare_and_swap_loop (mem
, target
, val
, NULL_RTX
))
6112 /* This function tries to implement an atomic test-and-set operation
6113 using the atomic_test_and_set instruction pattern. A boolean value
6114 is returned from the operation, using TARGET if possible. */
6117 maybe_emit_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
6119 machine_mode pat_bool_mode
;
6120 struct expand_operand ops
[3];
6122 if (!targetm
.have_atomic_test_and_set ())
6125 /* While we always get QImode from __atomic_test_and_set, we get
6126 other memory modes from __sync_lock_test_and_set. Note that we
6127 use no endian adjustment here. This matches the 4.6 behavior
6128 in the Sparc backend. */
6129 enum insn_code icode
= targetm
.code_for_atomic_test_and_set
;
6130 gcc_checking_assert (insn_data
[icode
].operand
[1].mode
== QImode
);
6131 if (GET_MODE (mem
) != QImode
)
6132 mem
= adjust_address_nv (mem
, QImode
, 0);
6134 pat_bool_mode
= insn_data
[icode
].operand
[0].mode
;
6135 create_output_operand (&ops
[0], target
, pat_bool_mode
);
6136 create_fixed_operand (&ops
[1], mem
);
6137 create_integer_operand (&ops
[2], model
);
6139 if (maybe_expand_insn (icode
, 3, ops
))
6140 return ops
[0].value
;
6144 /* This function expands the legacy _sync_lock test_and_set operation which is
6145 generally an atomic exchange. Some limited targets only allow the
6146 constant 1 to be stored. This is an ACQUIRE operation.
6148 TARGET is an optional place to stick the return value.
6149 MEM is where VAL is stored. */
6152 expand_sync_lock_test_and_set (rtx target
, rtx mem
, rtx val
)
6156 /* Try an atomic_exchange first. */
6157 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, MEMMODEL_SYNC_ACQUIRE
);
6161 ret
= maybe_emit_sync_lock_test_and_set (target
, mem
, val
,
6162 MEMMODEL_SYNC_ACQUIRE
);
6166 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
6170 /* If there are no other options, try atomic_test_and_set if the value
6171 being stored is 1. */
6172 if (val
== const1_rtx
)
6173 ret
= maybe_emit_atomic_test_and_set (target
, mem
, MEMMODEL_SYNC_ACQUIRE
);
6178 /* This function expands the atomic test_and_set operation:
6179 atomically store a boolean TRUE into MEM and return the previous value.
6181 MEMMODEL is the memory model variant to use.
6182 TARGET is an optional place to stick the return value. */
6185 expand_atomic_test_and_set (rtx target
, rtx mem
, enum memmodel model
)
6187 machine_mode mode
= GET_MODE (mem
);
6188 rtx ret
, trueval
, subtarget
;
6190 ret
= maybe_emit_atomic_test_and_set (target
, mem
, model
);
6194 /* Be binary compatible with non-default settings of trueval, and different
6195 cpu revisions. E.g. one revision may have atomic-test-and-set, but
6196 another only has atomic-exchange. */
6197 if (targetm
.atomic_test_and_set_trueval
== 1)
6199 trueval
= const1_rtx
;
6200 subtarget
= target
? target
: gen_reg_rtx (mode
);
6204 trueval
= gen_int_mode (targetm
.atomic_test_and_set_trueval
, mode
);
6205 subtarget
= gen_reg_rtx (mode
);
6208 /* Try the atomic-exchange optab... */
6209 ret
= maybe_emit_atomic_exchange (subtarget
, mem
, trueval
, model
);
6211 /* ... then an atomic-compare-and-swap loop ... */
6213 ret
= maybe_emit_compare_and_swap_exchange_loop (subtarget
, mem
, trueval
);
6215 /* ... before trying the vaguely defined legacy lock_test_and_set. */
6217 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, trueval
, model
);
6219 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
6220 things with the value 1. Thus we try again without trueval. */
6221 if (!ret
&& targetm
.atomic_test_and_set_trueval
!= 1)
6222 ret
= maybe_emit_sync_lock_test_and_set (subtarget
, mem
, const1_rtx
, model
);
6224 /* Failing all else, assume a single threaded environment and simply
6225 perform the operation. */
6228 /* If the result is ignored skip the move to target. */
6229 if (subtarget
!= const0_rtx
)
6230 emit_move_insn (subtarget
, mem
);
6232 emit_move_insn (mem
, trueval
);
6236 /* Recall that have to return a boolean value; rectify if trueval
6237 is not exactly one. */
6238 if (targetm
.atomic_test_and_set_trueval
!= 1)
6239 ret
= emit_store_flag_force (target
, NE
, ret
, const0_rtx
, mode
, 0, 1);
6244 /* This function expands the atomic exchange operation:
6245 atomically store VAL in MEM and return the previous value in MEM.
6247 MEMMODEL is the memory model variant to use.
6248 TARGET is an optional place to stick the return value. */
6251 expand_atomic_exchange (rtx target
, rtx mem
, rtx val
, enum memmodel model
)
6253 machine_mode mode
= GET_MODE (mem
);
6256 /* If loads are not atomic for the required size and we are not called to
6257 provide a __sync builtin, do not do anything so that we stay consistent
6258 with atomic loads of the same size. */
6259 if (!can_atomic_load_p (mode
) && !is_mm_sync (model
))
6262 ret
= maybe_emit_atomic_exchange (target
, mem
, val
, model
);
6264 /* Next try a compare-and-swap loop for the exchange. */
6266 ret
= maybe_emit_compare_and_swap_exchange_loop (target
, mem
, val
);
6271 /* This function expands the atomic compare exchange operation:
6273 *PTARGET_BOOL is an optional place to store the boolean success/failure.
6274 *PTARGET_OVAL is an optional place to store the old value from memory.
6275 Both target parameters may be NULL or const0_rtx to indicate that we do
6276 not care about that return value. Both target parameters are updated on
6277 success to the actual location of the corresponding result.
6279 MEMMODEL is the memory model variant to use.
6281 The return value of the function is true for success. */
6284 expand_atomic_compare_and_swap (rtx
*ptarget_bool
, rtx
*ptarget_oval
,
6285 rtx mem
, rtx expected
, rtx desired
,
6286 bool is_weak
, enum memmodel succ_model
,
6287 enum memmodel fail_model
)
6289 machine_mode mode
= GET_MODE (mem
);
6290 struct expand_operand ops
[8];
6291 enum insn_code icode
;
6292 rtx target_oval
, target_bool
= NULL_RTX
;
6295 /* If loads are not atomic for the required size and we are not called to
6296 provide a __sync builtin, do not do anything so that we stay consistent
6297 with atomic loads of the same size. */
6298 if (!can_atomic_load_p (mode
) && !is_mm_sync (succ_model
))
6301 /* Load expected into a register for the compare and swap. */
6302 if (MEM_P (expected
))
6303 expected
= copy_to_reg (expected
);
6305 /* Make sure we always have some place to put the return oldval.
6306 Further, make sure that place is distinct from the input expected,
6307 just in case we need that path down below. */
6308 if (ptarget_oval
&& *ptarget_oval
== const0_rtx
)
6309 ptarget_oval
= NULL
;
6311 if (ptarget_oval
== NULL
6312 || (target_oval
= *ptarget_oval
) == NULL
6313 || reg_overlap_mentioned_p (expected
, target_oval
))
6314 target_oval
= gen_reg_rtx (mode
);
6316 icode
= direct_optab_handler (atomic_compare_and_swap_optab
, mode
);
6317 if (icode
!= CODE_FOR_nothing
)
6319 machine_mode bool_mode
= insn_data
[icode
].operand
[0].mode
;
6321 if (ptarget_bool
&& *ptarget_bool
== const0_rtx
)
6322 ptarget_bool
= NULL
;
6324 /* Make sure we always have a place for the bool operand. */
6325 if (ptarget_bool
== NULL
6326 || (target_bool
= *ptarget_bool
) == NULL
6327 || GET_MODE (target_bool
) != bool_mode
)
6328 target_bool
= gen_reg_rtx (bool_mode
);
6330 /* Emit the compare_and_swap. */
6331 create_output_operand (&ops
[0], target_bool
, bool_mode
);
6332 create_output_operand (&ops
[1], target_oval
, mode
);
6333 create_fixed_operand (&ops
[2], mem
);
6334 create_input_operand (&ops
[3], expected
, mode
);
6335 create_input_operand (&ops
[4], desired
, mode
);
6336 create_integer_operand (&ops
[5], is_weak
);
6337 create_integer_operand (&ops
[6], succ_model
);
6338 create_integer_operand (&ops
[7], fail_model
);
6339 if (maybe_expand_insn (icode
, 8, ops
))
6341 /* Return success/failure. */
6342 target_bool
= ops
[0].value
;
6343 target_oval
= ops
[1].value
;
6348 /* Otherwise fall back to the original __sync_val_compare_and_swap
6349 which is always seq-cst. */
6350 icode
= optab_handler (sync_compare_and_swap_optab
, mode
);
6351 if (icode
!= CODE_FOR_nothing
)
6355 create_output_operand (&ops
[0], target_oval
, mode
);
6356 create_fixed_operand (&ops
[1], mem
);
6357 create_input_operand (&ops
[2], expected
, mode
);
6358 create_input_operand (&ops
[3], desired
, mode
);
6359 if (!maybe_expand_insn (icode
, 4, ops
))
6362 target_oval
= ops
[0].value
;
6364 /* If the caller isn't interested in the boolean return value,
6365 skip the computation of it. */
6366 if (ptarget_bool
== NULL
)
6369 /* Otherwise, work out if the compare-and-swap succeeded. */
6371 if (have_insn_for (COMPARE
, CCmode
))
6372 note_stores (PATTERN (get_last_insn ()), find_cc_set
, &cc_reg
);
6375 target_bool
= emit_store_flag_force (target_bool
, EQ
, cc_reg
,
6376 const0_rtx
, VOIDmode
, 0, 1);
6379 goto success_bool_from_val
;
6382 /* Also check for library support for __sync_val_compare_and_swap. */
6383 libfunc
= optab_libfunc (sync_compare_and_swap_optab
, mode
);
6384 if (libfunc
!= NULL
)
6386 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
6387 rtx target
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_NORMAL
,
6388 mode
, addr
, ptr_mode
,
6389 expected
, mode
, desired
, mode
);
6390 emit_move_insn (target_oval
, target
);
6392 /* Compute the boolean return value only if requested. */
6394 goto success_bool_from_val
;
6402 success_bool_from_val
:
6403 target_bool
= emit_store_flag_force (target_bool
, EQ
, target_oval
,
6404 expected
, VOIDmode
, 1, 1);
6406 /* Make sure that the oval output winds up where the caller asked. */
6408 *ptarget_oval
= target_oval
;
6410 *ptarget_bool
= target_bool
;
6414 /* Generate asm volatile("" : : : "memory") as the memory blockage. */
6417 expand_asm_memory_blockage (void)
6421 asm_op
= gen_rtx_ASM_OPERANDS (VOIDmode
, "", "", 0,
6422 rtvec_alloc (0), rtvec_alloc (0),
6423 rtvec_alloc (0), UNKNOWN_LOCATION
);
6424 MEM_VOLATILE_P (asm_op
) = 1;
6426 clob
= gen_rtx_SCRATCH (VOIDmode
);
6427 clob
= gen_rtx_MEM (BLKmode
, clob
);
6428 clob
= gen_rtx_CLOBBER (VOIDmode
, clob
);
6430 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, asm_op
, clob
)));
6433 /* Do not propagate memory accesses across this point. */
6436 expand_memory_blockage (void)
6438 if (targetm
.have_memory_blockage ())
6439 emit_insn (targetm
.gen_memory_blockage ());
6441 expand_asm_memory_blockage ();
6444 /* This routine will either emit the mem_thread_fence pattern or issue a
6445 sync_synchronize to generate a fence for memory model MEMMODEL. */
6448 expand_mem_thread_fence (enum memmodel model
)
6450 if (is_mm_relaxed (model
))
6452 if (targetm
.have_mem_thread_fence ())
6454 emit_insn (targetm
.gen_mem_thread_fence (GEN_INT (model
)));
6455 expand_memory_blockage ();
6457 else if (targetm
.have_memory_barrier ())
6458 emit_insn (targetm
.gen_memory_barrier ());
6459 else if (synchronize_libfunc
!= NULL_RTX
)
6460 emit_library_call (synchronize_libfunc
, LCT_NORMAL
, VOIDmode
);
6462 expand_memory_blockage ();
6465 /* Emit a signal fence with given memory model. */
6468 expand_mem_signal_fence (enum memmodel model
)
6470 /* No machine barrier is required to implement a signal fence, but
6471 a compiler memory barrier must be issued, except for relaxed MM. */
6472 if (!is_mm_relaxed (model
))
6473 expand_memory_blockage ();
6476 /* This function expands the atomic load operation:
6477 return the atomically loaded value in MEM.
6479 MEMMODEL is the memory model variant to use.
6480 TARGET is an option place to stick the return value. */
6483 expand_atomic_load (rtx target
, rtx mem
, enum memmodel model
)
6485 machine_mode mode
= GET_MODE (mem
);
6486 enum insn_code icode
;
6488 /* If the target supports the load directly, great. */
6489 icode
= direct_optab_handler (atomic_load_optab
, mode
);
6490 if (icode
!= CODE_FOR_nothing
)
6492 struct expand_operand ops
[3];
6493 rtx_insn
*last
= get_last_insn ();
6494 if (is_mm_seq_cst (model
))
6495 expand_memory_blockage ();
6497 create_output_operand (&ops
[0], target
, mode
);
6498 create_fixed_operand (&ops
[1], mem
);
6499 create_integer_operand (&ops
[2], model
);
6500 if (maybe_expand_insn (icode
, 3, ops
))
6502 if (!is_mm_relaxed (model
))
6503 expand_memory_blockage ();
6504 return ops
[0].value
;
6506 delete_insns_since (last
);
6509 /* If the size of the object is greater than word size on this target,
6510 then we assume that a load will not be atomic. We could try to
6511 emulate a load with a compare-and-swap operation, but the store that
6512 doing this could result in would be incorrect if this is a volatile
6513 atomic load or targetting read-only-mapped memory. */
6514 if (maybe_gt (GET_MODE_PRECISION (mode
), BITS_PER_WORD
))
6515 /* If there is no atomic load, leave the library call. */
6518 /* Otherwise assume loads are atomic, and emit the proper barriers. */
6519 if (!target
|| target
== const0_rtx
)
6520 target
= gen_reg_rtx (mode
);
6522 /* For SEQ_CST, emit a barrier before the load. */
6523 if (is_mm_seq_cst (model
))
6524 expand_mem_thread_fence (model
);
6526 emit_move_insn (target
, mem
);
6528 /* Emit the appropriate barrier after the load. */
6529 expand_mem_thread_fence (model
);
6534 /* This function expands the atomic store operation:
6535 Atomically store VAL in MEM.
6536 MEMMODEL is the memory model variant to use.
6537 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
6538 function returns const0_rtx if a pattern was emitted. */
6541 expand_atomic_store (rtx mem
, rtx val
, enum memmodel model
, bool use_release
)
6543 machine_mode mode
= GET_MODE (mem
);
6544 enum insn_code icode
;
6545 struct expand_operand ops
[3];
6547 /* If the target supports the store directly, great. */
6548 icode
= direct_optab_handler (atomic_store_optab
, mode
);
6549 if (icode
!= CODE_FOR_nothing
)
6551 rtx_insn
*last
= get_last_insn ();
6552 if (!is_mm_relaxed (model
))
6553 expand_memory_blockage ();
6554 create_fixed_operand (&ops
[0], mem
);
6555 create_input_operand (&ops
[1], val
, mode
);
6556 create_integer_operand (&ops
[2], model
);
6557 if (maybe_expand_insn (icode
, 3, ops
))
6559 if (is_mm_seq_cst (model
))
6560 expand_memory_blockage ();
6563 delete_insns_since (last
);
6566 /* If using __sync_lock_release is a viable alternative, try it.
6567 Note that this will not be set to true if we are expanding a generic
6568 __atomic_store_n. */
6571 icode
= direct_optab_handler (sync_lock_release_optab
, mode
);
6572 if (icode
!= CODE_FOR_nothing
)
6574 create_fixed_operand (&ops
[0], mem
);
6575 create_input_operand (&ops
[1], const0_rtx
, mode
);
6576 if (maybe_expand_insn (icode
, 2, ops
))
6578 /* lock_release is only a release barrier. */
6579 if (is_mm_seq_cst (model
))
6580 expand_mem_thread_fence (model
);
6586 /* If the size of the object is greater than word size on this target,
6587 a default store will not be atomic. */
6588 if (maybe_gt (GET_MODE_PRECISION (mode
), BITS_PER_WORD
))
6590 /* If loads are atomic or we are called to provide a __sync builtin,
6591 we can try a atomic_exchange and throw away the result. Otherwise,
6592 don't do anything so that we do not create an inconsistency between
6593 loads and stores. */
6594 if (can_atomic_load_p (mode
) || is_mm_sync (model
))
6596 rtx target
= maybe_emit_atomic_exchange (NULL_RTX
, mem
, val
, model
);
6598 target
= maybe_emit_compare_and_swap_exchange_loop (NULL_RTX
, mem
,
6606 /* Otherwise assume stores are atomic, and emit the proper barriers. */
6607 expand_mem_thread_fence (model
);
6609 emit_move_insn (mem
, val
);
6611 /* For SEQ_CST, also emit a barrier after the store. */
6612 if (is_mm_seq_cst (model
))
6613 expand_mem_thread_fence (model
);
6619 /* Structure containing the pointers and values required to process the
6620 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
6622 struct atomic_op_functions
6624 direct_optab mem_fetch_before
;
6625 direct_optab mem_fetch_after
;
6626 direct_optab mem_no_result
;
6629 direct_optab no_result
;
6630 enum rtx_code reverse_code
;
6634 /* Fill in structure pointed to by OP with the various optab entries for an
6635 operation of type CODE. */
6638 get_atomic_op_for_code (struct atomic_op_functions
*op
, enum rtx_code code
)
6640 gcc_assert (op
!= NULL
);
6642 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
6643 in the source code during compilation, and the optab entries are not
6644 computable until runtime. Fill in the values at runtime. */
6648 op
->mem_fetch_before
= atomic_fetch_add_optab
;
6649 op
->mem_fetch_after
= atomic_add_fetch_optab
;
6650 op
->mem_no_result
= atomic_add_optab
;
6651 op
->fetch_before
= sync_old_add_optab
;
6652 op
->fetch_after
= sync_new_add_optab
;
6653 op
->no_result
= sync_add_optab
;
6654 op
->reverse_code
= MINUS
;
6657 op
->mem_fetch_before
= atomic_fetch_sub_optab
;
6658 op
->mem_fetch_after
= atomic_sub_fetch_optab
;
6659 op
->mem_no_result
= atomic_sub_optab
;
6660 op
->fetch_before
= sync_old_sub_optab
;
6661 op
->fetch_after
= sync_new_sub_optab
;
6662 op
->no_result
= sync_sub_optab
;
6663 op
->reverse_code
= PLUS
;
6666 op
->mem_fetch_before
= atomic_fetch_xor_optab
;
6667 op
->mem_fetch_after
= atomic_xor_fetch_optab
;
6668 op
->mem_no_result
= atomic_xor_optab
;
6669 op
->fetch_before
= sync_old_xor_optab
;
6670 op
->fetch_after
= sync_new_xor_optab
;
6671 op
->no_result
= sync_xor_optab
;
6672 op
->reverse_code
= XOR
;
6675 op
->mem_fetch_before
= atomic_fetch_and_optab
;
6676 op
->mem_fetch_after
= atomic_and_fetch_optab
;
6677 op
->mem_no_result
= atomic_and_optab
;
6678 op
->fetch_before
= sync_old_and_optab
;
6679 op
->fetch_after
= sync_new_and_optab
;
6680 op
->no_result
= sync_and_optab
;
6681 op
->reverse_code
= UNKNOWN
;
6684 op
->mem_fetch_before
= atomic_fetch_or_optab
;
6685 op
->mem_fetch_after
= atomic_or_fetch_optab
;
6686 op
->mem_no_result
= atomic_or_optab
;
6687 op
->fetch_before
= sync_old_ior_optab
;
6688 op
->fetch_after
= sync_new_ior_optab
;
6689 op
->no_result
= sync_ior_optab
;
6690 op
->reverse_code
= UNKNOWN
;
6693 op
->mem_fetch_before
= atomic_fetch_nand_optab
;
6694 op
->mem_fetch_after
= atomic_nand_fetch_optab
;
6695 op
->mem_no_result
= atomic_nand_optab
;
6696 op
->fetch_before
= sync_old_nand_optab
;
6697 op
->fetch_after
= sync_new_nand_optab
;
6698 op
->no_result
= sync_nand_optab
;
6699 op
->reverse_code
= UNKNOWN
;
6706 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
6707 using memory order MODEL. If AFTER is true the operation needs to return
6708 the value of *MEM after the operation, otherwise the previous value.
6709 TARGET is an optional place to place the result. The result is unused if
6711 Return the result if there is a better sequence, otherwise NULL_RTX. */
6714 maybe_optimize_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
6715 enum memmodel model
, bool after
)
6717 /* If the value is prefetched, or not used, it may be possible to replace
6718 the sequence with a native exchange operation. */
6719 if (!after
|| target
== const0_rtx
)
6721 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
6722 if (code
== AND
&& val
== const0_rtx
)
6724 if (target
== const0_rtx
)
6725 target
= gen_reg_rtx (GET_MODE (mem
));
6726 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
6729 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
6730 if (code
== IOR
&& val
== constm1_rtx
)
6732 if (target
== const0_rtx
)
6733 target
= gen_reg_rtx (GET_MODE (mem
));
6734 return maybe_emit_atomic_exchange (target
, mem
, val
, model
);
6741 /* Try to emit an instruction for a specific operation varaition.
6742 OPTAB contains the OP functions.
6743 TARGET is an optional place to return the result. const0_rtx means unused.
6744 MEM is the memory location to operate on.
6745 VAL is the value to use in the operation.
6746 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
6747 MODEL is the memory model, if used.
6748 AFTER is true if the returned result is the value after the operation. */
6751 maybe_emit_op (const struct atomic_op_functions
*optab
, rtx target
, rtx mem
,
6752 rtx val
, bool use_memmodel
, enum memmodel model
, bool after
)
6754 machine_mode mode
= GET_MODE (mem
);
6755 struct expand_operand ops
[4];
6756 enum insn_code icode
;
6760 /* Check to see if there is a result returned. */
6761 if (target
== const0_rtx
)
6765 icode
= direct_optab_handler (optab
->mem_no_result
, mode
);
6766 create_integer_operand (&ops
[2], model
);
6771 icode
= direct_optab_handler (optab
->no_result
, mode
);
6775 /* Otherwise, we need to generate a result. */
6780 icode
= direct_optab_handler (after
? optab
->mem_fetch_after
6781 : optab
->mem_fetch_before
, mode
);
6782 create_integer_operand (&ops
[3], model
);
6787 icode
= optab_handler (after
? optab
->fetch_after
6788 : optab
->fetch_before
, mode
);
6791 create_output_operand (&ops
[op_counter
++], target
, mode
);
6793 if (icode
== CODE_FOR_nothing
)
6796 create_fixed_operand (&ops
[op_counter
++], mem
);
6797 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6798 create_convert_operand_to (&ops
[op_counter
++], val
, mode
, true);
6800 if (maybe_expand_insn (icode
, num_ops
, ops
))
6801 return (target
== const0_rtx
? const0_rtx
: ops
[0].value
);
6807 /* This function expands an atomic fetch_OP or OP_fetch operation:
6808 TARGET is an option place to stick the return value. const0_rtx indicates
6809 the result is unused.
6810 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6811 CODE is the operation being performed (OP)
6812 MEMMODEL is the memory model variant to use.
6813 AFTER is true to return the result of the operation (OP_fetch).
6814 AFTER is false to return the value before the operation (fetch_OP).
6816 This function will *only* generate instructions if there is a direct
6817 optab. No compare and swap loops or libcalls will be generated. */
6820 expand_atomic_fetch_op_no_fallback (rtx target
, rtx mem
, rtx val
,
6821 enum rtx_code code
, enum memmodel model
,
6824 machine_mode mode
= GET_MODE (mem
);
6825 struct atomic_op_functions optab
;
6827 bool unused_result
= (target
== const0_rtx
);
6829 get_atomic_op_for_code (&optab
, code
);
6831 /* Check to see if there are any better instructions. */
6832 result
= maybe_optimize_fetch_op (target
, mem
, val
, code
, model
, after
);
6836 /* Check for the case where the result isn't used and try those patterns. */
6839 /* Try the memory model variant first. */
6840 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, true);
6844 /* Next try the old style withuot a memory model. */
6845 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, true);
6849 /* There is no no-result pattern, so try patterns with a result. */
6853 /* Try the __atomic version. */
6854 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, after
);
6858 /* Try the older __sync version. */
6859 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, after
);
6863 /* If the fetch value can be calculated from the other variation of fetch,
6864 try that operation. */
6865 if (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
)
6867 /* Try the __atomic version, then the older __sync version. */
6868 result
= maybe_emit_op (&optab
, target
, mem
, val
, true, model
, !after
);
6870 result
= maybe_emit_op (&optab
, target
, mem
, val
, false, model
, !after
);
6874 /* If the result isn't used, no need to do compensation code. */
6878 /* Issue compensation code. Fetch_after == fetch_before OP val.
6879 Fetch_before == after REVERSE_OP val. */
6881 code
= optab
.reverse_code
;
6884 result
= expand_simple_binop (mode
, AND
, result
, val
, NULL_RTX
,
6885 true, OPTAB_LIB_WIDEN
);
6886 result
= expand_simple_unop (mode
, NOT
, result
, target
, true);
6889 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
6890 true, OPTAB_LIB_WIDEN
);
6895 /* No direct opcode can be generated. */
6901 /* This function expands an atomic fetch_OP or OP_fetch operation:
6902 TARGET is an option place to stick the return value. const0_rtx indicates
6903 the result is unused.
6904 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6905 CODE is the operation being performed (OP)
6906 MEMMODEL is the memory model variant to use.
6907 AFTER is true to return the result of the operation (OP_fetch).
6908 AFTER is false to return the value before the operation (fetch_OP). */
6910 expand_atomic_fetch_op (rtx target
, rtx mem
, rtx val
, enum rtx_code code
,
6911 enum memmodel model
, bool after
)
6913 machine_mode mode
= GET_MODE (mem
);
6915 bool unused_result
= (target
== const0_rtx
);
6917 /* If loads are not atomic for the required size and we are not called to
6918 provide a __sync builtin, do not do anything so that we stay consistent
6919 with atomic loads of the same size. */
6920 if (!can_atomic_load_p (mode
) && !is_mm_sync (model
))
6923 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, val
, code
, model
,
6929 /* Add/sub can be implemented by doing the reverse operation with -(val). */
6930 if (code
== PLUS
|| code
== MINUS
)
6933 enum rtx_code reverse
= (code
== PLUS
? MINUS
: PLUS
);
6936 tmp
= expand_simple_unop (mode
, NEG
, val
, NULL_RTX
, true);
6937 result
= expand_atomic_fetch_op_no_fallback (target
, mem
, tmp
, reverse
,
6941 /* PLUS worked so emit the insns and return. */
6948 /* PLUS did not work, so throw away the negation code and continue. */
6952 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
6953 if (!can_compare_and_swap_p (mode
, false))
6957 enum rtx_code orig_code
= code
;
6958 struct atomic_op_functions optab
;
6960 get_atomic_op_for_code (&optab
, code
);
6961 libfunc
= optab_libfunc (after
? optab
.fetch_after
6962 : optab
.fetch_before
, mode
);
6964 && (after
|| unused_result
|| optab
.reverse_code
!= UNKNOWN
))
6968 code
= optab
.reverse_code
;
6969 libfunc
= optab_libfunc (after
? optab
.fetch_before
6970 : optab
.fetch_after
, mode
);
6972 if (libfunc
!= NULL
)
6974 rtx addr
= convert_memory_address (ptr_mode
, XEXP (mem
, 0));
6975 result
= emit_library_call_value (libfunc
, NULL
, LCT_NORMAL
, mode
,
6976 addr
, ptr_mode
, val
, mode
);
6978 if (!unused_result
&& fixup
)
6979 result
= expand_simple_binop (mode
, code
, result
, val
, target
,
6980 true, OPTAB_LIB_WIDEN
);
6984 /* We need the original code for any further attempts. */
6988 /* If nothing else has succeeded, default to a compare and swap loop. */
6989 if (can_compare_and_swap_p (mode
, true))
6992 rtx t0
= gen_reg_rtx (mode
), t1
;
6996 /* If the result is used, get a register for it. */
6999 if (!target
|| !register_operand (target
, mode
))
7000 target
= gen_reg_rtx (mode
);
7001 /* If fetch_before, copy the value now. */
7003 emit_move_insn (target
, t0
);
7006 target
= const0_rtx
;
7011 t1
= expand_simple_binop (mode
, AND
, t1
, val
, NULL_RTX
,
7012 true, OPTAB_LIB_WIDEN
);
7013 t1
= expand_simple_unop (mode
, code
, t1
, NULL_RTX
, true);
7016 t1
= expand_simple_binop (mode
, code
, t1
, val
, NULL_RTX
, true,
7019 /* For after, copy the value now. */
7020 if (!unused_result
&& after
)
7021 emit_move_insn (target
, t1
);
7022 insn
= get_insns ();
7025 if (t1
!= NULL
&& expand_compare_and_swap_loop (mem
, t0
, t1
, insn
))
7032 /* Return true if OPERAND is suitable for operand number OPNO of
7033 instruction ICODE. */
7036 insn_operand_matches (enum insn_code icode
, unsigned int opno
, rtx operand
)
7038 return (!insn_data
[(int) icode
].operand
[opno
].predicate
7039 || (insn_data
[(int) icode
].operand
[opno
].predicate
7040 (operand
, insn_data
[(int) icode
].operand
[opno
].mode
)));
7043 /* TARGET is a target of a multiword operation that we are going to
7044 implement as a series of word-mode operations. Return true if
7045 TARGET is suitable for this purpose. */
7048 valid_multiword_target_p (rtx target
)
7053 mode
= GET_MODE (target
);
7054 if (!GET_MODE_SIZE (mode
).is_constant (&size
))
7056 for (i
= 0; i
< size
; i
+= UNITS_PER_WORD
)
7057 if (!validate_subreg (word_mode
, mode
, target
, i
))
7062 /* Make OP describe an input operand that has value INTVAL and that has
7063 no inherent mode. This function should only be used for operands that
7064 are always expand-time constants. The backend may request that INTVAL
7065 be copied into a different kind of rtx, but it must specify the mode
7066 of that rtx if so. */
7069 create_integer_operand (struct expand_operand
*op
, poly_int64 intval
)
7071 create_expand_operand (op
, EXPAND_INTEGER
,
7072 gen_int_mode (intval
, MAX_MODE_INT
),
7073 VOIDmode
, false, intval
);
7076 /* Like maybe_legitimize_operand, but do not change the code of the
7077 current rtx value. */
7080 maybe_legitimize_operand_same_code (enum insn_code icode
, unsigned int opno
,
7081 struct expand_operand
*op
)
7083 /* See if the operand matches in its current form. */
7084 if (insn_operand_matches (icode
, opno
, op
->value
))
7087 /* If the operand is a memory whose address has no side effects,
7088 try forcing the address into a non-virtual pseudo register.
7089 The check for side effects is important because copy_to_mode_reg
7090 cannot handle things like auto-modified addresses. */
7091 if (insn_data
[(int) icode
].operand
[opno
].allows_mem
&& MEM_P (op
->value
))
7096 addr
= XEXP (mem
, 0);
7097 if (!(REG_P (addr
) && REGNO (addr
) > LAST_VIRTUAL_REGISTER
)
7098 && !side_effects_p (addr
))
7103 last
= get_last_insn ();
7104 mode
= get_address_mode (mem
);
7105 mem
= replace_equiv_address (mem
, copy_to_mode_reg (mode
, addr
));
7106 if (insn_operand_matches (icode
, opno
, mem
))
7111 delete_insns_since (last
);
7118 /* Try to make OP match operand OPNO of instruction ICODE. Return true
7119 on success, storing the new operand value back in OP. */
7122 maybe_legitimize_operand (enum insn_code icode
, unsigned int opno
,
7123 struct expand_operand
*op
)
7125 machine_mode mode
, imode
;
7126 bool old_volatile_ok
, result
;
7132 old_volatile_ok
= volatile_ok
;
7134 result
= maybe_legitimize_operand_same_code (icode
, opno
, op
);
7135 volatile_ok
= old_volatile_ok
;
7139 gcc_assert (mode
!= VOIDmode
);
7141 && op
->value
!= const0_rtx
7142 && GET_MODE (op
->value
) == mode
7143 && maybe_legitimize_operand_same_code (icode
, opno
, op
))
7146 op
->value
= gen_reg_rtx (mode
);
7152 gcc_assert (mode
!= VOIDmode
);
7153 gcc_assert (GET_MODE (op
->value
) == VOIDmode
7154 || GET_MODE (op
->value
) == mode
);
7155 if (maybe_legitimize_operand_same_code (icode
, opno
, op
))
7158 op
->value
= copy_to_mode_reg (mode
, op
->value
);
7161 case EXPAND_CONVERT_TO
:
7162 gcc_assert (mode
!= VOIDmode
);
7163 op
->value
= convert_to_mode (mode
, op
->value
, op
->unsigned_p
);
7166 case EXPAND_CONVERT_FROM
:
7167 if (GET_MODE (op
->value
) != VOIDmode
)
7168 mode
= GET_MODE (op
->value
);
7170 /* The caller must tell us what mode this value has. */
7171 gcc_assert (mode
!= VOIDmode
);
7173 imode
= insn_data
[(int) icode
].operand
[opno
].mode
;
7174 if (imode
!= VOIDmode
&& imode
!= mode
)
7176 op
->value
= convert_modes (imode
, mode
, op
->value
, op
->unsigned_p
);
7181 case EXPAND_ADDRESS
:
7182 op
->value
= convert_memory_address (as_a
<scalar_int_mode
> (mode
),
7186 case EXPAND_INTEGER
:
7187 mode
= insn_data
[(int) icode
].operand
[opno
].mode
;
7188 if (mode
!= VOIDmode
7189 && known_eq (trunc_int_for_mode (op
->int_value
, mode
),
7192 op
->value
= gen_int_mode (op
->int_value
, mode
);
7197 return insn_operand_matches (icode
, opno
, op
->value
);
7200 /* Make OP describe an input operand that should have the same value
7201 as VALUE, after any mode conversion that the target might request.
7202 TYPE is the type of VALUE. */
7205 create_convert_operand_from_type (struct expand_operand
*op
,
7206 rtx value
, tree type
)
7208 create_convert_operand_from (op
, value
, TYPE_MODE (type
),
7209 TYPE_UNSIGNED (type
));
7212 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
7213 of instruction ICODE. Return true on success, leaving the new operand
7214 values in the OPS themselves. Emit no code on failure. */
7217 maybe_legitimize_operands (enum insn_code icode
, unsigned int opno
,
7218 unsigned int nops
, struct expand_operand
*ops
)
7223 last
= get_last_insn ();
7224 for (i
= 0; i
< nops
; i
++)
7225 if (!maybe_legitimize_operand (icode
, opno
+ i
, &ops
[i
]))
7227 delete_insns_since (last
);
7233 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
7234 as its operands. Return the instruction pattern on success,
7235 and emit any necessary set-up code. Return null and emit no
7239 maybe_gen_insn (enum insn_code icode
, unsigned int nops
,
7240 struct expand_operand
*ops
)
7242 gcc_assert (nops
== (unsigned int) insn_data
[(int) icode
].n_generator_args
);
7243 if (!maybe_legitimize_operands (icode
, 0, nops
, ops
))
7249 return GEN_FCN (icode
) (ops
[0].value
);
7251 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
);
7253 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
);
7255 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7258 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7259 ops
[3].value
, ops
[4].value
);
7261 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7262 ops
[3].value
, ops
[4].value
, ops
[5].value
);
7264 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7265 ops
[3].value
, ops
[4].value
, ops
[5].value
,
7268 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7269 ops
[3].value
, ops
[4].value
, ops
[5].value
,
7270 ops
[6].value
, ops
[7].value
);
7272 return GEN_FCN (icode
) (ops
[0].value
, ops
[1].value
, ops
[2].value
,
7273 ops
[3].value
, ops
[4].value
, ops
[5].value
,
7274 ops
[6].value
, ops
[7].value
, ops
[8].value
);
7279 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7280 as its operands. Return true on success and emit no code on failure. */
7283 maybe_expand_insn (enum insn_code icode
, unsigned int nops
,
7284 struct expand_operand
*ops
)
7286 rtx_insn
*pat
= maybe_gen_insn (icode
, nops
, ops
);
7295 /* Like maybe_expand_insn, but for jumps. */
7298 maybe_expand_jump_insn (enum insn_code icode
, unsigned int nops
,
7299 struct expand_operand
*ops
)
7301 rtx_insn
*pat
= maybe_gen_insn (icode
, nops
, ops
);
7304 emit_jump_insn (pat
);
7310 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
7314 expand_insn (enum insn_code icode
, unsigned int nops
,
7315 struct expand_operand
*ops
)
7317 if (!maybe_expand_insn (icode
, nops
, ops
))
7321 /* Like expand_insn, but for jumps. */
7324 expand_jump_insn (enum insn_code icode
, unsigned int nops
,
7325 struct expand_operand
*ops
)
7327 if (!maybe_expand_jump_insn (icode
, nops
, ops
))