1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 /* Include insn-config.h before expr.h so that HAVE_conditional_move
30 is properly defined. */
31 #include "insn-config.h"
45 #include "basic-block.h"
48 /* Each optab contains info on how this target machine
49 can perform a particular operation
50 for all sizes and kinds of operands.
52 The operation to be performed is often specified
53 by passing one of these optabs as an argument.
55 See expr.h for documentation of these optabs. */
57 optab optab_table
[OTI_MAX
];
59 rtx libfunc_table
[LTI_MAX
];
61 /* Tables of patterns for converting one mode to another. */
62 convert_optab convert_optab_table
[COI_MAX
];
64 /* Contains the optab used for each rtx code. */
65 optab code_to_optab
[NUM_RTX_CODE
+ 1];
67 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
68 gives the gen_function to make a branch to test that condition. */
70 rtxfun bcc_gen_fctn
[NUM_RTX_CODE
];
72 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
73 gives the insn code to make a store-condition insn
74 to test that condition. */
76 enum insn_code setcc_gen_code
[NUM_RTX_CODE
];
78 #ifdef HAVE_conditional_move
79 /* Indexed by the machine mode, gives the insn code to make a conditional
80 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
81 setcc_gen_code to cut down on the number of named patterns. Consider a day
82 when a lot more rtx codes are conditional (eg: for the ARM). */
84 enum insn_code movcc_gen_code
[NUM_MACHINE_MODES
];
87 /* Indexed by the machine mode, gives the insn code for vector conditional
90 enum insn_code vcond_gen_code
[NUM_MACHINE_MODES
];
91 enum insn_code vcondu_gen_code
[NUM_MACHINE_MODES
];
93 /* The insn generating function can not take an rtx_code argument.
94 TRAP_RTX is used as an rtx argument. Its code is replaced with
95 the code to be used in the trap insn and all other fields are ignored. */
96 static GTY(()) rtx trap_rtx
;
98 static void prepare_float_lib_cmp (rtx
*, rtx
*, enum rtx_code
*,
99 enum machine_mode
*, int *);
100 static rtx
expand_unop_direct (enum machine_mode
, optab
, rtx
, rtx
, int);
102 /* Current libcall id. It doesn't matter what these are, as long
103 as they are unique to each libcall that is emitted. */
104 static HOST_WIDE_INT libcall_id
= 0;
106 #ifndef HAVE_conditional_trap
107 #define HAVE_conditional_trap 0
108 #define gen_conditional_trap(a,b) (gcc_unreachable (), NULL_RTX)
111 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
112 #if ENABLE_DECIMAL_BID_FORMAT
113 #define DECIMAL_PREFIX "bid_"
115 #define DECIMAL_PREFIX "dpd_"
119 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
120 the result of operation CODE applied to OP0 (and OP1 if it is a binary
123 If the last insn does not set TARGET, don't do anything, but return 1.
125 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
126 don't add the REG_EQUAL note but return 0. Our caller can then try
127 again, ensuring that TARGET is not one of the operands. */
130 add_equal_note (rtx insns
, rtx target
, enum rtx_code code
, rtx op0
, rtx op1
)
132 rtx last_insn
, insn
, set
;
135 gcc_assert (insns
&& INSN_P (insns
) && NEXT_INSN (insns
));
137 if (GET_RTX_CLASS (code
) != RTX_COMM_ARITH
138 && GET_RTX_CLASS (code
) != RTX_BIN_ARITH
139 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
140 && GET_RTX_CLASS (code
) != RTX_COMPARE
141 && GET_RTX_CLASS (code
) != RTX_UNARY
)
144 if (GET_CODE (target
) == ZERO_EXTRACT
)
147 for (last_insn
= insns
;
148 NEXT_INSN (last_insn
) != NULL_RTX
;
149 last_insn
= NEXT_INSN (last_insn
))
152 set
= single_set (last_insn
);
156 if (! rtx_equal_p (SET_DEST (set
), target
)
157 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
158 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
159 || ! rtx_equal_p (XEXP (SET_DEST (set
), 0), target
)))
162 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
163 besides the last insn. */
164 if (reg_overlap_mentioned_p (target
, op0
)
165 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
167 insn
= PREV_INSN (last_insn
);
168 while (insn
!= NULL_RTX
)
170 if (reg_set_p (target
, insn
))
173 insn
= PREV_INSN (insn
);
177 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
178 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
180 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
182 set_unique_reg_note (last_insn
, REG_EQUAL
, note
);
187 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
188 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
189 not actually do a sign-extend or zero-extend, but can leave the
190 higher-order bits of the result rtx undefined, for example, in the case
191 of logical operations, but not right shifts. */
194 widen_operand (rtx op
, enum machine_mode mode
, enum machine_mode oldmode
,
195 int unsignedp
, int no_extend
)
199 /* If we don't have to extend and this is a constant, return it. */
200 if (no_extend
&& GET_MODE (op
) == VOIDmode
)
203 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
204 extend since it will be more efficient to do so unless the signedness of
205 a promoted object differs from our extension. */
207 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)
208 && SUBREG_PROMOTED_UNSIGNED_P (op
) == unsignedp
))
209 return convert_modes (mode
, oldmode
, op
, unsignedp
);
211 /* If MODE is no wider than a single word, we return a paradoxical
213 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
214 return gen_rtx_SUBREG (mode
, force_reg (GET_MODE (op
), op
), 0);
216 /* Otherwise, get an object of MODE, clobber it, and set the low-order
219 result
= gen_reg_rtx (mode
);
220 emit_insn (gen_rtx_CLOBBER (VOIDmode
, result
));
221 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
225 /* Return the optab used for computing the operation given by
226 the tree code, CODE. This function is not always usable (for
227 example, it cannot give complete results for multiplication
228 or division) but probably ought to be relied on more widely
229 throughout the expander. */
231 optab_for_tree_code (enum tree_code code
, const_tree type
)
243 return one_cmpl_optab
;
252 return TYPE_UNSIGNED (type
) ? umod_optab
: smod_optab
;
260 return TYPE_UNSIGNED (type
) ? udiv_optab
: sdiv_optab
;
266 return TYPE_UNSIGNED (type
) ? lshr_optab
: ashr_optab
;
275 return TYPE_UNSIGNED (type
) ? umax_optab
: smax_optab
;
278 return TYPE_UNSIGNED (type
) ? umin_optab
: smin_optab
;
280 case REALIGN_LOAD_EXPR
:
281 return vec_realign_load_optab
;
284 return TYPE_UNSIGNED (type
) ? usum_widen_optab
: ssum_widen_optab
;
287 return TYPE_UNSIGNED (type
) ? udot_prod_optab
: sdot_prod_optab
;
290 return TYPE_UNSIGNED (type
) ? reduc_umax_optab
: reduc_smax_optab
;
293 return TYPE_UNSIGNED (type
) ? reduc_umin_optab
: reduc_smin_optab
;
295 case REDUC_PLUS_EXPR
:
296 return TYPE_UNSIGNED (type
) ? reduc_uplus_optab
: reduc_splus_optab
;
298 case VEC_LSHIFT_EXPR
:
299 return vec_shl_optab
;
301 case VEC_RSHIFT_EXPR
:
302 return vec_shr_optab
;
304 case VEC_WIDEN_MULT_HI_EXPR
:
305 return TYPE_UNSIGNED (type
) ?
306 vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
308 case VEC_WIDEN_MULT_LO_EXPR
:
309 return TYPE_UNSIGNED (type
) ?
310 vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
312 case VEC_UNPACK_HI_EXPR
:
313 return TYPE_UNSIGNED (type
) ?
314 vec_unpacku_hi_optab
: vec_unpacks_hi_optab
;
316 case VEC_UNPACK_LO_EXPR
:
317 return TYPE_UNSIGNED (type
) ?
318 vec_unpacku_lo_optab
: vec_unpacks_lo_optab
;
320 case VEC_UNPACK_FLOAT_HI_EXPR
:
321 /* The signedness is determined from input operand. */
322 return TYPE_UNSIGNED (type
) ?
323 vec_unpacku_float_hi_optab
: vec_unpacks_float_hi_optab
;
325 case VEC_UNPACK_FLOAT_LO_EXPR
:
326 /* The signedness is determined from input operand. */
327 return TYPE_UNSIGNED (type
) ?
328 vec_unpacku_float_lo_optab
: vec_unpacks_float_lo_optab
;
330 case VEC_PACK_TRUNC_EXPR
:
331 return vec_pack_trunc_optab
;
333 case VEC_PACK_SAT_EXPR
:
334 return TYPE_UNSIGNED (type
) ? vec_pack_usat_optab
: vec_pack_ssat_optab
;
336 case VEC_PACK_FIX_TRUNC_EXPR
:
337 /* The signedness is determined from output operand. */
338 return TYPE_UNSIGNED (type
) ?
339 vec_pack_ufix_trunc_optab
: vec_pack_sfix_trunc_optab
;
345 trapv
= INTEGRAL_TYPE_P (type
) && TYPE_OVERFLOW_TRAPS (type
);
348 case POINTER_PLUS_EXPR
:
350 return trapv
? addv_optab
: add_optab
;
353 return trapv
? subv_optab
: sub_optab
;
356 return trapv
? smulv_optab
: smul_optab
;
359 return trapv
? negv_optab
: neg_optab
;
362 return trapv
? absv_optab
: abs_optab
;
364 case VEC_EXTRACT_EVEN_EXPR
:
365 return vec_extract_even_optab
;
367 case VEC_EXTRACT_ODD_EXPR
:
368 return vec_extract_odd_optab
;
370 case VEC_INTERLEAVE_HIGH_EXPR
:
371 return vec_interleave_high_optab
;
373 case VEC_INTERLEAVE_LOW_EXPR
:
374 return vec_interleave_low_optab
;
382 /* Expand vector widening operations.
384 There are two different classes of operations handled here:
385 1) Operations whose result is wider than all the arguments to the operation.
386 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
387 In this case OP0 and optionally OP1 would be initialized,
388 but WIDE_OP wouldn't (not relevant for this case).
389 2) Operations whose result is of the same size as the last argument to the
390 operation, but wider than all the other arguments to the operation.
391 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
392 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
394 E.g, when called to expand the following operations, this is how
395 the arguments will be initialized:
397 widening-sum 2 oprnd0 - oprnd1
398 widening-dot-product 3 oprnd0 oprnd1 oprnd2
399 widening-mult 2 oprnd0 oprnd1 -
400 type-promotion (vec-unpack) 1 oprnd0 - - */
403 expand_widen_pattern_expr (tree exp
, rtx op0
, rtx op1
, rtx wide_op
, rtx target
,
406 tree oprnd0
, oprnd1
, oprnd2
;
407 enum machine_mode wmode
= 0, tmode0
, tmode1
= 0;
408 optab widen_pattern_optab
;
410 enum machine_mode xmode0
, xmode1
= 0, wxmode
= 0;
413 rtx xop0
, xop1
, wxop
;
414 int nops
= TREE_OPERAND_LENGTH (exp
);
416 oprnd0
= TREE_OPERAND (exp
, 0);
417 tmode0
= TYPE_MODE (TREE_TYPE (oprnd0
));
418 widen_pattern_optab
=
419 optab_for_tree_code (TREE_CODE (exp
), TREE_TYPE (oprnd0
));
420 icode
= (int) optab_handler (widen_pattern_optab
, tmode0
)->insn_code
;
421 gcc_assert (icode
!= CODE_FOR_nothing
);
422 xmode0
= insn_data
[icode
].operand
[1].mode
;
426 oprnd1
= TREE_OPERAND (exp
, 1);
427 tmode1
= TYPE_MODE (TREE_TYPE (oprnd1
));
428 xmode1
= insn_data
[icode
].operand
[2].mode
;
431 /* The last operand is of a wider mode than the rest of the operands. */
439 gcc_assert (tmode1
== tmode0
);
441 oprnd2
= TREE_OPERAND (exp
, 2);
442 wmode
= TYPE_MODE (TREE_TYPE (oprnd2
));
443 wxmode
= insn_data
[icode
].operand
[3].mode
;
447 wmode
= wxmode
= insn_data
[icode
].operand
[0].mode
;
450 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, wmode
))
451 temp
= gen_reg_rtx (wmode
);
459 /* In case the insn wants input operands in modes different from
460 those of the actual operands, convert the operands. It would
461 seem that we don't need to convert CONST_INTs, but we do, so
462 that they're properly zero-extended, sign-extended or truncated
465 if (GET_MODE (op0
) != xmode0
&& xmode0
!= VOIDmode
)
466 xop0
= convert_modes (xmode0
,
467 GET_MODE (op0
) != VOIDmode
473 if (GET_MODE (op1
) != xmode1
&& xmode1
!= VOIDmode
)
474 xop1
= convert_modes (xmode1
,
475 GET_MODE (op1
) != VOIDmode
481 if (GET_MODE (wide_op
) != wxmode
&& wxmode
!= VOIDmode
)
482 wxop
= convert_modes (wxmode
,
483 GET_MODE (wide_op
) != VOIDmode
488 /* Now, if insn's predicates don't allow our operands, put them into
491 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, xmode0
)
492 && xmode0
!= VOIDmode
)
493 xop0
= copy_to_mode_reg (xmode0
, xop0
);
497 if (! (*insn_data
[icode
].operand
[2].predicate
) (xop1
, xmode1
)
498 && xmode1
!= VOIDmode
)
499 xop1
= copy_to_mode_reg (xmode1
, xop1
);
503 if (! (*insn_data
[icode
].operand
[3].predicate
) (wxop
, wxmode
)
504 && wxmode
!= VOIDmode
)
505 wxop
= copy_to_mode_reg (wxmode
, wxop
);
507 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
, wxop
);
510 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
516 if (! (*insn_data
[icode
].operand
[2].predicate
) (wxop
, wxmode
)
517 && wxmode
!= VOIDmode
)
518 wxop
= copy_to_mode_reg (wxmode
, wxop
);
520 pat
= GEN_FCN (icode
) (temp
, xop0
, wxop
);
523 pat
= GEN_FCN (icode
) (temp
, xop0
);
530 /* Generate code to perform an operation specified by TERNARY_OPTAB
531 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
533 UNSIGNEDP is for the case where we have to widen the operands
534 to perform the operation. It says to use zero-extension.
536 If TARGET is nonzero, the value
537 is generated there, if it is convenient to do so.
538 In all cases an rtx is returned for the locus of the value;
539 this may or may not be TARGET. */
542 expand_ternary_op (enum machine_mode mode
, optab ternary_optab
, rtx op0
,
543 rtx op1
, rtx op2
, rtx target
, int unsignedp
)
545 int icode
= (int) optab_handler (ternary_optab
, mode
)->insn_code
;
546 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
547 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
548 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
551 rtx xop0
= op0
, xop1
= op1
, xop2
= op2
;
553 gcc_assert (optab_handler (ternary_optab
, mode
)->insn_code
554 != CODE_FOR_nothing
);
556 if (!target
|| !insn_data
[icode
].operand
[0].predicate (target
, mode
))
557 temp
= gen_reg_rtx (mode
);
561 /* In case the insn wants input operands in modes different from
562 those of the actual operands, convert the operands. It would
563 seem that we don't need to convert CONST_INTs, but we do, so
564 that they're properly zero-extended, sign-extended or truncated
567 if (GET_MODE (op0
) != mode0
&& mode0
!= VOIDmode
)
568 xop0
= convert_modes (mode0
,
569 GET_MODE (op0
) != VOIDmode
574 if (GET_MODE (op1
) != mode1
&& mode1
!= VOIDmode
)
575 xop1
= convert_modes (mode1
,
576 GET_MODE (op1
) != VOIDmode
581 if (GET_MODE (op2
) != mode2
&& mode2
!= VOIDmode
)
582 xop2
= convert_modes (mode2
,
583 GET_MODE (op2
) != VOIDmode
588 /* Now, if insn's predicates don't allow our operands, put them into
591 if (!insn_data
[icode
].operand
[1].predicate (xop0
, mode0
)
592 && mode0
!= VOIDmode
)
593 xop0
= copy_to_mode_reg (mode0
, xop0
);
595 if (!insn_data
[icode
].operand
[2].predicate (xop1
, mode1
)
596 && mode1
!= VOIDmode
)
597 xop1
= copy_to_mode_reg (mode1
, xop1
);
599 if (!insn_data
[icode
].operand
[3].predicate (xop2
, mode2
)
600 && mode2
!= VOIDmode
)
601 xop2
= copy_to_mode_reg (mode2
, xop2
);
603 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
, xop2
);
610 /* Like expand_binop, but return a constant rtx if the result can be
611 calculated at compile time. The arguments and return value are
612 otherwise the same as for expand_binop. */
615 simplify_expand_binop (enum machine_mode mode
, optab binoptab
,
616 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
617 enum optab_methods methods
)
619 if (CONSTANT_P (op0
) && CONSTANT_P (op1
))
621 rtx x
= simplify_binary_operation (binoptab
->code
, mode
, op0
, op1
);
627 return expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
);
630 /* Like simplify_expand_binop, but always put the result in TARGET.
631 Return true if the expansion succeeded. */
634 force_expand_binop (enum machine_mode mode
, optab binoptab
,
635 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
636 enum optab_methods methods
)
638 rtx x
= simplify_expand_binop (mode
, binoptab
, op0
, op1
,
639 target
, unsignedp
, methods
);
643 emit_move_insn (target
, x
);
647 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */
650 expand_vec_shift_expr (tree vec_shift_expr
, rtx target
)
652 enum insn_code icode
;
653 rtx rtx_op1
, rtx_op2
;
654 enum machine_mode mode1
;
655 enum machine_mode mode2
;
656 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (vec_shift_expr
));
657 tree vec_oprnd
= TREE_OPERAND (vec_shift_expr
, 0);
658 tree shift_oprnd
= TREE_OPERAND (vec_shift_expr
, 1);
662 switch (TREE_CODE (vec_shift_expr
))
664 case VEC_RSHIFT_EXPR
:
665 shift_optab
= vec_shr_optab
;
667 case VEC_LSHIFT_EXPR
:
668 shift_optab
= vec_shl_optab
;
674 icode
= (int) optab_handler (shift_optab
, mode
)->insn_code
;
675 gcc_assert (icode
!= CODE_FOR_nothing
);
677 mode1
= insn_data
[icode
].operand
[1].mode
;
678 mode2
= insn_data
[icode
].operand
[2].mode
;
680 rtx_op1
= expand_normal (vec_oprnd
);
681 if (!(*insn_data
[icode
].operand
[1].predicate
) (rtx_op1
, mode1
)
682 && mode1
!= VOIDmode
)
683 rtx_op1
= force_reg (mode1
, rtx_op1
);
685 rtx_op2
= expand_normal (shift_oprnd
);
686 if (!(*insn_data
[icode
].operand
[2].predicate
) (rtx_op2
, mode2
)
687 && mode2
!= VOIDmode
)
688 rtx_op2
= force_reg (mode2
, rtx_op2
);
691 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode
))
692 target
= gen_reg_rtx (mode
);
694 /* Emit instruction */
695 pat
= GEN_FCN (icode
) (target
, rtx_op1
, rtx_op2
);
702 /* This subroutine of expand_doubleword_shift handles the cases in which
703 the effective shift value is >= BITS_PER_WORD. The arguments and return
704 value are the same as for the parent routine, except that SUPERWORD_OP1
705 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
706 INTO_TARGET may be null if the caller has decided to calculate it. */
709 expand_superword_shift (optab binoptab
, rtx outof_input
, rtx superword_op1
,
710 rtx outof_target
, rtx into_target
,
711 int unsignedp
, enum optab_methods methods
)
713 if (into_target
!= 0)
714 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, superword_op1
,
715 into_target
, unsignedp
, methods
))
718 if (outof_target
!= 0)
720 /* For a signed right shift, we must fill OUTOF_TARGET with copies
721 of the sign bit, otherwise we must fill it with zeros. */
722 if (binoptab
!= ashr_optab
)
723 emit_move_insn (outof_target
, CONST0_RTX (word_mode
));
725 if (!force_expand_binop (word_mode
, binoptab
,
726 outof_input
, GEN_INT (BITS_PER_WORD
- 1),
727 outof_target
, unsignedp
, methods
))
733 /* This subroutine of expand_doubleword_shift handles the cases in which
734 the effective shift value is < BITS_PER_WORD. The arguments and return
735 value are the same as for the parent routine. */
738 expand_subword_shift (enum machine_mode op1_mode
, optab binoptab
,
739 rtx outof_input
, rtx into_input
, rtx op1
,
740 rtx outof_target
, rtx into_target
,
741 int unsignedp
, enum optab_methods methods
,
742 unsigned HOST_WIDE_INT shift_mask
)
744 optab reverse_unsigned_shift
, unsigned_shift
;
747 reverse_unsigned_shift
= (binoptab
== ashl_optab
? lshr_optab
: ashl_optab
);
748 unsigned_shift
= (binoptab
== ashl_optab
? ashl_optab
: lshr_optab
);
750 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
751 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
752 the opposite direction to BINOPTAB. */
753 if (CONSTANT_P (op1
) || shift_mask
>= BITS_PER_WORD
)
755 carries
= outof_input
;
756 tmp
= immed_double_const (BITS_PER_WORD
, 0, op1_mode
);
757 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
762 /* We must avoid shifting by BITS_PER_WORD bits since that is either
763 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
764 has unknown behavior. Do a single shift first, then shift by the
765 remainder. It's OK to use ~OP1 as the remainder if shift counts
766 are truncated to the mode size. */
767 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
768 outof_input
, const1_rtx
, 0, unsignedp
, methods
);
769 if (shift_mask
== BITS_PER_WORD
- 1)
771 tmp
= immed_double_const (-1, -1, op1_mode
);
772 tmp
= simplify_expand_binop (op1_mode
, xor_optab
, op1
, tmp
,
777 tmp
= immed_double_const (BITS_PER_WORD
- 1, 0, op1_mode
);
778 tmp
= simplify_expand_binop (op1_mode
, sub_optab
, tmp
, op1
,
782 if (tmp
== 0 || carries
== 0)
784 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
785 carries
, tmp
, 0, unsignedp
, methods
);
789 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
790 so the result can go directly into INTO_TARGET if convenient. */
791 tmp
= expand_binop (word_mode
, unsigned_shift
, into_input
, op1
,
792 into_target
, unsignedp
, methods
);
796 /* Now OR in the bits carried over from OUTOF_INPUT. */
797 if (!force_expand_binop (word_mode
, ior_optab
, tmp
, carries
,
798 into_target
, unsignedp
, methods
))
801 /* Use a standard word_mode shift for the out-of half. */
802 if (outof_target
!= 0)
803 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
804 outof_target
, unsignedp
, methods
))
811 #ifdef HAVE_conditional_move
812 /* Try implementing expand_doubleword_shift using conditional moves.
813 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
814 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
815 are the shift counts to use in the former and latter case. All other
816 arguments are the same as the parent routine. */
819 expand_doubleword_shift_condmove (enum machine_mode op1_mode
, optab binoptab
,
820 enum rtx_code cmp_code
, rtx cmp1
, rtx cmp2
,
821 rtx outof_input
, rtx into_input
,
822 rtx subword_op1
, rtx superword_op1
,
823 rtx outof_target
, rtx into_target
,
824 int unsignedp
, enum optab_methods methods
,
825 unsigned HOST_WIDE_INT shift_mask
)
827 rtx outof_superword
, into_superword
;
829 /* Put the superword version of the output into OUTOF_SUPERWORD and
831 outof_superword
= outof_target
!= 0 ? gen_reg_rtx (word_mode
) : 0;
832 if (outof_target
!= 0 && subword_op1
== superword_op1
)
834 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
835 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
836 into_superword
= outof_target
;
837 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
838 outof_superword
, 0, unsignedp
, methods
))
843 into_superword
= gen_reg_rtx (word_mode
);
844 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
845 outof_superword
, into_superword
,
850 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
851 if (!expand_subword_shift (op1_mode
, binoptab
,
852 outof_input
, into_input
, subword_op1
,
853 outof_target
, into_target
,
854 unsignedp
, methods
, shift_mask
))
857 /* Select between them. Do the INTO half first because INTO_SUPERWORD
858 might be the current value of OUTOF_TARGET. */
859 if (!emit_conditional_move (into_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
860 into_target
, into_superword
, word_mode
, false))
863 if (outof_target
!= 0)
864 if (!emit_conditional_move (outof_target
, cmp_code
, cmp1
, cmp2
, op1_mode
,
865 outof_target
, outof_superword
,
873 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
874 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
875 input operand; the shift moves bits in the direction OUTOF_INPUT->
876 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
877 of the target. OP1 is the shift count and OP1_MODE is its mode.
878 If OP1 is constant, it will have been truncated as appropriate
879 and is known to be nonzero.
881 If SHIFT_MASK is zero, the result of word shifts is undefined when the
882 shift count is outside the range [0, BITS_PER_WORD). This routine must
883 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
885 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
886 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
887 fill with zeros or sign bits as appropriate.
889 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
890 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
891 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
892 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
895 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
896 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
897 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
898 function wants to calculate it itself.
900 Return true if the shift could be successfully synthesized. */
903 expand_doubleword_shift (enum machine_mode op1_mode
, optab binoptab
,
904 rtx outof_input
, rtx into_input
, rtx op1
,
905 rtx outof_target
, rtx into_target
,
906 int unsignedp
, enum optab_methods methods
,
907 unsigned HOST_WIDE_INT shift_mask
)
909 rtx superword_op1
, tmp
, cmp1
, cmp2
;
910 rtx subword_label
, done_label
;
911 enum rtx_code cmp_code
;
913 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
914 fill the result with sign or zero bits as appropriate. If so, the value
915 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
916 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
917 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
919 This isn't worthwhile for constant shifts since the optimizers will
920 cope better with in-range shift counts. */
921 if (shift_mask
>= BITS_PER_WORD
923 && !CONSTANT_P (op1
))
925 if (!expand_doubleword_shift (op1_mode
, binoptab
,
926 outof_input
, into_input
, op1
,
928 unsignedp
, methods
, shift_mask
))
930 if (!force_expand_binop (word_mode
, binoptab
, outof_input
, op1
,
931 outof_target
, unsignedp
, methods
))
936 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
937 is true when the effective shift value is less than BITS_PER_WORD.
938 Set SUPERWORD_OP1 to the shift count that should be used to shift
939 OUTOF_INPUT into INTO_TARGET when the condition is false. */
940 tmp
= immed_double_const (BITS_PER_WORD
, 0, op1_mode
);
941 if (!CONSTANT_P (op1
) && shift_mask
== BITS_PER_WORD
- 1)
943 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
944 is a subword shift count. */
945 cmp1
= simplify_expand_binop (op1_mode
, and_optab
, op1
, tmp
,
947 cmp2
= CONST0_RTX (op1_mode
);
953 /* Set CMP1 to OP1 - BITS_PER_WORD. */
954 cmp1
= simplify_expand_binop (op1_mode
, sub_optab
, op1
, tmp
,
956 cmp2
= CONST0_RTX (op1_mode
);
958 superword_op1
= cmp1
;
963 /* If we can compute the condition at compile time, pick the
964 appropriate subroutine. */
965 tmp
= simplify_relational_operation (cmp_code
, SImode
, op1_mode
, cmp1
, cmp2
);
966 if (tmp
!= 0 && GET_CODE (tmp
) == CONST_INT
)
968 if (tmp
== const0_rtx
)
969 return expand_superword_shift (binoptab
, outof_input
, superword_op1
,
970 outof_target
, into_target
,
973 return expand_subword_shift (op1_mode
, binoptab
,
974 outof_input
, into_input
, op1
,
975 outof_target
, into_target
,
976 unsignedp
, methods
, shift_mask
);
979 #ifdef HAVE_conditional_move
980 /* Try using conditional moves to generate straight-line code. */
982 rtx start
= get_last_insn ();
983 if (expand_doubleword_shift_condmove (op1_mode
, binoptab
,
984 cmp_code
, cmp1
, cmp2
,
985 outof_input
, into_input
,
987 outof_target
, into_target
,
988 unsignedp
, methods
, shift_mask
))
990 delete_insns_since (start
);
994 /* As a last resort, use branches to select the correct alternative. */
995 subword_label
= gen_label_rtx ();
996 done_label
= gen_label_rtx ();
999 do_compare_rtx_and_jump (cmp1
, cmp2
, cmp_code
, false, op1_mode
,
1000 0, 0, subword_label
);
1003 if (!expand_superword_shift (binoptab
, outof_input
, superword_op1
,
1004 outof_target
, into_target
,
1005 unsignedp
, methods
))
1008 emit_jump_insn (gen_jump (done_label
));
1010 emit_label (subword_label
);
1012 if (!expand_subword_shift (op1_mode
, binoptab
,
1013 outof_input
, into_input
, op1
,
1014 outof_target
, into_target
,
1015 unsignedp
, methods
, shift_mask
))
1018 emit_label (done_label
);
1022 /* Subroutine of expand_binop. Perform a double word multiplication of
1023 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1024 as the target's word_mode. This function return NULL_RTX if anything
1025 goes wrong, in which case it may have already emitted instructions
1026 which need to be deleted.
1028 If we want to multiply two two-word values and have normal and widening
1029 multiplies of single-word values, we can do this with three smaller
1030 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1031 because we are not operating on one word at a time.
1033 The multiplication proceeds as follows:
1034 _______________________
1035 [__op0_high_|__op0_low__]
1036 _______________________
1037 * [__op1_high_|__op1_low__]
1038 _______________________________________________
1039 _______________________
1040 (1) [__op0_low__*__op1_low__]
1041 _______________________
1042 (2a) [__op0_low__*__op1_high_]
1043 _______________________
1044 (2b) [__op0_high_*__op1_low__]
1045 _______________________
1046 (3) [__op0_high_*__op1_high_]
1049 This gives a 4-word result. Since we are only interested in the
1050 lower 2 words, partial result (3) and the upper words of (2a) and
1051 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1052 calculated using non-widening multiplication.
1054 (1), however, needs to be calculated with an unsigned widening
1055 multiplication. If this operation is not directly supported we
1056 try using a signed widening multiplication and adjust the result.
1057 This adjustment works as follows:
1059 If both operands are positive then no adjustment is needed.
1061 If the operands have different signs, for example op0_low < 0 and
1062 op1_low >= 0, the instruction treats the most significant bit of
1063 op0_low as a sign bit instead of a bit with significance
1064 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1065 with 2**BITS_PER_WORD - op0_low, and two's complements the
1066 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1069 Similarly, if both operands are negative, we need to add
1070 (op0_low + op1_low) * 2**BITS_PER_WORD.
1072 We use a trick to adjust quickly. We logically shift op0_low right
1073 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1074 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1075 logical shift exists, we do an arithmetic right shift and subtract
1079 expand_doubleword_mult (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
1080 bool umulp
, enum optab_methods methods
)
1082 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1083 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1084 rtx wordm1
= umulp
? NULL_RTX
: GEN_INT (BITS_PER_WORD
- 1);
1085 rtx product
, adjust
, product_high
, temp
;
1087 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1088 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1089 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1090 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1092 /* If we're using an unsigned multiply to directly compute the product
1093 of the low-order words of the operands and perform any required
1094 adjustments of the operands, we begin by trying two more multiplications
1095 and then computing the appropriate sum.
1097 We have checked above that the required addition is provided.
1098 Full-word addition will normally always succeed, especially if
1099 it is provided at all, so we don't worry about its failure. The
1100 multiplication may well fail, however, so we do handle that. */
1104 /* ??? This could be done with emit_store_flag where available. */
1105 temp
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1106 NULL_RTX
, 1, methods
);
1108 op0_high
= expand_binop (word_mode
, add_optab
, op0_high
, temp
,
1109 NULL_RTX
, 0, OPTAB_DIRECT
);
1112 temp
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1113 NULL_RTX
, 0, methods
);
1116 op0_high
= expand_binop (word_mode
, sub_optab
, op0_high
, temp
,
1117 NULL_RTX
, 0, OPTAB_DIRECT
);
1124 adjust
= expand_binop (word_mode
, smul_optab
, op0_high
, op1_low
,
1125 NULL_RTX
, 0, OPTAB_DIRECT
);
1129 /* OP0_HIGH should now be dead. */
1133 /* ??? This could be done with emit_store_flag where available. */
1134 temp
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1135 NULL_RTX
, 1, methods
);
1137 op1_high
= expand_binop (word_mode
, add_optab
, op1_high
, temp
,
1138 NULL_RTX
, 0, OPTAB_DIRECT
);
1141 temp
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1142 NULL_RTX
, 0, methods
);
1145 op1_high
= expand_binop (word_mode
, sub_optab
, op1_high
, temp
,
1146 NULL_RTX
, 0, OPTAB_DIRECT
);
1153 temp
= expand_binop (word_mode
, smul_optab
, op1_high
, op0_low
,
1154 NULL_RTX
, 0, OPTAB_DIRECT
);
1158 /* OP1_HIGH should now be dead. */
1160 adjust
= expand_binop (word_mode
, add_optab
, adjust
, temp
,
1161 adjust
, 0, OPTAB_DIRECT
);
1163 if (target
&& !REG_P (target
))
1167 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1168 target
, 1, OPTAB_DIRECT
);
1170 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1171 target
, 1, OPTAB_DIRECT
);
1176 product_high
= operand_subword (product
, high
, 1, mode
);
1177 adjust
= expand_binop (word_mode
, add_optab
, product_high
, adjust
,
1178 REG_P (product_high
) ? product_high
: adjust
,
1180 emit_move_insn (product_high
, adjust
);
1184 /* Wrapper around expand_binop which takes an rtx code to specify
1185 the operation to perform, not an optab pointer. All other
1186 arguments are the same. */
1188 expand_simple_binop (enum machine_mode mode
, enum rtx_code code
, rtx op0
,
1189 rtx op1
, rtx target
, int unsignedp
,
1190 enum optab_methods methods
)
1192 optab binop
= code_to_optab
[(int) code
];
1195 return expand_binop (mode
, binop
, op0
, op1
, target
, unsignedp
, methods
);
1198 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1199 binop. Order them according to commutative_operand_precedence and, if
1200 possible, try to put TARGET or a pseudo first. */
1202 swap_commutative_operands_with_target (rtx target
, rtx op0
, rtx op1
)
1204 int op0_prec
= commutative_operand_precedence (op0
);
1205 int op1_prec
= commutative_operand_precedence (op1
);
1207 if (op0_prec
< op1_prec
)
1210 if (op0_prec
> op1_prec
)
1213 /* With equal precedence, both orders are ok, but it is better if the
1214 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1215 if (target
== 0 || REG_P (target
))
1216 return (REG_P (op1
) && !REG_P (op0
)) || target
== op1
;
1218 return rtx_equal_p (op1
, target
);
1221 /* Return true if BINOPTAB implements a shift operation. */
1224 shift_optab_p (optab binoptab
)
1226 switch (binoptab
->code
)
1240 /* Return true if BINOPTAB implements a commutative binary operation. */
1243 commutative_optab_p (optab binoptab
)
1245 return (GET_RTX_CLASS (binoptab
->code
) == RTX_COMM_ARITH
1246 || binoptab
== smul_widen_optab
1247 || binoptab
== umul_widen_optab
1248 || binoptab
== smul_highpart_optab
1249 || binoptab
== umul_highpart_optab
);
1252 /* X is to be used in mode MODE as an operand to BINOPTAB. If we're
1253 optimizing, and if the operand is a constant that costs more than
1254 1 instruction, force the constant into a register and return that
1255 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1258 avoid_expensive_constant (enum machine_mode mode
, optab binoptab
,
1259 rtx x
, bool unsignedp
)
1263 && rtx_cost (x
, binoptab
->code
) > COSTS_N_INSNS (1))
1265 if (GET_CODE (x
) == CONST_INT
)
1267 HOST_WIDE_INT intval
= trunc_int_for_mode (INTVAL (x
), mode
);
1268 if (intval
!= INTVAL (x
))
1269 x
= GEN_INT (intval
);
1272 x
= convert_modes (mode
, VOIDmode
, x
, unsignedp
);
1273 x
= force_reg (mode
, x
);
1278 /* Helper function for expand_binop: handle the case where there
1279 is an insn that directly implements the indicated operation.
1280 Returns null if this is not possible. */
1282 expand_binop_directly (enum machine_mode mode
, optab binoptab
,
1284 rtx target
, int unsignedp
, enum optab_methods methods
,
1287 int icode
= (int) optab_handler (binoptab
, mode
)->insn_code
;
1288 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
1289 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
1290 enum machine_mode tmp_mode
;
1293 rtx xop0
= op0
, xop1
= op1
;
1300 temp
= gen_reg_rtx (mode
);
1302 /* If it is a commutative operator and the modes would match
1303 if we would swap the operands, we can save the conversions. */
1304 commutative_p
= commutative_optab_p (binoptab
);
1306 && GET_MODE (xop0
) != mode0
&& GET_MODE (xop1
) != mode1
1307 && GET_MODE (xop0
) == mode1
&& GET_MODE (xop1
) == mode1
)
1314 /* If we are optimizing, force expensive constants into a register. */
1315 xop0
= avoid_expensive_constant (mode0
, binoptab
, xop0
, unsignedp
);
1316 if (!shift_optab_p (binoptab
))
1317 xop1
= avoid_expensive_constant (mode1
, binoptab
, xop1
, unsignedp
);
1319 /* In case the insn wants input operands in modes different from
1320 those of the actual operands, convert the operands. It would
1321 seem that we don't need to convert CONST_INTs, but we do, so
1322 that they're properly zero-extended, sign-extended or truncated
1325 if (GET_MODE (xop0
) != mode0
&& mode0
!= VOIDmode
)
1326 xop0
= convert_modes (mode0
,
1327 GET_MODE (xop0
) != VOIDmode
1332 if (GET_MODE (xop1
) != mode1
&& mode1
!= VOIDmode
)
1333 xop1
= convert_modes (mode1
,
1334 GET_MODE (xop1
) != VOIDmode
1339 /* If operation is commutative,
1340 try to make the first operand a register.
1341 Even better, try to make it the same as the target.
1342 Also try to make the last operand a constant. */
1344 && swap_commutative_operands_with_target (target
, xop0
, xop1
))
1351 /* Now, if insn's predicates don't allow our operands, put them into
1354 if (!insn_data
[icode
].operand
[1].predicate (xop0
, mode0
)
1355 && mode0
!= VOIDmode
)
1356 xop0
= copy_to_mode_reg (mode0
, xop0
);
1358 if (!insn_data
[icode
].operand
[2].predicate (xop1
, mode1
)
1359 && mode1
!= VOIDmode
)
1360 xop1
= copy_to_mode_reg (mode1
, xop1
);
1362 if (binoptab
== vec_pack_trunc_optab
1363 || binoptab
== vec_pack_usat_optab
1364 || binoptab
== vec_pack_ssat_optab
1365 || binoptab
== vec_pack_ufix_trunc_optab
1366 || binoptab
== vec_pack_sfix_trunc_optab
)
1368 /* The mode of the result is different then the mode of the
1370 tmp_mode
= insn_data
[icode
].operand
[0].mode
;
1371 if (GET_MODE_NUNITS (tmp_mode
) != 2 * GET_MODE_NUNITS (mode
))
1377 if (!insn_data
[icode
].operand
[0].predicate (temp
, tmp_mode
))
1378 temp
= gen_reg_rtx (tmp_mode
);
1380 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
1383 /* If PAT is composed of more than one insn, try to add an appropriate
1384 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1385 operand, call expand_binop again, this time without a target. */
1386 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
1387 && ! add_equal_note (pat
, temp
, binoptab
->code
, xop0
, xop1
))
1389 delete_insns_since (last
);
1390 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
1391 unsignedp
, methods
);
1398 delete_insns_since (last
);
1402 /* Generate code to perform an operation specified by BINOPTAB
1403 on operands OP0 and OP1, with result having machine-mode MODE.
1405 UNSIGNEDP is for the case where we have to widen the operands
1406 to perform the operation. It says to use zero-extension.
1408 If TARGET is nonzero, the value
1409 is generated there, if it is convenient to do so.
1410 In all cases an rtx is returned for the locus of the value;
1411 this may or may not be TARGET. */
1414 expand_binop (enum machine_mode mode
, optab binoptab
, rtx op0
, rtx op1
,
1415 rtx target
, int unsignedp
, enum optab_methods methods
)
1417 enum optab_methods next_methods
1418 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
1419 ? OPTAB_WIDEN
: methods
);
1420 enum mode_class
class;
1421 enum machine_mode wider_mode
;
1423 rtx entry_last
= get_last_insn ();
1426 class = GET_MODE_CLASS (mode
);
1428 /* If subtracting an integer constant, convert this into an addition of
1429 the negated constant. */
1431 if (binoptab
== sub_optab
&& GET_CODE (op1
) == CONST_INT
)
1433 op1
= negate_rtx (mode
, op1
);
1434 binoptab
= add_optab
;
1437 /* Record where to delete back to if we backtrack. */
1438 last
= get_last_insn ();
1440 /* If we can do it with a three-operand insn, do so. */
1442 if (methods
!= OPTAB_MUST_WIDEN
1443 && optab_handler (binoptab
, mode
)->insn_code
!= CODE_FOR_nothing
)
1445 temp
= expand_binop_directly (mode
, binoptab
, op0
, op1
, target
,
1446 unsignedp
, methods
, last
);
1451 /* If we were trying to rotate, and that didn't work, try rotating
1452 the other direction before falling back to shifts and bitwise-or. */
1453 if (((binoptab
== rotl_optab
1454 && optab_handler (rotr_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
1455 || (binoptab
== rotr_optab
1456 && optab_handler (rotl_optab
, mode
)->insn_code
!= CODE_FOR_nothing
))
1457 && class == MODE_INT
)
1459 optab otheroptab
= (binoptab
== rotl_optab
? rotr_optab
: rotl_optab
);
1461 unsigned int bits
= GET_MODE_BITSIZE (mode
);
1463 if (GET_CODE (op1
) == CONST_INT
)
1464 newop1
= GEN_INT (bits
- INTVAL (op1
));
1465 else if (targetm
.shift_truncation_mask (mode
) == bits
- 1)
1466 newop1
= negate_rtx (mode
, op1
);
1468 newop1
= expand_binop (mode
, sub_optab
,
1469 GEN_INT (bits
), op1
,
1470 NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1472 temp
= expand_binop_directly (mode
, otheroptab
, op0
, newop1
,
1473 target
, unsignedp
, methods
, last
);
1478 /* If this is a multiply, see if we can do a widening operation that
1479 takes operands of this mode and makes a wider mode. */
1481 if (binoptab
== smul_optab
1482 && GET_MODE_WIDER_MODE (mode
) != VOIDmode
1483 && ((optab_handler ((unsignedp
? umul_widen_optab
: smul_widen_optab
),
1484 GET_MODE_WIDER_MODE (mode
))->insn_code
)
1485 != CODE_FOR_nothing
))
1487 temp
= expand_binop (GET_MODE_WIDER_MODE (mode
),
1488 unsignedp
? umul_widen_optab
: smul_widen_optab
,
1489 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
1493 if (GET_MODE_CLASS (mode
) == MODE_INT
1494 && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode
),
1495 GET_MODE_BITSIZE (GET_MODE (temp
))))
1496 return gen_lowpart (mode
, temp
);
1498 return convert_to_mode (mode
, temp
, unsignedp
);
1502 /* Look for a wider mode of the same class for which we think we
1503 can open-code the operation. Check for a widening multiply at the
1504 wider mode as well. */
1506 if (CLASS_HAS_WIDER_MODES_P (class)
1507 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
1508 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
1509 wider_mode
!= VOIDmode
;
1510 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1512 if (optab_handler (binoptab
, wider_mode
)->insn_code
!= CODE_FOR_nothing
1513 || (binoptab
== smul_optab
1514 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
1515 && ((optab_handler ((unsignedp
? umul_widen_optab
1516 : smul_widen_optab
),
1517 GET_MODE_WIDER_MODE (wider_mode
))->insn_code
)
1518 != CODE_FOR_nothing
)))
1520 rtx xop0
= op0
, xop1
= op1
;
1523 /* For certain integer operations, we need not actually extend
1524 the narrow operands, as long as we will truncate
1525 the results to the same narrowness. */
1527 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1528 || binoptab
== xor_optab
1529 || binoptab
== add_optab
|| binoptab
== sub_optab
1530 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1531 && class == MODE_INT
)
1534 xop0
= avoid_expensive_constant (mode
, binoptab
,
1536 if (binoptab
!= ashl_optab
)
1537 xop1
= avoid_expensive_constant (mode
, binoptab
,
1541 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
1543 /* The second operand of a shift must always be extended. */
1544 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1545 no_extend
&& binoptab
!= ashl_optab
);
1547 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1548 unsignedp
, OPTAB_DIRECT
);
1551 if (class != MODE_INT
1552 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode
),
1553 GET_MODE_BITSIZE (wider_mode
)))
1556 target
= gen_reg_rtx (mode
);
1557 convert_move (target
, temp
, 0);
1561 return gen_lowpart (mode
, temp
);
1564 delete_insns_since (last
);
1568 /* If operation is commutative,
1569 try to make the first operand a register.
1570 Even better, try to make it the same as the target.
1571 Also try to make the last operand a constant. */
1572 if (commutative_optab_p (binoptab
)
1573 && swap_commutative_operands_with_target (target
, op0
, op1
))
1580 /* These can be done a word at a time. */
1581 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
1582 && class == MODE_INT
1583 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1584 && optab_handler (binoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
1590 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1591 won't be accurate, so use a new target. */
1592 if (target
== 0 || target
== op0
|| target
== op1
)
1593 target
= gen_reg_rtx (mode
);
1597 /* Do the actual arithmetic. */
1598 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1600 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1601 rtx x
= expand_binop (word_mode
, binoptab
,
1602 operand_subword_force (op0
, i
, mode
),
1603 operand_subword_force (op1
, i
, mode
),
1604 target_piece
, unsignedp
, next_methods
);
1609 if (target_piece
!= x
)
1610 emit_move_insn (target_piece
, x
);
1613 insns
= get_insns ();
1616 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
1618 if (binoptab
->code
!= UNKNOWN
)
1620 = gen_rtx_fmt_ee (binoptab
->code
, mode
,
1621 copy_rtx (op0
), copy_rtx (op1
));
1625 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
1630 /* Synthesize double word shifts from single word shifts. */
1631 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
1632 || binoptab
== ashr_optab
)
1633 && class == MODE_INT
1634 && (GET_CODE (op1
) == CONST_INT
|| !optimize_size
)
1635 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1636 && optab_handler (binoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
1637 && optab_handler (ashl_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
1638 && optab_handler (lshr_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
1640 unsigned HOST_WIDE_INT shift_mask
, double_shift_mask
;
1641 enum machine_mode op1_mode
;
1643 double_shift_mask
= targetm
.shift_truncation_mask (mode
);
1644 shift_mask
= targetm
.shift_truncation_mask (word_mode
);
1645 op1_mode
= GET_MODE (op1
) != VOIDmode
? GET_MODE (op1
) : word_mode
;
1647 /* Apply the truncation to constant shifts. */
1648 if (double_shift_mask
> 0 && GET_CODE (op1
) == CONST_INT
)
1649 op1
= GEN_INT (INTVAL (op1
) & double_shift_mask
);
1651 if (op1
== CONST0_RTX (op1_mode
))
1654 /* Make sure that this is a combination that expand_doubleword_shift
1655 can handle. See the comments there for details. */
1656 if (double_shift_mask
== 0
1657 || (shift_mask
== BITS_PER_WORD
- 1
1658 && double_shift_mask
== BITS_PER_WORD
* 2 - 1))
1660 rtx insns
, equiv_value
;
1661 rtx into_target
, outof_target
;
1662 rtx into_input
, outof_input
;
1663 int left_shift
, outof_word
;
1665 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1666 won't be accurate, so use a new target. */
1667 if (target
== 0 || target
== op0
|| target
== op1
)
1668 target
= gen_reg_rtx (mode
);
1672 /* OUTOF_* is the word we are shifting bits away from, and
1673 INTO_* is the word that we are shifting bits towards, thus
1674 they differ depending on the direction of the shift and
1675 WORDS_BIG_ENDIAN. */
1677 left_shift
= binoptab
== ashl_optab
;
1678 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1680 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1681 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1683 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1684 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1686 if (expand_doubleword_shift (op1_mode
, binoptab
,
1687 outof_input
, into_input
, op1
,
1688 outof_target
, into_target
,
1689 unsignedp
, next_methods
, shift_mask
))
1691 insns
= get_insns ();
1694 equiv_value
= gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
);
1695 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
1702 /* Synthesize double word rotates from single word shifts. */
1703 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
1704 && class == MODE_INT
1705 && GET_CODE (op1
) == CONST_INT
1706 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1707 && optab_handler (ashl_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
1708 && optab_handler (lshr_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
1711 rtx into_target
, outof_target
;
1712 rtx into_input
, outof_input
;
1714 int shift_count
, left_shift
, outof_word
;
1716 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1717 won't be accurate, so use a new target. Do this also if target is not
1718 a REG, first because having a register instead may open optimization
1719 opportunities, and second because if target and op0 happen to be MEMs
1720 designating the same location, we would risk clobbering it too early
1721 in the code sequence we generate below. */
1722 if (target
== 0 || target
== op0
|| target
== op1
|| ! REG_P (target
))
1723 target
= gen_reg_rtx (mode
);
1727 shift_count
= INTVAL (op1
);
1729 /* OUTOF_* is the word we are shifting bits away from, and
1730 INTO_* is the word that we are shifting bits towards, thus
1731 they differ depending on the direction of the shift and
1732 WORDS_BIG_ENDIAN. */
1734 left_shift
= (binoptab
== rotl_optab
);
1735 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1737 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1738 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1740 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1741 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1743 if (shift_count
== BITS_PER_WORD
)
1745 /* This is just a word swap. */
1746 emit_move_insn (outof_target
, into_input
);
1747 emit_move_insn (into_target
, outof_input
);
1752 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1753 rtx first_shift_count
, second_shift_count
;
1754 optab reverse_unsigned_shift
, unsigned_shift
;
1756 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1757 ? lshr_optab
: ashl_optab
);
1759 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1760 ? ashl_optab
: lshr_optab
);
1762 if (shift_count
> BITS_PER_WORD
)
1764 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
1765 second_shift_count
= GEN_INT (2 * BITS_PER_WORD
- shift_count
);
1769 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
1770 second_shift_count
= GEN_INT (shift_count
);
1773 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1774 outof_input
, first_shift_count
,
1775 NULL_RTX
, unsignedp
, next_methods
);
1776 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1777 into_input
, second_shift_count
,
1778 NULL_RTX
, unsignedp
, next_methods
);
1780 if (into_temp1
!= 0 && into_temp2
!= 0)
1781 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1782 into_target
, unsignedp
, next_methods
);
1786 if (inter
!= 0 && inter
!= into_target
)
1787 emit_move_insn (into_target
, inter
);
1789 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1790 into_input
, first_shift_count
,
1791 NULL_RTX
, unsignedp
, next_methods
);
1792 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1793 outof_input
, second_shift_count
,
1794 NULL_RTX
, unsignedp
, next_methods
);
1796 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1797 inter
= expand_binop (word_mode
, ior_optab
,
1798 outof_temp1
, outof_temp2
,
1799 outof_target
, unsignedp
, next_methods
);
1801 if (inter
!= 0 && inter
!= outof_target
)
1802 emit_move_insn (outof_target
, inter
);
1805 insns
= get_insns ();
1810 /* One may be tempted to wrap the insns in a REG_NO_CONFLICT
1811 block to help the register allocator a bit. But a multi-word
1812 rotate will need all the input bits when setting the output
1813 bits, so there clearly is a conflict between the input and
1814 output registers. So we can't use a no-conflict block here. */
1820 /* These can be done a word at a time by propagating carries. */
1821 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1822 && class == MODE_INT
1823 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
1824 && optab_handler (binoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
1827 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1828 const unsigned int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
1829 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1830 rtx xop0
, xop1
, xtarget
;
1832 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1833 value is one of those, use it. Otherwise, use 1 since it is the
1834 one easiest to get. */
1835 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1836 int normalizep
= STORE_FLAG_VALUE
;
1841 /* Prepare the operands. */
1842 xop0
= force_reg (mode
, op0
);
1843 xop1
= force_reg (mode
, op1
);
1845 xtarget
= gen_reg_rtx (mode
);
1847 if (target
== 0 || !REG_P (target
))
1850 /* Indicate for flow that the entire target reg is being set. */
1852 emit_insn (gen_rtx_CLOBBER (VOIDmode
, xtarget
));
1854 /* Do the actual arithmetic. */
1855 for (i
= 0; i
< nwords
; i
++)
1857 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
1858 rtx target_piece
= operand_subword (xtarget
, index
, 1, mode
);
1859 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
1860 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
1863 /* Main add/subtract of the input operands. */
1864 x
= expand_binop (word_mode
, binoptab
,
1865 op0_piece
, op1_piece
,
1866 target_piece
, unsignedp
, next_methods
);
1872 /* Store carry from main add/subtract. */
1873 carry_out
= gen_reg_rtx (word_mode
);
1874 carry_out
= emit_store_flag_force (carry_out
,
1875 (binoptab
== add_optab
1878 word_mode
, 1, normalizep
);
1885 /* Add/subtract previous carry to main result. */
1886 newx
= expand_binop (word_mode
,
1887 normalizep
== 1 ? binoptab
: otheroptab
,
1889 NULL_RTX
, 1, next_methods
);
1893 /* Get out carry from adding/subtracting carry in. */
1894 rtx carry_tmp
= gen_reg_rtx (word_mode
);
1895 carry_tmp
= emit_store_flag_force (carry_tmp
,
1896 (binoptab
== add_optab
1899 word_mode
, 1, normalizep
);
1901 /* Logical-ior the two poss. carry together. */
1902 carry_out
= expand_binop (word_mode
, ior_optab
,
1903 carry_out
, carry_tmp
,
1904 carry_out
, 0, next_methods
);
1908 emit_move_insn (target_piece
, newx
);
1912 if (x
!= target_piece
)
1913 emit_move_insn (target_piece
, x
);
1916 carry_in
= carry_out
;
1919 if (i
== GET_MODE_BITSIZE (mode
) / (unsigned) BITS_PER_WORD
)
1921 if (optab_handler (mov_optab
, mode
)->insn_code
!= CODE_FOR_nothing
1922 || ! rtx_equal_p (target
, xtarget
))
1924 rtx temp
= emit_move_insn (target
, xtarget
);
1926 set_unique_reg_note (temp
,
1928 gen_rtx_fmt_ee (binoptab
->code
, mode
,
1939 delete_insns_since (last
);
1942 /* Attempt to synthesize double word multiplies using a sequence of word
1943 mode multiplications. We first attempt to generate a sequence using a
1944 more efficient unsigned widening multiply, and if that fails we then
1945 try using a signed widening multiply. */
1947 if (binoptab
== smul_optab
1948 && class == MODE_INT
1949 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1950 && optab_handler (smul_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
1951 && optab_handler (add_optab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
1953 rtx product
= NULL_RTX
;
1955 if (optab_handler (umul_widen_optab
, mode
)->insn_code
1956 != CODE_FOR_nothing
)
1958 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
1961 delete_insns_since (last
);
1964 if (product
== NULL_RTX
1965 && optab_handler (smul_widen_optab
, mode
)->insn_code
1966 != CODE_FOR_nothing
)
1968 product
= expand_doubleword_mult (mode
, op0
, op1
, target
,
1971 delete_insns_since (last
);
1974 if (product
!= NULL_RTX
)
1976 if (optab_handler (mov_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
1978 temp
= emit_move_insn (target
? target
: product
, product
);
1979 set_unique_reg_note (temp
,
1981 gen_rtx_fmt_ee (MULT
, mode
,
1989 /* It can't be open-coded in this mode.
1990 Use a library call if one is available and caller says that's ok. */
1992 if (optab_handler (binoptab
, mode
)->libfunc
1993 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1997 enum machine_mode op1_mode
= mode
;
2002 if (shift_optab_p (binoptab
))
2004 op1_mode
= targetm
.libgcc_shift_count_mode ();
2005 /* Specify unsigned here,
2006 since negative shift counts are meaningless. */
2007 op1x
= convert_to_mode (op1_mode
, op1
, 1);
2010 if (GET_MODE (op0
) != VOIDmode
2011 && GET_MODE (op0
) != mode
)
2012 op0
= convert_to_mode (mode
, op0
, unsignedp
);
2014 /* Pass 1 for NO_QUEUE so we don't lose any increments
2015 if the libcall is cse'd or moved. */
2016 value
= emit_library_call_value (optab_handler (binoptab
, mode
)->libfunc
,
2017 NULL_RTX
, LCT_CONST
, mode
, 2,
2018 op0
, mode
, op1x
, op1_mode
);
2020 insns
= get_insns ();
2023 target
= gen_reg_rtx (mode
);
2024 emit_libcall_block (insns
, target
, value
,
2025 gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
));
2030 delete_insns_since (last
);
2032 /* It can't be done in this mode. Can we do it in a wider mode? */
2034 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
2035 || methods
== OPTAB_MUST_WIDEN
))
2037 /* Caller says, don't even try. */
2038 delete_insns_since (entry_last
);
2042 /* Compute the value of METHODS to pass to recursive calls.
2043 Don't allow widening to be tried recursively. */
2045 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
2047 /* Look for a wider mode of the same class for which it appears we can do
2050 if (CLASS_HAS_WIDER_MODES_P (class))
2052 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2053 wider_mode
!= VOIDmode
;
2054 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2056 if ((optab_handler (binoptab
, wider_mode
)->insn_code
2057 != CODE_FOR_nothing
)
2058 || (methods
== OPTAB_LIB
2059 && optab_handler (binoptab
, wider_mode
)->libfunc
))
2061 rtx xop0
= op0
, xop1
= op1
;
2064 /* For certain integer operations, we need not actually extend
2065 the narrow operands, as long as we will truncate
2066 the results to the same narrowness. */
2068 if ((binoptab
== ior_optab
|| binoptab
== and_optab
2069 || binoptab
== xor_optab
2070 || binoptab
== add_optab
|| binoptab
== sub_optab
2071 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
2072 && class == MODE_INT
)
2075 xop0
= widen_operand (xop0
, wider_mode
, mode
,
2076 unsignedp
, no_extend
);
2078 /* The second operand of a shift must always be extended. */
2079 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
2080 no_extend
&& binoptab
!= ashl_optab
);
2082 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
2083 unsignedp
, methods
);
2086 if (class != MODE_INT
2087 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode
),
2088 GET_MODE_BITSIZE (wider_mode
)))
2091 target
= gen_reg_rtx (mode
);
2092 convert_move (target
, temp
, 0);
2096 return gen_lowpart (mode
, temp
);
2099 delete_insns_since (last
);
2104 delete_insns_since (entry_last
);
2108 /* Expand a binary operator which has both signed and unsigned forms.
2109 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2112 If we widen unsigned operands, we may use a signed wider operation instead
2113 of an unsigned wider operation, since the result would be the same. */
2116 sign_expand_binop (enum machine_mode mode
, optab uoptab
, optab soptab
,
2117 rtx op0
, rtx op1
, rtx target
, int unsignedp
,
2118 enum optab_methods methods
)
2121 optab direct_optab
= unsignedp
? uoptab
: soptab
;
2122 struct optab wide_soptab
;
2124 /* Do it without widening, if possible. */
2125 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
2126 unsignedp
, OPTAB_DIRECT
);
2127 if (temp
|| methods
== OPTAB_DIRECT
)
2130 /* Try widening to a signed int. Make a fake signed optab that
2131 hides any signed insn for direct use. */
2132 wide_soptab
= *soptab
;
2133 optab_handler (&wide_soptab
, mode
)->insn_code
= CODE_FOR_nothing
;
2134 optab_handler (&wide_soptab
, mode
)->libfunc
= 0;
2136 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
2137 unsignedp
, OPTAB_WIDEN
);
2139 /* For unsigned operands, try widening to an unsigned int. */
2140 if (temp
== 0 && unsignedp
)
2141 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
2142 unsignedp
, OPTAB_WIDEN
);
2143 if (temp
|| methods
== OPTAB_WIDEN
)
2146 /* Use the right width lib call if that exists. */
2147 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
, unsignedp
, OPTAB_LIB
);
2148 if (temp
|| methods
== OPTAB_LIB
)
2151 /* Must widen and use a lib call, use either signed or unsigned. */
2152 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
2153 unsignedp
, methods
);
2157 return expand_binop (mode
, uoptab
, op0
, op1
, target
,
2158 unsignedp
, methods
);
2162 /* Generate code to perform an operation specified by UNOPPTAB
2163 on operand OP0, with two results to TARG0 and TARG1.
2164 We assume that the order of the operands for the instruction
2165 is TARG0, TARG1, OP0.
2167 Either TARG0 or TARG1 may be zero, but what that means is that
2168 the result is not actually wanted. We will generate it into
2169 a dummy pseudo-reg and discard it. They may not both be zero.
2171 Returns 1 if this operation can be performed; 0 if not. */
2174 expand_twoval_unop (optab unoptab
, rtx op0
, rtx targ0
, rtx targ1
,
2177 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2178 enum mode_class
class;
2179 enum machine_mode wider_mode
;
2180 rtx entry_last
= get_last_insn ();
2183 class = GET_MODE_CLASS (mode
);
2186 targ0
= gen_reg_rtx (mode
);
2188 targ1
= gen_reg_rtx (mode
);
2190 /* Record where to go back to if we fail. */
2191 last
= get_last_insn ();
2193 if (optab_handler (unoptab
, mode
)->insn_code
!= CODE_FOR_nothing
)
2195 int icode
= (int) optab_handler (unoptab
, mode
)->insn_code
;
2196 enum machine_mode mode0
= insn_data
[icode
].operand
[2].mode
;
2200 if (GET_MODE (xop0
) != VOIDmode
2201 && GET_MODE (xop0
) != mode0
)
2202 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2204 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2205 if (!insn_data
[icode
].operand
[2].predicate (xop0
, mode0
))
2206 xop0
= copy_to_mode_reg (mode0
, xop0
);
2208 /* We could handle this, but we should always be called with a pseudo
2209 for our targets and all insns should take them as outputs. */
2210 gcc_assert (insn_data
[icode
].operand
[0].predicate (targ0
, mode
));
2211 gcc_assert (insn_data
[icode
].operand
[1].predicate (targ1
, mode
));
2213 pat
= GEN_FCN (icode
) (targ0
, targ1
, xop0
);
2220 delete_insns_since (last
);
2223 /* It can't be done in this mode. Can we do it in a wider mode? */
2225 if (CLASS_HAS_WIDER_MODES_P (class))
2227 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2228 wider_mode
!= VOIDmode
;
2229 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2231 if (optab_handler (unoptab
, wider_mode
)->insn_code
2232 != CODE_FOR_nothing
)
2234 rtx t0
= gen_reg_rtx (wider_mode
);
2235 rtx t1
= gen_reg_rtx (wider_mode
);
2236 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2238 if (expand_twoval_unop (unoptab
, cop0
, t0
, t1
, unsignedp
))
2240 convert_move (targ0
, t0
, unsignedp
);
2241 convert_move (targ1
, t1
, unsignedp
);
2245 delete_insns_since (last
);
2250 delete_insns_since (entry_last
);
2254 /* Generate code to perform an operation specified by BINOPTAB
2255 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2256 We assume that the order of the operands for the instruction
2257 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2258 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2260 Either TARG0 or TARG1 may be zero, but what that means is that
2261 the result is not actually wanted. We will generate it into
2262 a dummy pseudo-reg and discard it. They may not both be zero.
2264 Returns 1 if this operation can be performed; 0 if not. */
2267 expand_twoval_binop (optab binoptab
, rtx op0
, rtx op1
, rtx targ0
, rtx targ1
,
2270 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
2271 enum mode_class
class;
2272 enum machine_mode wider_mode
;
2273 rtx entry_last
= get_last_insn ();
2276 class = GET_MODE_CLASS (mode
);
2279 targ0
= gen_reg_rtx (mode
);
2281 targ1
= gen_reg_rtx (mode
);
2283 /* Record where to go back to if we fail. */
2284 last
= get_last_insn ();
2286 if (optab_handler (binoptab
, mode
)->insn_code
!= CODE_FOR_nothing
)
2288 int icode
= (int) optab_handler (binoptab
, mode
)->insn_code
;
2289 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2290 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2292 rtx xop0
= op0
, xop1
= op1
;
2294 /* If we are optimizing, force expensive constants into a register. */
2295 xop0
= avoid_expensive_constant (mode0
, binoptab
, xop0
, unsignedp
);
2296 xop1
= avoid_expensive_constant (mode1
, binoptab
, xop1
, unsignedp
);
2298 /* In case the insn wants input operands in modes different from
2299 those of the actual operands, convert the operands. It would
2300 seem that we don't need to convert CONST_INTs, but we do, so
2301 that they're properly zero-extended, sign-extended or truncated
2304 if (GET_MODE (op0
) != mode0
&& mode0
!= VOIDmode
)
2305 xop0
= convert_modes (mode0
,
2306 GET_MODE (op0
) != VOIDmode
2311 if (GET_MODE (op1
) != mode1
&& mode1
!= VOIDmode
)
2312 xop1
= convert_modes (mode1
,
2313 GET_MODE (op1
) != VOIDmode
2318 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2319 if (!insn_data
[icode
].operand
[1].predicate (xop0
, mode0
))
2320 xop0
= copy_to_mode_reg (mode0
, xop0
);
2322 if (!insn_data
[icode
].operand
[2].predicate (xop1
, mode1
))
2323 xop1
= copy_to_mode_reg (mode1
, xop1
);
2325 /* We could handle this, but we should always be called with a pseudo
2326 for our targets and all insns should take them as outputs. */
2327 gcc_assert (insn_data
[icode
].operand
[0].predicate (targ0
, mode
));
2328 gcc_assert (insn_data
[icode
].operand
[3].predicate (targ1
, mode
));
2330 pat
= GEN_FCN (icode
) (targ0
, xop0
, xop1
, targ1
);
2337 delete_insns_since (last
);
2340 /* It can't be done in this mode. Can we do it in a wider mode? */
2342 if (CLASS_HAS_WIDER_MODES_P (class))
2344 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2345 wider_mode
!= VOIDmode
;
2346 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2348 if (optab_handler (binoptab
, wider_mode
)->insn_code
2349 != CODE_FOR_nothing
)
2351 rtx t0
= gen_reg_rtx (wider_mode
);
2352 rtx t1
= gen_reg_rtx (wider_mode
);
2353 rtx cop0
= convert_modes (wider_mode
, mode
, op0
, unsignedp
);
2354 rtx cop1
= convert_modes (wider_mode
, mode
, op1
, unsignedp
);
2356 if (expand_twoval_binop (binoptab
, cop0
, cop1
,
2359 convert_move (targ0
, t0
, unsignedp
);
2360 convert_move (targ1
, t1
, unsignedp
);
2364 delete_insns_since (last
);
2369 delete_insns_since (entry_last
);
2373 /* Expand the two-valued library call indicated by BINOPTAB, but
2374 preserve only one of the values. If TARG0 is non-NULL, the first
2375 value is placed into TARG0; otherwise the second value is placed
2376 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2377 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2378 This routine assumes that the value returned by the library call is
2379 as if the return value was of an integral mode twice as wide as the
2380 mode of OP0. Returns 1 if the call was successful. */
2383 expand_twoval_binop_libfunc (optab binoptab
, rtx op0
, rtx op1
,
2384 rtx targ0
, rtx targ1
, enum rtx_code code
)
2386 enum machine_mode mode
;
2387 enum machine_mode libval_mode
;
2391 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2392 gcc_assert (!targ0
!= !targ1
);
2394 mode
= GET_MODE (op0
);
2395 if (!optab_handler (binoptab
, mode
)->libfunc
)
2398 /* The value returned by the library function will have twice as
2399 many bits as the nominal MODE. */
2400 libval_mode
= smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode
),
2403 libval
= emit_library_call_value (optab_handler (binoptab
, mode
)->libfunc
,
2404 NULL_RTX
, LCT_CONST
,
2408 /* Get the part of VAL containing the value that we want. */
2409 libval
= simplify_gen_subreg (mode
, libval
, libval_mode
,
2410 targ0
? 0 : GET_MODE_SIZE (mode
));
2411 insns
= get_insns ();
2413 /* Move the into the desired location. */
2414 emit_libcall_block (insns
, targ0
? targ0
: targ1
, libval
,
2415 gen_rtx_fmt_ee (code
, mode
, op0
, op1
));
2421 /* Wrapper around expand_unop which takes an rtx code to specify
2422 the operation to perform, not an optab pointer. All other
2423 arguments are the same. */
2425 expand_simple_unop (enum machine_mode mode
, enum rtx_code code
, rtx op0
,
2426 rtx target
, int unsignedp
)
2428 optab unop
= code_to_optab
[(int) code
];
2431 return expand_unop (mode
, unop
, op0
, target
, unsignedp
);
2437 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)). */
2439 widen_clz (enum machine_mode mode
, rtx op0
, rtx target
)
2441 enum mode_class
class = GET_MODE_CLASS (mode
);
2442 if (CLASS_HAS_WIDER_MODES_P (class))
2444 enum machine_mode wider_mode
;
2445 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2446 wider_mode
!= VOIDmode
;
2447 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2449 if (optab_handler (clz_optab
, wider_mode
)->insn_code
2450 != CODE_FOR_nothing
)
2452 rtx xop0
, temp
, last
;
2454 last
= get_last_insn ();
2457 target
= gen_reg_rtx (mode
);
2458 xop0
= widen_operand (op0
, wider_mode
, mode
, true, false);
2459 temp
= expand_unop (wider_mode
, clz_optab
, xop0
, NULL_RTX
, true);
2461 temp
= expand_binop (wider_mode
, sub_optab
, temp
,
2462 GEN_INT (GET_MODE_BITSIZE (wider_mode
)
2463 - GET_MODE_BITSIZE (mode
)),
2464 target
, true, OPTAB_DIRECT
);
2466 delete_insns_since (last
);
2475 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2476 quantities, choosing which based on whether the high word is nonzero. */
2478 expand_doubleword_clz (enum machine_mode mode
, rtx op0
, rtx target
)
2480 rtx xop0
= force_reg (mode
, op0
);
2481 rtx subhi
= gen_highpart (word_mode
, xop0
);
2482 rtx sublo
= gen_lowpart (word_mode
, xop0
);
2483 rtx hi0_label
= gen_label_rtx ();
2484 rtx after_label
= gen_label_rtx ();
2485 rtx seq
, temp
, result
;
2487 /* If we were not given a target, use a word_mode register, not a
2488 'mode' register. The result will fit, and nobody is expecting
2489 anything bigger (the return type of __builtin_clz* is int). */
2491 target
= gen_reg_rtx (word_mode
);
2493 /* In any case, write to a word_mode scratch in both branches of the
2494 conditional, so we can ensure there is a single move insn setting
2495 'target' to tag a REG_EQUAL note on. */
2496 result
= gen_reg_rtx (word_mode
);
2500 /* If the high word is not equal to zero,
2501 then clz of the full value is clz of the high word. */
2502 emit_cmp_and_jump_insns (subhi
, CONST0_RTX (word_mode
), EQ
, 0,
2503 word_mode
, true, hi0_label
);
2505 temp
= expand_unop_direct (word_mode
, clz_optab
, subhi
, result
, true);
2510 convert_move (result
, temp
, true);
2512 emit_jump_insn (gen_jump (after_label
));
2515 /* Else clz of the full value is clz of the low word plus the number
2516 of bits in the high word. */
2517 emit_label (hi0_label
);
2519 temp
= expand_unop_direct (word_mode
, clz_optab
, sublo
, 0, true);
2522 temp
= expand_binop (word_mode
, add_optab
, temp
,
2523 GEN_INT (GET_MODE_BITSIZE (word_mode
)),
2524 result
, true, OPTAB_DIRECT
);
2528 convert_move (result
, temp
, true);
2530 emit_label (after_label
);
2531 convert_move (target
, result
, true);
2536 add_equal_note (seq
, target
, CLZ
, xop0
, 0);
2548 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2550 widen_bswap (enum machine_mode mode
, rtx op0
, rtx target
)
2552 enum mode_class
class = GET_MODE_CLASS (mode
);
2553 enum machine_mode wider_mode
;
2556 if (!CLASS_HAS_WIDER_MODES_P (class))
2559 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
2560 wider_mode
!= VOIDmode
;
2561 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2562 if (optab_handler (bswap_optab
, wider_mode
)->insn_code
!= CODE_FOR_nothing
)
2567 last
= get_last_insn ();
2569 x
= widen_operand (op0
, wider_mode
, mode
, true, true);
2570 x
= expand_unop (wider_mode
, bswap_optab
, x
, NULL_RTX
, true);
2573 x
= expand_shift (RSHIFT_EXPR
, wider_mode
, x
,
2574 size_int (GET_MODE_BITSIZE (wider_mode
)
2575 - GET_MODE_BITSIZE (mode
)),
2581 target
= gen_reg_rtx (mode
);
2582 emit_move_insn (target
, gen_lowpart (mode
, x
));
2585 delete_insns_since (last
);
2590 /* Try calculating bswap as two bswaps of two word-sized operands. */
2593 expand_doubleword_bswap (enum machine_mode mode
, rtx op
, rtx target
)
2597 t1
= expand_unop (word_mode
, bswap_optab
,
2598 operand_subword_force (op
, 0, mode
), NULL_RTX
, true);
2599 t0
= expand_unop (word_mode
, bswap_optab
,
2600 operand_subword_force (op
, 1, mode
), NULL_RTX
, true);
2603 target
= gen_reg_rtx (mode
);
2605 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
2606 emit_move_insn (operand_subword (target
, 0, 1, mode
), t0
);
2607 emit_move_insn (operand_subword (target
, 1, 1, mode
), t1
);
2612 /* Try calculating (parity x) as (and (popcount x) 1), where
2613 popcount can also be done in a wider mode. */
2615 expand_parity (enum machine_mode mode
, rtx op0
, rtx target
)
2617 enum mode_class
class = GET_MODE_CLASS (mode
);
2618 if (CLASS_HAS_WIDER_MODES_P (class))
2620 enum machine_mode wider_mode
;
2621 for (wider_mode
= mode
; wider_mode
!= VOIDmode
;
2622 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2624 if (optab_handler (popcount_optab
, wider_mode
)->insn_code
2625 != CODE_FOR_nothing
)
2627 rtx xop0
, temp
, last
;
2629 last
= get_last_insn ();
2632 target
= gen_reg_rtx (mode
);
2633 xop0
= widen_operand (op0
, wider_mode
, mode
, true, false);
2634 temp
= expand_unop (wider_mode
, popcount_optab
, xop0
, NULL_RTX
,
2637 temp
= expand_binop (wider_mode
, and_optab
, temp
, const1_rtx
,
2638 target
, true, OPTAB_DIRECT
);
2640 delete_insns_since (last
);
2649 /* Try calculating ctz(x) as K - clz(x & -x) ,
2650 where K is GET_MODE_BITSIZE(mode) - 1.
2652 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2653 don't have to worry about what the hardware does in that case. (If
2654 the clz instruction produces the usual value at 0, which is K, the
2655 result of this code sequence will be -1; expand_ffs, below, relies
2656 on this. It might be nice to have it be K instead, for consistency
2657 with the (very few) processors that provide a ctz with a defined
2658 value, but that would take one more instruction, and it would be
2659 less convenient for expand_ffs anyway. */
2662 expand_ctz (enum machine_mode mode
, rtx op0
, rtx target
)
2666 if (optab_handler (clz_optab
, mode
)->insn_code
== CODE_FOR_nothing
)
2671 temp
= expand_unop_direct (mode
, neg_optab
, op0
, NULL_RTX
, true);
2673 temp
= expand_binop (mode
, and_optab
, op0
, temp
, NULL_RTX
,
2674 true, OPTAB_DIRECT
);
2676 temp
= expand_unop_direct (mode
, clz_optab
, temp
, NULL_RTX
, true);
2678 temp
= expand_binop (mode
, sub_optab
, GEN_INT (GET_MODE_BITSIZE (mode
) - 1),
2680 true, OPTAB_DIRECT
);
2690 add_equal_note (seq
, temp
, CTZ
, op0
, 0);
2696 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2697 else with the sequence used by expand_clz.
2699 The ffs builtin promises to return zero for a zero value and ctz/clz
2700 may have an undefined value in that case. If they do not give us a
2701 convenient value, we have to generate a test and branch. */
2703 expand_ffs (enum machine_mode mode
, rtx op0
, rtx target
)
2705 HOST_WIDE_INT val
= 0;
2706 bool defined_at_zero
= false;
2709 if (optab_handler (ctz_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
2713 temp
= expand_unop_direct (mode
, ctz_optab
, op0
, 0, true);
2717 defined_at_zero
= (CTZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2);
2719 else if (optab_handler (clz_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
2722 temp
= expand_ctz (mode
, op0
, 0);
2726 if (CLZ_DEFINED_VALUE_AT_ZERO (mode
, val
) == 2)
2728 defined_at_zero
= true;
2729 val
= (GET_MODE_BITSIZE (mode
) - 1) - val
;
2735 if (defined_at_zero
&& val
== -1)
2736 /* No correction needed at zero. */;
2739 /* We don't try to do anything clever with the situation found
2740 on some processors (eg Alpha) where ctz(0:mode) ==
2741 bitsize(mode). If someone can think of a way to send N to -1
2742 and leave alone all values in the range 0..N-1 (where N is a
2743 power of two), cheaper than this test-and-branch, please add it.
2745 The test-and-branch is done after the operation itself, in case
2746 the operation sets condition codes that can be recycled for this.
2747 (This is true on i386, for instance.) */
2749 rtx nonzero_label
= gen_label_rtx ();
2750 emit_cmp_and_jump_insns (op0
, CONST0_RTX (mode
), NE
, 0,
2751 mode
, true, nonzero_label
);
2753 convert_move (temp
, GEN_INT (-1), false);
2754 emit_label (nonzero_label
);
2757 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2758 to produce a value in the range 0..bitsize. */
2759 temp
= expand_binop (mode
, add_optab
, temp
, GEN_INT (1),
2760 target
, false, OPTAB_DIRECT
);
2767 add_equal_note (seq
, temp
, FFS
, op0
, 0);
2776 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2777 conditions, VAL may already be a SUBREG against which we cannot generate
2778 a further SUBREG. In this case, we expect forcing the value into a
2779 register will work around the situation. */
2782 lowpart_subreg_maybe_copy (enum machine_mode omode
, rtx val
,
2783 enum machine_mode imode
)
2786 ret
= lowpart_subreg (omode
, val
, imode
);
2789 val
= force_reg (imode
, val
);
2790 ret
= lowpart_subreg (omode
, val
, imode
);
2791 gcc_assert (ret
!= NULL
);
2796 /* Expand a floating point absolute value or negation operation via a
2797 logical operation on the sign bit. */
2800 expand_absneg_bit (enum rtx_code code
, enum machine_mode mode
,
2801 rtx op0
, rtx target
)
2803 const struct real_format
*fmt
;
2804 int bitpos
, word
, nwords
, i
;
2805 enum machine_mode imode
;
2806 HOST_WIDE_INT hi
, lo
;
2809 /* The format has to have a simple sign bit. */
2810 fmt
= REAL_MODE_FORMAT (mode
);
2814 bitpos
= fmt
->signbit_rw
;
2818 /* Don't create negative zeros if the format doesn't support them. */
2819 if (code
== NEG
&& !fmt
->has_signed_zero
)
2822 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
2824 imode
= int_mode_for_mode (mode
);
2825 if (imode
== BLKmode
)
2834 if (FLOAT_WORDS_BIG_ENDIAN
)
2835 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
2837 word
= bitpos
/ BITS_PER_WORD
;
2838 bitpos
= bitpos
% BITS_PER_WORD
;
2839 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
2842 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
2845 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
2849 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
2855 if (target
== 0 || target
== op0
)
2856 target
= gen_reg_rtx (mode
);
2862 for (i
= 0; i
< nwords
; ++i
)
2864 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
2865 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
2869 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2871 immed_double_const (lo
, hi
, imode
),
2872 targ_piece
, 1, OPTAB_LIB_WIDEN
);
2873 if (temp
!= targ_piece
)
2874 emit_move_insn (targ_piece
, temp
);
2877 emit_move_insn (targ_piece
, op0_piece
);
2880 insns
= get_insns ();
2883 temp
= gen_rtx_fmt_e (code
, mode
, copy_rtx (op0
));
2884 emit_no_conflict_block (insns
, target
, op0
, NULL_RTX
, temp
);
2888 temp
= expand_binop (imode
, code
== ABS
? and_optab
: xor_optab
,
2889 gen_lowpart (imode
, op0
),
2890 immed_double_const (lo
, hi
, imode
),
2891 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
2892 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
2894 set_unique_reg_note (get_last_insn (), REG_EQUAL
,
2895 gen_rtx_fmt_e (code
, mode
, copy_rtx (op0
)));
2901 /* As expand_unop, but will fail rather than attempt the operation in a
2902 different mode or with a libcall. */
2904 expand_unop_direct (enum machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
2907 if (optab_handler (unoptab
, mode
)->insn_code
!= CODE_FOR_nothing
)
2909 int icode
= (int) optab_handler (unoptab
, mode
)->insn_code
;
2910 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2912 rtx last
= get_last_insn ();
2918 temp
= gen_reg_rtx (mode
);
2920 if (GET_MODE (xop0
) != VOIDmode
2921 && GET_MODE (xop0
) != mode0
)
2922 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2924 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2926 if (!insn_data
[icode
].operand
[1].predicate (xop0
, mode0
))
2927 xop0
= copy_to_mode_reg (mode0
, xop0
);
2929 if (!insn_data
[icode
].operand
[0].predicate (temp
, mode
))
2930 temp
= gen_reg_rtx (mode
);
2932 pat
= GEN_FCN (icode
) (temp
, xop0
);
2935 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
2936 && ! add_equal_note (pat
, temp
, unoptab
->code
, xop0
, NULL_RTX
))
2938 delete_insns_since (last
);
2939 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
2947 delete_insns_since (last
);
2952 /* Generate code to perform an operation specified by UNOPTAB
2953 on operand OP0, with result having machine-mode MODE.
2955 UNSIGNEDP is for the case where we have to widen the operands
2956 to perform the operation. It says to use zero-extension.
2958 If TARGET is nonzero, the value
2959 is generated there, if it is convenient to do so.
2960 In all cases an rtx is returned for the locus of the value;
2961 this may or may not be TARGET. */
2964 expand_unop (enum machine_mode mode
, optab unoptab
, rtx op0
, rtx target
,
2967 enum mode_class
class = GET_MODE_CLASS (mode
);
2968 enum machine_mode wider_mode
;
2971 temp
= expand_unop_direct (mode
, unoptab
, op0
, target
, unsignedp
);
2975 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2977 /* Widening (or narrowing) clz needs special treatment. */
2978 if (unoptab
== clz_optab
)
2980 temp
= widen_clz (mode
, op0
, target
);
2984 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
2985 && optab_handler (unoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
2987 temp
= expand_doubleword_clz (mode
, op0
, target
);
2995 /* Widening (or narrowing) bswap needs special treatment. */
2996 if (unoptab
== bswap_optab
)
2998 temp
= widen_bswap (mode
, op0
, target
);
3002 if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
3003 && optab_handler (unoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
3005 temp
= expand_doubleword_bswap (mode
, op0
, target
);
3013 if (CLASS_HAS_WIDER_MODES_P (class))
3014 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
3015 wider_mode
!= VOIDmode
;
3016 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3018 if (optab_handler (unoptab
, wider_mode
)->insn_code
!= CODE_FOR_nothing
)
3021 rtx last
= get_last_insn ();
3023 /* For certain operations, we need not actually extend
3024 the narrow operand, as long as we will truncate the
3025 results to the same narrowness. */
3027 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3028 (unoptab
== neg_optab
3029 || unoptab
== one_cmpl_optab
)
3030 && class == MODE_INT
);
3032 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3037 if (class != MODE_INT
3038 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode
),
3039 GET_MODE_BITSIZE (wider_mode
)))
3042 target
= gen_reg_rtx (mode
);
3043 convert_move (target
, temp
, 0);
3047 return gen_lowpart (mode
, temp
);
3050 delete_insns_since (last
);
3054 /* These can be done a word at a time. */
3055 if (unoptab
== one_cmpl_optab
3056 && class == MODE_INT
3057 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
3058 && optab_handler (unoptab
, word_mode
)->insn_code
!= CODE_FOR_nothing
)
3063 if (target
== 0 || target
== op0
)
3064 target
= gen_reg_rtx (mode
);
3068 /* Do the actual arithmetic. */
3069 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
3071 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
3072 rtx x
= expand_unop (word_mode
, unoptab
,
3073 operand_subword_force (op0
, i
, mode
),
3074 target_piece
, unsignedp
);
3076 if (target_piece
!= x
)
3077 emit_move_insn (target_piece
, x
);
3080 insns
= get_insns ();
3083 emit_no_conflict_block (insns
, target
, op0
, NULL_RTX
,
3084 gen_rtx_fmt_e (unoptab
->code
, mode
,
3089 if (unoptab
->code
== NEG
)
3091 /* Try negating floating point values by flipping the sign bit. */
3092 if (SCALAR_FLOAT_MODE_P (mode
))
3094 temp
= expand_absneg_bit (NEG
, mode
, op0
, target
);
3099 /* If there is no negation pattern, and we have no negative zero,
3100 try subtracting from zero. */
3101 if (!HONOR_SIGNED_ZEROS (mode
))
3103 temp
= expand_binop (mode
, (unoptab
== negv_optab
3104 ? subv_optab
: sub_optab
),
3105 CONST0_RTX (mode
), op0
, target
,
3106 unsignedp
, OPTAB_DIRECT
);
3112 /* Try calculating parity (x) as popcount (x) % 2. */
3113 if (unoptab
== parity_optab
)
3115 temp
= expand_parity (mode
, op0
, target
);
3120 /* Try implementing ffs (x) in terms of clz (x). */
3121 if (unoptab
== ffs_optab
)
3123 temp
= expand_ffs (mode
, op0
, target
);
3128 /* Try implementing ctz (x) in terms of clz (x). */
3129 if (unoptab
== ctz_optab
)
3131 temp
= expand_ctz (mode
, op0
, target
);
3137 /* Now try a library call in this mode. */
3138 if (optab_handler (unoptab
, mode
)->libfunc
)
3142 enum machine_mode outmode
= mode
;
3144 /* All of these functions return small values. Thus we choose to
3145 have them return something that isn't a double-word. */
3146 if (unoptab
== ffs_optab
|| unoptab
== clz_optab
|| unoptab
== ctz_optab
3147 || unoptab
== popcount_optab
|| unoptab
== parity_optab
)
3149 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node
)));
3153 /* Pass 1 for NO_QUEUE so we don't lose any increments
3154 if the libcall is cse'd or moved. */
3155 value
= emit_library_call_value (optab_handler (unoptab
, mode
)->libfunc
,
3156 NULL_RTX
, LCT_CONST
, outmode
,
3158 insns
= get_insns ();
3161 target
= gen_reg_rtx (outmode
);
3162 emit_libcall_block (insns
, target
, value
,
3163 gen_rtx_fmt_e (unoptab
->code
, outmode
, op0
));
3168 /* It can't be done in this mode. Can we do it in a wider mode? */
3170 if (CLASS_HAS_WIDER_MODES_P (class))
3172 for (wider_mode
= GET_MODE_WIDER_MODE (mode
);
3173 wider_mode
!= VOIDmode
;
3174 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3176 if ((optab_handler (unoptab
, wider_mode
)->insn_code
3177 != CODE_FOR_nothing
)
3178 || optab_handler (unoptab
, wider_mode
)->libfunc
)
3181 rtx last
= get_last_insn ();
3183 /* For certain operations, we need not actually extend
3184 the narrow operand, as long as we will truncate the
3185 results to the same narrowness. */
3187 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
3188 (unoptab
== neg_optab
3189 || unoptab
== one_cmpl_optab
)
3190 && class == MODE_INT
);
3192 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
3195 /* If we are generating clz using wider mode, adjust the
3197 if (unoptab
== clz_optab
&& temp
!= 0)
3198 temp
= expand_binop (wider_mode
, sub_optab
, temp
,
3199 GEN_INT (GET_MODE_BITSIZE (wider_mode
)
3200 - GET_MODE_BITSIZE (mode
)),
3201 target
, true, OPTAB_DIRECT
);
3205 if (class != MODE_INT
)
3208 target
= gen_reg_rtx (mode
);
3209 convert_move (target
, temp
, 0);
3213 return gen_lowpart (mode
, temp
);
3216 delete_insns_since (last
);
3221 /* One final attempt at implementing negation via subtraction,
3222 this time allowing widening of the operand. */
3223 if (unoptab
->code
== NEG
&& !HONOR_SIGNED_ZEROS (mode
))
3226 temp
= expand_binop (mode
,
3227 unoptab
== negv_optab
? subv_optab
: sub_optab
,
3228 CONST0_RTX (mode
), op0
,
3229 target
, unsignedp
, OPTAB_LIB_WIDEN
);
3237 /* Emit code to compute the absolute value of OP0, with result to
3238 TARGET if convenient. (TARGET may be 0.) The return value says
3239 where the result actually is to be found.
3241 MODE is the mode of the operand; the mode of the result is
3242 different but can be deduced from MODE.
3247 expand_abs_nojump (enum machine_mode mode
, rtx op0
, rtx target
,
3248 int result_unsignedp
)
3253 result_unsignedp
= 1;
3255 /* First try to do it with a special abs instruction. */
3256 temp
= expand_unop (mode
, result_unsignedp
? abs_optab
: absv_optab
,
3261 /* For floating point modes, try clearing the sign bit. */
3262 if (SCALAR_FLOAT_MODE_P (mode
))
3264 temp
= expand_absneg_bit (ABS
, mode
, op0
, target
);
3269 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3270 if (optab_handler (smax_optab
, mode
)->insn_code
!= CODE_FOR_nothing
3271 && !HONOR_SIGNED_ZEROS (mode
))
3273 rtx last
= get_last_insn ();
3275 temp
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, 0);
3277 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
3283 delete_insns_since (last
);
3286 /* If this machine has expensive jumps, we can do integer absolute
3287 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3288 where W is the width of MODE. */
3290 if (GET_MODE_CLASS (mode
) == MODE_INT
&& BRANCH_COST
>= 2)
3292 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
3293 size_int (GET_MODE_BITSIZE (mode
) - 1),
3296 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
3299 temp
= expand_binop (mode
, result_unsignedp
? sub_optab
: subv_optab
,
3300 temp
, extended
, target
, 0, OPTAB_LIB_WIDEN
);
3310 expand_abs (enum machine_mode mode
, rtx op0
, rtx target
,
3311 int result_unsignedp
, int safe
)
3316 result_unsignedp
= 1;
3318 temp
= expand_abs_nojump (mode
, op0
, target
, result_unsignedp
);
3322 /* If that does not win, use conditional jump and negate. */
3324 /* It is safe to use the target if it is the same
3325 as the source if this is also a pseudo register */
3326 if (op0
== target
&& REG_P (op0
)
3327 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
3330 op1
= gen_label_rtx ();
3331 if (target
== 0 || ! safe
3332 || GET_MODE (target
) != mode
3333 || (MEM_P (target
) && MEM_VOLATILE_P (target
))
3335 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
3336 target
= gen_reg_rtx (mode
);
3338 emit_move_insn (target
, op0
);
3341 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
3342 NULL_RTX
, NULL_RTX
, op1
);
3344 op0
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
3347 emit_move_insn (target
, op0
);
3353 /* A subroutine of expand_copysign, perform the copysign operation using the
3354 abs and neg primitives advertised to exist on the target. The assumption
3355 is that we have a split register file, and leaving op0 in fp registers,
3356 and not playing with subregs so much, will help the register allocator. */
3359 expand_copysign_absneg (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3360 int bitpos
, bool op0_is_abs
)
3362 enum machine_mode imode
;
3369 /* Check if the back end provides an insn that handles signbit for the
3371 icode
= (int) signbit_optab
->handlers
[(int) mode
].insn_code
;
3372 if (icode
!= CODE_FOR_nothing
)
3374 imode
= insn_data
[icode
].operand
[0].mode
;
3375 sign
= gen_reg_rtx (imode
);
3376 emit_unop_insn (icode
, sign
, op1
, UNKNOWN
);
3380 HOST_WIDE_INT hi
, lo
;
3382 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3384 imode
= int_mode_for_mode (mode
);
3385 if (imode
== BLKmode
)
3387 op1
= gen_lowpart (imode
, op1
);
3394 if (FLOAT_WORDS_BIG_ENDIAN
)
3395 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3397 word
= bitpos
/ BITS_PER_WORD
;
3398 bitpos
= bitpos
% BITS_PER_WORD
;
3399 op1
= operand_subword_force (op1
, word
, mode
);
3402 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
3405 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
3409 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
3413 sign
= gen_reg_rtx (imode
);
3414 sign
= expand_binop (imode
, and_optab
, op1
,
3415 immed_double_const (lo
, hi
, imode
),
3416 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3421 op0
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
3428 if (target
== NULL_RTX
)
3429 target
= copy_to_reg (op0
);
3431 emit_move_insn (target
, op0
);
3434 label
= gen_label_rtx ();
3435 emit_cmp_and_jump_insns (sign
, const0_rtx
, EQ
, NULL_RTX
, imode
, 1, label
);
3437 if (GET_CODE (op0
) == CONST_DOUBLE
)
3438 op0
= simplify_unary_operation (NEG
, mode
, op0
, mode
);
3440 op0
= expand_unop (mode
, neg_optab
, op0
, target
, 0);
3442 emit_move_insn (target
, op0
);
3450 /* A subroutine of expand_copysign, perform the entire copysign operation
3451 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3452 is true if op0 is known to have its sign bit clear. */
3455 expand_copysign_bit (enum machine_mode mode
, rtx op0
, rtx op1
, rtx target
,
3456 int bitpos
, bool op0_is_abs
)
3458 enum machine_mode imode
;
3459 HOST_WIDE_INT hi
, lo
;
3460 int word
, nwords
, i
;
3463 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
3465 imode
= int_mode_for_mode (mode
);
3466 if (imode
== BLKmode
)
3475 if (FLOAT_WORDS_BIG_ENDIAN
)
3476 word
= (GET_MODE_BITSIZE (mode
) - bitpos
) / BITS_PER_WORD
;
3478 word
= bitpos
/ BITS_PER_WORD
;
3479 bitpos
= bitpos
% BITS_PER_WORD
;
3480 nwords
= (GET_MODE_BITSIZE (mode
) + BITS_PER_WORD
- 1) / BITS_PER_WORD
;
3483 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
3486 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
3490 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
3494 if (target
== 0 || target
== op0
|| target
== op1
)
3495 target
= gen_reg_rtx (mode
);
3501 for (i
= 0; i
< nwords
; ++i
)
3503 rtx targ_piece
= operand_subword (target
, i
, 1, mode
);
3504 rtx op0_piece
= operand_subword_force (op0
, i
, mode
);
3509 op0_piece
= expand_binop (imode
, and_optab
, op0_piece
,
3510 immed_double_const (~lo
, ~hi
, imode
),
3511 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3513 op1
= expand_binop (imode
, and_optab
,
3514 operand_subword_force (op1
, i
, mode
),
3515 immed_double_const (lo
, hi
, imode
),
3516 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3518 temp
= expand_binop (imode
, ior_optab
, op0_piece
, op1
,
3519 targ_piece
, 1, OPTAB_LIB_WIDEN
);
3520 if (temp
!= targ_piece
)
3521 emit_move_insn (targ_piece
, temp
);
3524 emit_move_insn (targ_piece
, op0_piece
);
3527 insns
= get_insns ();
3530 emit_no_conflict_block (insns
, target
, op0
, op1
, NULL_RTX
);
3534 op1
= expand_binop (imode
, and_optab
, gen_lowpart (imode
, op1
),
3535 immed_double_const (lo
, hi
, imode
),
3536 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3538 op0
= gen_lowpart (imode
, op0
);
3540 op0
= expand_binop (imode
, and_optab
, op0
,
3541 immed_double_const (~lo
, ~hi
, imode
),
3542 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3544 temp
= expand_binop (imode
, ior_optab
, op0
, op1
,
3545 gen_lowpart (imode
, target
), 1, OPTAB_LIB_WIDEN
);
3546 target
= lowpart_subreg_maybe_copy (mode
, temp
, imode
);
3552 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3553 scalar floating point mode. Return NULL if we do not know how to
3554 expand the operation inline. */
3557 expand_copysign (rtx op0
, rtx op1
, rtx target
)
3559 enum machine_mode mode
= GET_MODE (op0
);
3560 const struct real_format
*fmt
;
3564 gcc_assert (SCALAR_FLOAT_MODE_P (mode
));
3565 gcc_assert (GET_MODE (op1
) == mode
);
3567 /* First try to do it with a special instruction. */
3568 temp
= expand_binop (mode
, copysign_optab
, op0
, op1
,
3569 target
, 0, OPTAB_DIRECT
);
3573 fmt
= REAL_MODE_FORMAT (mode
);
3574 if (fmt
== NULL
|| !fmt
->has_signed_zero
)
3578 if (GET_CODE (op0
) == CONST_DOUBLE
)
3580 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0
)))
3581 op0
= simplify_unary_operation (ABS
, mode
, op0
, mode
);
3585 if (fmt
->signbit_ro
>= 0
3586 && (GET_CODE (op0
) == CONST_DOUBLE
3587 || (optab_handler (neg_optab
, mode
)->insn_code
!= CODE_FOR_nothing
3588 && optab_handler (abs_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)))
3590 temp
= expand_copysign_absneg (mode
, op0
, op1
, target
,
3591 fmt
->signbit_ro
, op0_is_abs
);
3596 if (fmt
->signbit_rw
< 0)
3598 return expand_copysign_bit (mode
, op0
, op1
, target
,
3599 fmt
->signbit_rw
, op0_is_abs
);
3602 /* Generate an instruction whose insn-code is INSN_CODE,
3603 with two operands: an output TARGET and an input OP0.
3604 TARGET *must* be nonzero, and the output is always stored there.
3605 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3606 the value that is stored into TARGET. */
3609 emit_unop_insn (int icode
, rtx target
, rtx op0
, enum rtx_code code
)
3612 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
3617 /* Now, if insn does not accept our operands, put them into pseudos. */
3619 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
3620 op0
= copy_to_mode_reg (mode0
, op0
);
3622 if (!insn_data
[icode
].operand
[0].predicate (temp
, GET_MODE (temp
)))
3623 temp
= gen_reg_rtx (GET_MODE (temp
));
3625 pat
= GEN_FCN (icode
) (temp
, op0
);
3627 if (INSN_P (pat
) && NEXT_INSN (pat
) != NULL_RTX
&& code
!= UNKNOWN
)
3628 add_equal_note (pat
, temp
, code
, op0
, NULL_RTX
);
3633 emit_move_insn (target
, temp
);
3636 struct no_conflict_data
3638 rtx target
, first
, insn
;
3642 /* Called via note_stores by emit_no_conflict_block and emit_libcall_block.
3643 Set P->must_stay if the currently examined clobber / store has to stay
3644 in the list of insns that constitute the actual no_conflict block /
3647 no_conflict_move_test (rtx dest
, const_rtx set
, void *p0
)
3649 struct no_conflict_data
*p
= p0
;
3651 /* If this inns directly contributes to setting the target, it must stay. */
3652 if (reg_overlap_mentioned_p (p
->target
, dest
))
3653 p
->must_stay
= true;
3654 /* If we haven't committed to keeping any other insns in the list yet,
3655 there is nothing more to check. */
3656 else if (p
->insn
== p
->first
)
3658 /* If this insn sets / clobbers a register that feeds one of the insns
3659 already in the list, this insn has to stay too. */
3660 else if (reg_overlap_mentioned_p (dest
, PATTERN (p
->first
))
3661 || (CALL_P (p
->first
) && (find_reg_fusage (p
->first
, USE
, dest
)))
3662 || reg_used_between_p (dest
, p
->first
, p
->insn
)
3663 /* Likewise if this insn depends on a register set by a previous
3664 insn in the list, or if it sets a result (presumably a hard
3665 register) that is set or clobbered by a previous insn.
3666 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3667 SET_DEST perform the former check on the address, and the latter
3668 check on the MEM. */
3669 || (GET_CODE (set
) == SET
3670 && (modified_in_p (SET_SRC (set
), p
->first
)
3671 || modified_in_p (SET_DEST (set
), p
->first
)
3672 || modified_between_p (SET_SRC (set
), p
->first
, p
->insn
)
3673 || modified_between_p (SET_DEST (set
), p
->first
, p
->insn
))))
3674 p
->must_stay
= true;
3677 /* Encapsulate the block starting at FIRST and ending with LAST, which is
3678 logically equivalent to EQUIV, so it gets manipulated as a unit if it
3679 is possible to do so. */
3682 maybe_encapsulate_block (rtx first
, rtx last
, rtx equiv
)
3684 if (!flag_non_call_exceptions
|| !may_trap_p (equiv
))
3686 /* We can't attach the REG_LIBCALL and REG_RETVAL notes when the
3687 encapsulated region would not be in one basic block, i.e. when
3688 there is a control_flow_insn_p insn between FIRST and LAST. */
3689 bool attach_libcall_retval_notes
= true;
3690 rtx insn
, next
= NEXT_INSN (last
);
3692 for (insn
= first
; insn
!= next
; insn
= NEXT_INSN (insn
))
3693 if (control_flow_insn_p (insn
))
3695 attach_libcall_retval_notes
= false;
3699 if (attach_libcall_retval_notes
)
3701 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
3703 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
,
3705 next
= NEXT_INSN (last
);
3706 for (insn
= first
; insn
!= next
; insn
= NEXT_INSN (insn
))
3707 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_LIBCALL_ID
,
3708 GEN_INT (libcall_id
),
3715 /* Emit code to perform a series of operations on a multi-word quantity, one
3718 Such a block is preceded by a CLOBBER of the output, consists of multiple
3719 insns, each setting one word of the output, and followed by a SET copying
3720 the output to itself.
3722 Each of the insns setting words of the output receives a REG_NO_CONFLICT
3723 note indicating that it doesn't conflict with the (also multi-word)
3724 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3727 INSNS is a block of code generated to perform the operation, not including
3728 the CLOBBER and final copy. All insns that compute intermediate values
3729 are first emitted, followed by the block as described above.
3731 TARGET, OP0, and OP1 are the output and inputs of the operations,
3732 respectively. OP1 may be zero for a unary operation.
3734 EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3737 If TARGET is not a register, INSNS is simply emitted with no special
3738 processing. Likewise if anything in INSNS is not an INSN or if
3739 there is a libcall block inside INSNS.
3741 The final insn emitted is returned. */
3744 emit_no_conflict_block (rtx insns
, rtx target
, rtx op0
, rtx op1
, rtx equiv
)
3746 rtx prev
, next
, first
, last
, insn
;
3748 if (!REG_P (target
) || reload_in_progress
)
3749 return emit_insn (insns
);
3751 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3752 if (!NONJUMP_INSN_P (insn
)
3753 || find_reg_note (insn
, REG_LIBCALL
, NULL_RTX
))
3754 return emit_insn (insns
);
3756 /* First emit all insns that do not store into words of the output and remove
3757 these from the list. */
3758 for (insn
= insns
; insn
; insn
= next
)
3761 struct no_conflict_data data
;
3763 next
= NEXT_INSN (insn
);
3765 /* Some ports (cris) create a libcall regions at their own. We must
3766 avoid any potential nesting of LIBCALLs. */
3767 if ((note
= find_reg_note (insn
, REG_LIBCALL
, NULL
)) != NULL
)
3768 remove_note (insn
, note
);
3769 if ((note
= find_reg_note (insn
, REG_RETVAL
, NULL
)) != NULL
)
3770 remove_note (insn
, note
);
3771 if ((note
= find_reg_note (insn
, REG_LIBCALL_ID
, NULL
)) != NULL
)
3772 remove_note (insn
, note
);
3774 data
.target
= target
;
3778 note_stores (PATTERN (insn
), no_conflict_move_test
, &data
);
3779 if (! data
.must_stay
)
3781 if (PREV_INSN (insn
))
3782 NEXT_INSN (PREV_INSN (insn
)) = next
;
3787 PREV_INSN (next
) = PREV_INSN (insn
);
3793 prev
= get_last_insn ();
3795 /* Now write the CLOBBER of the output, followed by the setting of each
3796 of the words, followed by the final copy. */
3797 if (target
!= op0
&& target
!= op1
)
3798 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
3800 for (insn
= insns
; insn
; insn
= next
)
3802 next
= NEXT_INSN (insn
);
3805 if (op1
&& REG_P (op1
))
3806 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op1
,
3809 if (op0
&& REG_P (op0
))
3810 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op0
,
3814 if (optab_handler (mov_optab
, GET_MODE (target
))->insn_code
3815 != CODE_FOR_nothing
)
3817 last
= emit_move_insn (target
, target
);
3819 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
3823 last
= get_last_insn ();
3825 /* Remove any existing REG_EQUAL note from "last", or else it will
3826 be mistaken for a note referring to the full contents of the
3827 alleged libcall value when found together with the REG_RETVAL
3828 note added below. An existing note can come from an insn
3829 expansion at "last". */
3830 remove_note (last
, find_reg_note (last
, REG_EQUAL
, NULL_RTX
));
3834 first
= get_insns ();
3836 first
= NEXT_INSN (prev
);
3838 maybe_encapsulate_block (first
, last
, equiv
);
3843 /* Emit code to make a call to a constant function or a library call.
3845 INSNS is a list containing all insns emitted in the call.
3846 These insns leave the result in RESULT. Our block is to copy RESULT
3847 to TARGET, which is logically equivalent to EQUIV.
3849 We first emit any insns that set a pseudo on the assumption that these are
3850 loading constants into registers; doing so allows them to be safely cse'ed
3851 between blocks. Then we emit all the other insns in the block, followed by
3852 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3853 note with an operand of EQUIV.
3855 Moving assignments to pseudos outside of the block is done to improve
3856 the generated code, but is not required to generate correct code,
3857 hence being unable to move an assignment is not grounds for not making
3858 a libcall block. There are two reasons why it is safe to leave these
3859 insns inside the block: First, we know that these pseudos cannot be
3860 used in generated RTL outside the block since they are created for
3861 temporary purposes within the block. Second, CSE will not record the
3862 values of anything set inside a libcall block, so we know they must
3863 be dead at the end of the block.
3865 Except for the first group of insns (the ones setting pseudos), the
3866 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
3868 emit_libcall_block (rtx insns
, rtx target
, rtx result
, rtx equiv
)
3870 rtx final_dest
= target
;
3871 rtx prev
, next
, first
, last
, insn
;
3873 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3874 into a MEM later. Protect the libcall block from this change. */
3875 if (! REG_P (target
) || REG_USERVAR_P (target
))
3876 target
= gen_reg_rtx (GET_MODE (target
));
3878 /* If we're using non-call exceptions, a libcall corresponding to an
3879 operation that may trap may also trap. */
3880 if (flag_non_call_exceptions
&& may_trap_p (equiv
))
3882 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3885 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
3887 if (note
!= 0 && INTVAL (XEXP (note
, 0)) <= 0)
3888 remove_note (insn
, note
);
3892 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3893 reg note to indicate that this call cannot throw or execute a nonlocal
3894 goto (unless there is already a REG_EH_REGION note, in which case
3896 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
3899 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
3902 XEXP (note
, 0) = constm1_rtx
;
3904 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_EH_REGION
, constm1_rtx
,
3908 /* First emit all insns that set pseudos. Remove them from the list as
3909 we go. Avoid insns that set pseudos which were referenced in previous
3910 insns. These can be generated by move_by_pieces, for example,
3911 to update an address. Similarly, avoid insns that reference things
3912 set in previous insns. */
3914 for (insn
= insns
; insn
; insn
= next
)
3916 rtx set
= single_set (insn
);
3919 /* Some ports (cris) create a libcall regions at their own. We must
3920 avoid any potential nesting of LIBCALLs. */
3921 if ((note
= find_reg_note (insn
, REG_LIBCALL
, NULL
)) != NULL
)
3922 remove_note (insn
, note
);
3923 if ((note
= find_reg_note (insn
, REG_RETVAL
, NULL
)) != NULL
)
3924 remove_note (insn
, note
);
3925 if ((note
= find_reg_note (insn
, REG_LIBCALL_ID
, NULL
)) != NULL
)
3926 remove_note (insn
, note
);
3928 next
= NEXT_INSN (insn
);
3930 if (set
!= 0 && REG_P (SET_DEST (set
))
3931 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
)
3933 struct no_conflict_data data
;
3935 data
.target
= const0_rtx
;
3939 note_stores (PATTERN (insn
), no_conflict_move_test
, &data
);
3940 if (! data
.must_stay
)
3942 if (PREV_INSN (insn
))
3943 NEXT_INSN (PREV_INSN (insn
)) = next
;
3948 PREV_INSN (next
) = PREV_INSN (insn
);
3954 /* Some ports use a loop to copy large arguments onto the stack.
3955 Don't move anything outside such a loop. */
3960 prev
= get_last_insn ();
3962 /* Write the remaining insns followed by the final copy. */
3964 for (insn
= insns
; insn
; insn
= next
)
3966 next
= NEXT_INSN (insn
);
3971 last
= emit_move_insn (target
, result
);
3972 if (optab_handler (mov_optab
, GET_MODE (target
))->insn_code
3973 != CODE_FOR_nothing
)
3974 set_unique_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
));
3977 /* Remove any existing REG_EQUAL note from "last", or else it will
3978 be mistaken for a note referring to the full contents of the
3979 libcall value when found together with the REG_RETVAL note added
3980 below. An existing note can come from an insn expansion at
3982 remove_note (last
, find_reg_note (last
, REG_EQUAL
, NULL_RTX
));
3985 if (final_dest
!= target
)
3986 emit_move_insn (final_dest
, target
);
3989 first
= get_insns ();
3991 first
= NEXT_INSN (prev
);
3993 maybe_encapsulate_block (first
, last
, equiv
);
3996 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3997 PURPOSE describes how this comparison will be used. CODE is the rtx
3998 comparison code we will be using.
4000 ??? Actually, CODE is slightly weaker than that. A target is still
4001 required to implement all of the normal bcc operations, but not
4002 required to implement all (or any) of the unordered bcc operations. */
4005 can_compare_p (enum rtx_code code
, enum machine_mode mode
,
4006 enum can_compare_purpose purpose
)
4010 if (optab_handler (cmp_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
4012 if (purpose
== ccp_jump
)
4013 return bcc_gen_fctn
[(int) code
] != NULL
;
4014 else if (purpose
== ccp_store_flag
)
4015 return setcc_gen_code
[(int) code
] != CODE_FOR_nothing
;
4017 /* There's only one cmov entry point, and it's allowed to fail. */
4020 if (purpose
== ccp_jump
4021 && optab_handler (cbranch_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
4023 if (purpose
== ccp_cmov
4024 && optab_handler (cmov_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
4026 if (purpose
== ccp_store_flag
4027 && optab_handler (cstore_optab
, mode
)->insn_code
!= CODE_FOR_nothing
)
4029 mode
= GET_MODE_WIDER_MODE (mode
);
4031 while (mode
!= VOIDmode
);
4036 /* This function is called when we are going to emit a compare instruction that
4037 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
4039 *PMODE is the mode of the inputs (in case they are const_int).
4040 *PUNSIGNEDP nonzero says that the operands are unsigned;
4041 this matters if they need to be widened.
4043 If they have mode BLKmode, then SIZE specifies the size of both operands.
4045 This function performs all the setup necessary so that the caller only has
4046 to emit a single comparison insn. This setup can involve doing a BLKmode
4047 comparison or emitting a library call to perform the comparison if no insn
4048 is available to handle it.
4049 The values which are passed in through pointers can be modified; the caller
4050 should perform the comparison on the modified values. Constant
4051 comparisons must have already been folded. */
4054 prepare_cmp_insn (rtx
*px
, rtx
*py
, enum rtx_code
*pcomparison
, rtx size
,
4055 enum machine_mode
*pmode
, int *punsignedp
,
4056 enum can_compare_purpose purpose
)
4058 enum machine_mode mode
= *pmode
;
4059 rtx x
= *px
, y
= *py
;
4060 int unsignedp
= *punsignedp
;
4062 /* If we are inside an appropriately-short loop and we are optimizing,
4063 force expensive constants into a register. */
4064 if (CONSTANT_P (x
) && optimize
4065 && rtx_cost (x
, COMPARE
) > COSTS_N_INSNS (1))
4066 x
= force_reg (mode
, x
);
4068 if (CONSTANT_P (y
) && optimize
4069 && rtx_cost (y
, COMPARE
) > COSTS_N_INSNS (1))
4070 y
= force_reg (mode
, y
);
4073 /* Make sure if we have a canonical comparison. The RTL
4074 documentation states that canonical comparisons are required only
4075 for targets which have cc0. */
4076 gcc_assert (!CONSTANT_P (x
) || CONSTANT_P (y
));
4079 /* Don't let both operands fail to indicate the mode. */
4080 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
4081 x
= force_reg (mode
, x
);
4083 /* Handle all BLKmode compares. */
4085 if (mode
== BLKmode
)
4087 enum machine_mode cmp_mode
, result_mode
;
4088 enum insn_code cmp_code
;
4093 = GEN_INT (MIN (MEM_ALIGN (x
), MEM_ALIGN (y
)) / BITS_PER_UNIT
);
4097 /* Try to use a memory block compare insn - either cmpstr
4098 or cmpmem will do. */
4099 for (cmp_mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
4100 cmp_mode
!= VOIDmode
;
4101 cmp_mode
= GET_MODE_WIDER_MODE (cmp_mode
))
4103 cmp_code
= cmpmem_optab
[cmp_mode
];
4104 if (cmp_code
== CODE_FOR_nothing
)
4105 cmp_code
= cmpstr_optab
[cmp_mode
];
4106 if (cmp_code
== CODE_FOR_nothing
)
4107 cmp_code
= cmpstrn_optab
[cmp_mode
];
4108 if (cmp_code
== CODE_FOR_nothing
)
4111 /* Must make sure the size fits the insn's mode. */
4112 if ((GET_CODE (size
) == CONST_INT
4113 && INTVAL (size
) >= (1 << GET_MODE_BITSIZE (cmp_mode
)))
4114 || (GET_MODE_BITSIZE (GET_MODE (size
))
4115 > GET_MODE_BITSIZE (cmp_mode
)))
4118 result_mode
= insn_data
[cmp_code
].operand
[0].mode
;
4119 result
= gen_reg_rtx (result_mode
);
4120 size
= convert_to_mode (cmp_mode
, size
, 1);
4121 emit_insn (GEN_FCN (cmp_code
) (result
, x
, y
, size
, opalign
));
4125 *pmode
= result_mode
;
4129 /* Otherwise call a library function, memcmp. */
4130 libfunc
= memcmp_libfunc
;
4131 length_type
= sizetype
;
4132 result_mode
= TYPE_MODE (integer_type_node
);
4133 cmp_mode
= TYPE_MODE (length_type
);
4134 size
= convert_to_mode (TYPE_MODE (length_type
), size
,
4135 TYPE_UNSIGNED (length_type
));
4137 result
= emit_library_call_value (libfunc
, 0, LCT_PURE_MAKE_BLOCK
,
4144 *pmode
= result_mode
;
4148 /* Don't allow operands to the compare to trap, as that can put the
4149 compare and branch in different basic blocks. */
4150 if (flag_non_call_exceptions
)
4153 x
= force_reg (mode
, x
);
4155 y
= force_reg (mode
, y
);
4160 if (can_compare_p (*pcomparison
, mode
, purpose
))
4163 /* Handle a lib call just for the mode we are using. */
4165 if (optab_handler (cmp_optab
, mode
)->libfunc
&& !SCALAR_FLOAT_MODE_P (mode
))
4167 rtx libfunc
= optab_handler (cmp_optab
, mode
)->libfunc
;
4170 /* If we want unsigned, and this mode has a distinct unsigned
4171 comparison routine, use that. */
4172 if (unsignedp
&& optab_handler (ucmp_optab
, mode
)->libfunc
)
4173 libfunc
= optab_handler (ucmp_optab
, mode
)->libfunc
;
4175 result
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST_MAKE_BLOCK
,
4176 targetm
.libgcc_cmp_return_mode (),
4177 2, x
, mode
, y
, mode
);
4179 /* There are two kinds of comparison routines. Biased routines
4180 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4181 of gcc expect that the comparison operation is equivalent
4182 to the modified comparison. For signed comparisons compare the
4183 result against 1 in the biased case, and zero in the unbiased
4184 case. For unsigned comparisons always compare against 1 after
4185 biasing the unbiased result by adding 1. This gives us a way to
4191 if (!TARGET_LIB_INT_CMP_BIASED
)
4194 *px
= plus_constant (result
, 1);
4201 gcc_assert (SCALAR_FLOAT_MODE_P (mode
));
4202 prepare_float_lib_cmp (px
, py
, pcomparison
, pmode
, punsignedp
);
4205 /* Before emitting an insn with code ICODE, make sure that X, which is going
4206 to be used for operand OPNUM of the insn, is converted from mode MODE to
4207 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4208 that it is accepted by the operand predicate. Return the new value. */
4211 prepare_operand (int icode
, rtx x
, int opnum
, enum machine_mode mode
,
4212 enum machine_mode wider_mode
, int unsignedp
)
4214 if (mode
!= wider_mode
)
4215 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
4217 if (!insn_data
[icode
].operand
[opnum
].predicate
4218 (x
, insn_data
[icode
].operand
[opnum
].mode
))
4220 if (reload_completed
)
4222 x
= copy_to_mode_reg (insn_data
[icode
].operand
[opnum
].mode
, x
);
4228 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4229 we can do the comparison.
4230 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
4231 be NULL_RTX which indicates that only a comparison is to be generated. */
4234 emit_cmp_and_jump_insn_1 (rtx x
, rtx y
, enum machine_mode mode
,
4235 enum rtx_code comparison
, int unsignedp
, rtx label
)
4237 rtx test
= gen_rtx_fmt_ee (comparison
, mode
, x
, y
);
4238 enum mode_class
class = GET_MODE_CLASS (mode
);
4239 enum machine_mode wider_mode
= mode
;
4241 /* Try combined insns first. */
4244 enum insn_code icode
;
4245 PUT_MODE (test
, wider_mode
);
4249 icode
= optab_handler (cbranch_optab
, wider_mode
)->insn_code
;
4251 if (icode
!= CODE_FOR_nothing
4252 && insn_data
[icode
].operand
[0].predicate (test
, wider_mode
))
4254 x
= prepare_operand (icode
, x
, 1, mode
, wider_mode
, unsignedp
);
4255 y
= prepare_operand (icode
, y
, 2, mode
, wider_mode
, unsignedp
);
4256 emit_jump_insn (GEN_FCN (icode
) (test
, x
, y
, label
));
4261 /* Handle some compares against zero. */
4262 icode
= (int) optab_handler (tst_optab
, wider_mode
)->insn_code
;
4263 if (y
== CONST0_RTX (mode
) && icode
!= CODE_FOR_nothing
)
4265 x
= prepare_operand (icode
, x
, 0, mode
, wider_mode
, unsignedp
);
4266 emit_insn (GEN_FCN (icode
) (x
));
4268 emit_jump_insn (bcc_gen_fctn
[(int) comparison
] (label
));
4272 /* Handle compares for which there is a directly suitable insn. */
4274 icode
= (int) optab_handler (cmp_optab
, wider_mode
)->insn_code
;
4275 if (icode
!= CODE_FOR_nothing
)
4277 x
= prepare_operand (icode
, x
, 0, mode
, wider_mode
, unsignedp
);
4278 y
= prepare_operand (icode
, y
, 1, mode
, wider_mode
, unsignedp
);
4279 emit_insn (GEN_FCN (icode
) (x
, y
));
4281 emit_jump_insn (bcc_gen_fctn
[(int) comparison
] (label
));
4285 if (!CLASS_HAS_WIDER_MODES_P (class))
4288 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
);
4290 while (wider_mode
!= VOIDmode
);
4295 /* Generate code to compare X with Y so that the condition codes are
4296 set and to jump to LABEL if the condition is true. If X is a
4297 constant and Y is not a constant, then the comparison is swapped to
4298 ensure that the comparison RTL has the canonical form.
4300 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4301 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
4302 the proper branch condition code.
4304 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4306 MODE is the mode of the inputs (in case they are const_int).
4308 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
4309 be passed unchanged to emit_cmp_insn, then potentially converted into an
4310 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
4313 emit_cmp_and_jump_insns (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4314 enum machine_mode mode
, int unsignedp
, rtx label
)
4316 rtx op0
= x
, op1
= y
;
4318 /* Swap operands and condition to ensure canonical RTL. */
4319 if (swap_commutative_operands_p (x
, y
))
4321 /* If we're not emitting a branch, callers are required to pass
4322 operands in an order conforming to canonical RTL. We relax this
4323 for commutative comparisons so callers using EQ don't need to do
4324 swapping by hand. */
4325 gcc_assert (label
|| (comparison
== swap_condition (comparison
)));
4328 comparison
= swap_condition (comparison
);
4332 /* If OP0 is still a constant, then both X and Y must be constants.
4333 Force X into a register to create canonical RTL. */
4334 if (CONSTANT_P (op0
))
4335 op0
= force_reg (mode
, op0
);
4339 comparison
= unsigned_condition (comparison
);
4341 prepare_cmp_insn (&op0
, &op1
, &comparison
, size
, &mode
, &unsignedp
,
4343 emit_cmp_and_jump_insn_1 (op0
, op1
, mode
, comparison
, unsignedp
, label
);
4346 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
4349 emit_cmp_insn (rtx x
, rtx y
, enum rtx_code comparison
, rtx size
,
4350 enum machine_mode mode
, int unsignedp
)
4352 emit_cmp_and_jump_insns (x
, y
, comparison
, size
, mode
, unsignedp
, 0);
4355 /* Emit a library call comparison between floating point X and Y.
4356 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4359 prepare_float_lib_cmp (rtx
*px
, rtx
*py
, enum rtx_code
*pcomparison
,
4360 enum machine_mode
*pmode
, int *punsignedp
)
4362 enum rtx_code comparison
= *pcomparison
;
4363 enum rtx_code swapped
= swap_condition (comparison
);
4364 enum rtx_code reversed
= reverse_condition_maybe_unordered (comparison
);
4367 enum machine_mode orig_mode
= GET_MODE (x
);
4368 enum machine_mode mode
, cmp_mode
;
4369 rtx value
, target
, insns
, equiv
;
4371 bool reversed_p
= false;
4372 cmp_mode
= targetm
.libgcc_cmp_return_mode ();
4374 for (mode
= orig_mode
;
4376 mode
= GET_MODE_WIDER_MODE (mode
))
4378 if ((libfunc
= optab_handler (code_to_optab
[comparison
], mode
)->libfunc
))
4381 if ((libfunc
= optab_handler (code_to_optab
[swapped
], mode
)->libfunc
))
4384 tmp
= x
; x
= y
; y
= tmp
;
4385 comparison
= swapped
;
4389 if ((libfunc
= optab_handler (code_to_optab
[reversed
], mode
)->libfunc
)
4390 && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, reversed
))
4392 comparison
= reversed
;
4398 gcc_assert (mode
!= VOIDmode
);
4400 if (mode
!= orig_mode
)
4402 x
= convert_to_mode (mode
, x
, 0);
4403 y
= convert_to_mode (mode
, y
, 0);
4406 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4407 the RTL. The allows the RTL optimizers to delete the libcall if the
4408 condition can be determined at compile-time. */
4409 if (comparison
== UNORDERED
)
4411 rtx temp
= simplify_gen_relational (NE
, cmp_mode
, mode
, x
, x
);
4412 equiv
= simplify_gen_relational (NE
, cmp_mode
, mode
, y
, y
);
4413 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4414 temp
, const_true_rtx
, equiv
);
4418 equiv
= simplify_gen_relational (comparison
, cmp_mode
, mode
, x
, y
);
4419 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4421 rtx true_rtx
, false_rtx
;
4426 true_rtx
= const0_rtx
;
4427 false_rtx
= const_true_rtx
;
4431 true_rtx
= const_true_rtx
;
4432 false_rtx
= const0_rtx
;
4436 true_rtx
= const1_rtx
;
4437 false_rtx
= const0_rtx
;
4441 true_rtx
= const0_rtx
;
4442 false_rtx
= constm1_rtx
;
4446 true_rtx
= constm1_rtx
;
4447 false_rtx
= const0_rtx
;
4451 true_rtx
= const0_rtx
;
4452 false_rtx
= const1_rtx
;
4458 equiv
= simplify_gen_ternary (IF_THEN_ELSE
, cmp_mode
, cmp_mode
,
4459 equiv
, true_rtx
, false_rtx
);
4464 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
4465 cmp_mode
, 2, x
, mode
, y
, mode
);
4466 insns
= get_insns ();
4469 target
= gen_reg_rtx (cmp_mode
);
4470 emit_libcall_block (insns
, target
, value
, equiv
);
4472 if (comparison
== UNORDERED
4473 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
4474 comparison
= reversed_p
? EQ
: NE
;
4479 *pcomparison
= comparison
;
4483 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4486 emit_indirect_jump (rtx loc
)
4488 if (!insn_data
[(int) CODE_FOR_indirect_jump
].operand
[0].predicate
4490 loc
= copy_to_mode_reg (Pmode
, loc
);
4492 emit_jump_insn (gen_indirect_jump (loc
));
4496 #ifdef HAVE_conditional_move
4498 /* Emit a conditional move instruction if the machine supports one for that
4499 condition and machine mode.
4501 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4502 the mode to use should they be constants. If it is VOIDmode, they cannot
4505 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4506 should be stored there. MODE is the mode to use should they be constants.
4507 If it is VOIDmode, they cannot both be constants.
4509 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4510 is not supported. */
4513 emit_conditional_move (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4514 enum machine_mode cmode
, rtx op2
, rtx op3
,
4515 enum machine_mode mode
, int unsignedp
)
4517 rtx tem
, subtarget
, comparison
, insn
;
4518 enum insn_code icode
;
4519 enum rtx_code reversed
;
4521 /* If one operand is constant, make it the second one. Only do this
4522 if the other operand is not constant as well. */
4524 if (swap_commutative_operands_p (op0
, op1
))
4529 code
= swap_condition (code
);
4532 /* get_condition will prefer to generate LT and GT even if the old
4533 comparison was against zero, so undo that canonicalization here since
4534 comparisons against zero are cheaper. */
4535 if (code
== LT
&& op1
== const1_rtx
)
4536 code
= LE
, op1
= const0_rtx
;
4537 else if (code
== GT
&& op1
== constm1_rtx
)
4538 code
= GE
, op1
= const0_rtx
;
4540 if (cmode
== VOIDmode
)
4541 cmode
= GET_MODE (op0
);
4543 if (swap_commutative_operands_p (op2
, op3
)
4544 && ((reversed
= reversed_comparison_code_parts (code
, op0
, op1
, NULL
))
4553 if (mode
== VOIDmode
)
4554 mode
= GET_MODE (op2
);
4556 icode
= movcc_gen_code
[mode
];
4558 if (icode
== CODE_FOR_nothing
)
4562 target
= gen_reg_rtx (mode
);
4566 /* If the insn doesn't accept these operands, put them in pseudos. */
4568 if (!insn_data
[icode
].operand
[0].predicate
4569 (subtarget
, insn_data
[icode
].operand
[0].mode
))
4570 subtarget
= gen_reg_rtx (insn_data
[icode
].operand
[0].mode
);
4572 if (!insn_data
[icode
].operand
[2].predicate
4573 (op2
, insn_data
[icode
].operand
[2].mode
))
4574 op2
= copy_to_mode_reg (insn_data
[icode
].operand
[2].mode
, op2
);
4576 if (!insn_data
[icode
].operand
[3].predicate
4577 (op3
, insn_data
[icode
].operand
[3].mode
))
4578 op3
= copy_to_mode_reg (insn_data
[icode
].operand
[3].mode
, op3
);
4580 /* Everything should now be in the suitable form, so emit the compare insn
4581 and then the conditional move. */
4584 = compare_from_rtx (op0
, op1
, code
, unsignedp
, cmode
, NULL_RTX
);
4586 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
4587 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4588 return NULL and let the caller figure out how best to deal with this
4590 if (GET_CODE (comparison
) != code
)
4593 insn
= GEN_FCN (icode
) (subtarget
, comparison
, op2
, op3
);
4595 /* If that failed, then give up. */
4601 if (subtarget
!= target
)
4602 convert_move (target
, subtarget
, 0);
4607 /* Return nonzero if a conditional move of mode MODE is supported.
4609 This function is for combine so it can tell whether an insn that looks
4610 like a conditional move is actually supported by the hardware. If we
4611 guess wrong we lose a bit on optimization, but that's it. */
4612 /* ??? sparc64 supports conditionally moving integers values based on fp
4613 comparisons, and vice versa. How do we handle them? */
4616 can_conditionally_move_p (enum machine_mode mode
)
4618 if (movcc_gen_code
[mode
] != CODE_FOR_nothing
)
4624 #endif /* HAVE_conditional_move */
4626 /* Emit a conditional addition instruction if the machine supports one for that
4627 condition and machine mode.
4629 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4630 the mode to use should they be constants. If it is VOIDmode, they cannot
4633 OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4634 should be stored there. MODE is the mode to use should they be constants.
4635 If it is VOIDmode, they cannot both be constants.
4637 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4638 is not supported. */
4641 emit_conditional_add (rtx target
, enum rtx_code code
, rtx op0
, rtx op1
,
4642 enum machine_mode cmode
, rtx op2
, rtx op3
,
4643 enum machine_mode mode
, int unsignedp
)
4645 rtx tem
, subtarget
, comparison
, insn
;
4646 enum insn_code icode
;
4647 enum rtx_code reversed
;
4649 /* If one operand is constant, make it the second one. Only do this
4650 if the other operand is not constant as well. */
4652 if (swap_commutative_operands_p (op0
, op1
))
4657 code
= swap_condition (code
);
4660 /* get_condition will prefer to generate LT and GT even if the old
4661 comparison was against zero, so undo that canonicalization here since
4662 comparisons against zero are cheaper. */
4663 if (code
== LT
&& op1
== const1_rtx
)
4664 code
= LE
, op1
= const0_rtx
;
4665 else if (code
== GT
&& op1
== constm1_rtx
)
4666 code
= GE
, op1
= const0_rtx
;
4668 if (cmode
== VOIDmode
)
4669 cmode
= GET_MODE (op0
);
4671 if (swap_commutative_operands_p (op2
, op3
)
4672 && ((reversed
= reversed_comparison_code_parts (code
, op0
, op1
, NULL
))
4681 if (mode
== VOIDmode
)
4682 mode
= GET_MODE (op2
);
4684 icode
= optab_handler (addcc_optab
, mode
)->insn_code
;
4686 if (icode
== CODE_FOR_nothing
)
4690 target
= gen_reg_rtx (mode
);
4692 /* If the insn doesn't accept these operands, put them in pseudos. */
4694 if (!insn_data
[icode
].operand
[0].predicate
4695 (target
, insn_data
[icode
].operand
[0].mode
))
4696 subtarget
= gen_reg_rtx (insn_data
[icode
].operand
[0].mode
);
4700 if (!insn_data
[icode
].operand
[2].predicate
4701 (op2
, insn_data
[icode
].operand
[2].mode
))
4702 op2
= copy_to_mode_reg (insn_data
[icode
].operand
[2].mode
, op2
);
4704 if (!insn_data
[icode
].operand
[3].predicate
4705 (op3
, insn_data
[icode
].operand
[3].mode
))
4706 op3
= copy_to_mode_reg (insn_data
[icode
].operand
[3].mode
, op3
);
4708 /* Everything should now be in the suitable form, so emit the compare insn
4709 and then the conditional move. */
4712 = compare_from_rtx (op0
, op1
, code
, unsignedp
, cmode
, NULL_RTX
);
4714 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
4715 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4716 return NULL and let the caller figure out how best to deal with this
4718 if (GET_CODE (comparison
) != code
)
4721 insn
= GEN_FCN (icode
) (subtarget
, comparison
, op2
, op3
);
4723 /* If that failed, then give up. */
4729 if (subtarget
!= target
)
4730 convert_move (target
, subtarget
, 0);
4735 /* These functions attempt to generate an insn body, rather than
4736 emitting the insn, but if the gen function already emits them, we
4737 make no attempt to turn them back into naked patterns. */
4739 /* Generate and return an insn body to add Y to X. */
4742 gen_add2_insn (rtx x
, rtx y
)
4744 int icode
= (int) optab_handler (add_optab
, GET_MODE (x
))->insn_code
;
4746 gcc_assert (insn_data
[icode
].operand
[0].predicate
4747 (x
, insn_data
[icode
].operand
[0].mode
));
4748 gcc_assert (insn_data
[icode
].operand
[1].predicate
4749 (x
, insn_data
[icode
].operand
[1].mode
));
4750 gcc_assert (insn_data
[icode
].operand
[2].predicate
4751 (y
, insn_data
[icode
].operand
[2].mode
));
4753 return GEN_FCN (icode
) (x
, x
, y
);
4756 /* Generate and return an insn body to add r1 and c,
4757 storing the result in r0. */
4759 gen_add3_insn (rtx r0
, rtx r1
, rtx c
)
4761 int icode
= (int) optab_handler (add_optab
, GET_MODE (r0
))->insn_code
;
4763 if (icode
== CODE_FOR_nothing
4764 || !(insn_data
[icode
].operand
[0].predicate
4765 (r0
, insn_data
[icode
].operand
[0].mode
))
4766 || !(insn_data
[icode
].operand
[1].predicate
4767 (r1
, insn_data
[icode
].operand
[1].mode
))
4768 || !(insn_data
[icode
].operand
[2].predicate
4769 (c
, insn_data
[icode
].operand
[2].mode
)))
4772 return GEN_FCN (icode
) (r0
, r1
, c
);
4776 have_add2_insn (rtx x
, rtx y
)
4780 gcc_assert (GET_MODE (x
) != VOIDmode
);
4782 icode
= (int) optab_handler (add_optab
, GET_MODE (x
))->insn_code
;
4784 if (icode
== CODE_FOR_nothing
)
4787 if (!(insn_data
[icode
].operand
[0].predicate
4788 (x
, insn_data
[icode
].operand
[0].mode
))
4789 || !(insn_data
[icode
].operand
[1].predicate
4790 (x
, insn_data
[icode
].operand
[1].mode
))
4791 || !(insn_data
[icode
].operand
[2].predicate
4792 (y
, insn_data
[icode
].operand
[2].mode
)))
4798 /* Generate and return an insn body to subtract Y from X. */
4801 gen_sub2_insn (rtx x
, rtx y
)
4803 int icode
= (int) optab_handler (sub_optab
, GET_MODE (x
))->insn_code
;
4805 gcc_assert (insn_data
[icode
].operand
[0].predicate
4806 (x
, insn_data
[icode
].operand
[0].mode
));
4807 gcc_assert (insn_data
[icode
].operand
[1].predicate
4808 (x
, insn_data
[icode
].operand
[1].mode
));
4809 gcc_assert (insn_data
[icode
].operand
[2].predicate
4810 (y
, insn_data
[icode
].operand
[2].mode
));
4812 return GEN_FCN (icode
) (x
, x
, y
);
4815 /* Generate and return an insn body to subtract r1 and c,
4816 storing the result in r0. */
4818 gen_sub3_insn (rtx r0
, rtx r1
, rtx c
)
4820 int icode
= (int) optab_handler (sub_optab
, GET_MODE (r0
))->insn_code
;
4822 if (icode
== CODE_FOR_nothing
4823 || !(insn_data
[icode
].operand
[0].predicate
4824 (r0
, insn_data
[icode
].operand
[0].mode
))
4825 || !(insn_data
[icode
].operand
[1].predicate
4826 (r1
, insn_data
[icode
].operand
[1].mode
))
4827 || !(insn_data
[icode
].operand
[2].predicate
4828 (c
, insn_data
[icode
].operand
[2].mode
)))
4831 return GEN_FCN (icode
) (r0
, r1
, c
);
4835 have_sub2_insn (rtx x
, rtx y
)
4839 gcc_assert (GET_MODE (x
) != VOIDmode
);
4841 icode
= (int) optab_handler (sub_optab
, GET_MODE (x
))->insn_code
;
4843 if (icode
== CODE_FOR_nothing
)
4846 if (!(insn_data
[icode
].operand
[0].predicate
4847 (x
, insn_data
[icode
].operand
[0].mode
))
4848 || !(insn_data
[icode
].operand
[1].predicate
4849 (x
, insn_data
[icode
].operand
[1].mode
))
4850 || !(insn_data
[icode
].operand
[2].predicate
4851 (y
, insn_data
[icode
].operand
[2].mode
)))
4857 /* Generate the body of an instruction to copy Y into X.
4858 It may be a list of insns, if one insn isn't enough. */
4861 gen_move_insn (rtx x
, rtx y
)
4866 emit_move_insn_1 (x
, y
);
4872 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4873 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4874 no such operation exists, CODE_FOR_nothing will be returned. */
4877 can_extend_p (enum machine_mode to_mode
, enum machine_mode from_mode
,
4881 #ifdef HAVE_ptr_extend
4883 return CODE_FOR_ptr_extend
;
4886 tab
= unsignedp
? zext_optab
: sext_optab
;
4887 return convert_optab_handler (tab
, to_mode
, from_mode
)->insn_code
;
4890 /* Generate the body of an insn to extend Y (with mode MFROM)
4891 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4894 gen_extend_insn (rtx x
, rtx y
, enum machine_mode mto
,
4895 enum machine_mode mfrom
, int unsignedp
)
4897 enum insn_code icode
= can_extend_p (mto
, mfrom
, unsignedp
);
4898 return GEN_FCN (icode
) (x
, y
);
4901 /* can_fix_p and can_float_p say whether the target machine
4902 can directly convert a given fixed point type to
4903 a given floating point type, or vice versa.
4904 The returned value is the CODE_FOR_... value to use,
4905 or CODE_FOR_nothing if these modes cannot be directly converted.
4907 *TRUNCP_PTR is set to 1 if it is necessary to output
4908 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4910 static enum insn_code
4911 can_fix_p (enum machine_mode fixmode
, enum machine_mode fltmode
,
4912 int unsignedp
, int *truncp_ptr
)
4915 enum insn_code icode
;
4917 tab
= unsignedp
? ufixtrunc_optab
: sfixtrunc_optab
;
4918 icode
= convert_optab_handler (tab
, fixmode
, fltmode
)->insn_code
;
4919 if (icode
!= CODE_FOR_nothing
)
4925 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4926 for this to work. We need to rework the fix* and ftrunc* patterns
4927 and documentation. */
4928 tab
= unsignedp
? ufix_optab
: sfix_optab
;
4929 icode
= convert_optab_handler (tab
, fixmode
, fltmode
)->insn_code
;
4930 if (icode
!= CODE_FOR_nothing
4931 && optab_handler (ftrunc_optab
, fltmode
)->insn_code
!= CODE_FOR_nothing
)
4938 return CODE_FOR_nothing
;
4941 static enum insn_code
4942 can_float_p (enum machine_mode fltmode
, enum machine_mode fixmode
,
4947 tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
4948 return convert_optab_handler (tab
, fltmode
, fixmode
)->insn_code
;
4951 /* Generate code to convert FROM to floating point
4952 and store in TO. FROM must be fixed point and not VOIDmode.
4953 UNSIGNEDP nonzero means regard FROM as unsigned.
4954 Normally this is done by correcting the final value
4955 if it is negative. */
4958 expand_float (rtx to
, rtx from
, int unsignedp
)
4960 enum insn_code icode
;
4962 enum machine_mode fmode
, imode
;
4963 bool can_do_signed
= false;
4965 /* Crash now, because we won't be able to decide which mode to use. */
4966 gcc_assert (GET_MODE (from
) != VOIDmode
);
4968 /* Look for an insn to do the conversion. Do it in the specified
4969 modes if possible; otherwise convert either input, output or both to
4970 wider mode. If the integer mode is wider than the mode of FROM,
4971 we can do the conversion signed even if the input is unsigned. */
4973 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
4974 fmode
= GET_MODE_WIDER_MODE (fmode
))
4975 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
4976 imode
= GET_MODE_WIDER_MODE (imode
))
4978 int doing_unsigned
= unsignedp
;
4980 if (fmode
!= GET_MODE (to
)
4981 && significand_size (fmode
) < GET_MODE_BITSIZE (GET_MODE (from
)))
4984 icode
= can_float_p (fmode
, imode
, unsignedp
);
4985 if (icode
== CODE_FOR_nothing
&& unsignedp
)
4987 enum insn_code scode
= can_float_p (fmode
, imode
, 0);
4988 if (scode
!= CODE_FOR_nothing
)
4989 can_do_signed
= true;
4990 if (imode
!= GET_MODE (from
))
4991 icode
= scode
, doing_unsigned
= 0;
4994 if (icode
!= CODE_FOR_nothing
)
4996 if (imode
!= GET_MODE (from
))
4997 from
= convert_to_mode (imode
, from
, unsignedp
);
4999 if (fmode
!= GET_MODE (to
))
5000 target
= gen_reg_rtx (fmode
);
5002 emit_unop_insn (icode
, target
, from
,
5003 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
5006 convert_move (to
, target
, 0);
5011 /* Unsigned integer, and no way to convert directly. For binary
5012 floating point modes, convert as signed, then conditionally adjust
5014 if (unsignedp
&& can_do_signed
&& !DECIMAL_FLOAT_MODE_P (GET_MODE (to
)))
5016 rtx label
= gen_label_rtx ();
5018 REAL_VALUE_TYPE offset
;
5020 /* Look for a usable floating mode FMODE wider than the source and at
5021 least as wide as the target. Using FMODE will avoid rounding woes
5022 with unsigned values greater than the signed maximum value. */
5024 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
5025 fmode
= GET_MODE_WIDER_MODE (fmode
))
5026 if (GET_MODE_BITSIZE (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
5027 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
5030 if (fmode
== VOIDmode
)
5032 /* There is no such mode. Pretend the target is wide enough. */
5033 fmode
= GET_MODE (to
);
5035 /* Avoid double-rounding when TO is narrower than FROM. */
5036 if ((significand_size (fmode
) + 1)
5037 < GET_MODE_BITSIZE (GET_MODE (from
)))
5040 rtx neglabel
= gen_label_rtx ();
5042 /* Don't use TARGET if it isn't a register, is a hard register,
5043 or is the wrong mode. */
5045 || REGNO (target
) < FIRST_PSEUDO_REGISTER
5046 || GET_MODE (target
) != fmode
)
5047 target
= gen_reg_rtx (fmode
);
5049 imode
= GET_MODE (from
);
5050 do_pending_stack_adjust ();
5052 /* Test whether the sign bit is set. */
5053 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
5056 /* The sign bit is not set. Convert as signed. */
5057 expand_float (target
, from
, 0);
5058 emit_jump_insn (gen_jump (label
));
5061 /* The sign bit is set.
5062 Convert to a usable (positive signed) value by shifting right
5063 one bit, while remembering if a nonzero bit was shifted
5064 out; i.e., compute (from & 1) | (from >> 1). */
5066 emit_label (neglabel
);
5067 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
5068 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5069 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, integer_one_node
,
5071 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
5073 expand_float (target
, temp
, 0);
5075 /* Multiply by 2 to undo the shift above. */
5076 temp
= expand_binop (fmode
, add_optab
, target
, target
,
5077 target
, 0, OPTAB_LIB_WIDEN
);
5079 emit_move_insn (target
, temp
);
5081 do_pending_stack_adjust ();
5087 /* If we are about to do some arithmetic to correct for an
5088 unsigned operand, do it in a pseudo-register. */
5090 if (GET_MODE (to
) != fmode
5091 || !REG_P (to
) || REGNO (to
) < FIRST_PSEUDO_REGISTER
)
5092 target
= gen_reg_rtx (fmode
);
5094 /* Convert as signed integer to floating. */
5095 expand_float (target
, from
, 0);
5097 /* If FROM is negative (and therefore TO is negative),
5098 correct its value by 2**bitwidth. */
5100 do_pending_stack_adjust ();
5101 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
),
5105 real_2expN (&offset
, GET_MODE_BITSIZE (GET_MODE (from
)));
5106 temp
= expand_binop (fmode
, add_optab
, target
,
5107 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
5108 target
, 0, OPTAB_LIB_WIDEN
);
5110 emit_move_insn (target
, temp
);
5112 do_pending_stack_adjust ();
5117 /* No hardware instruction available; call a library routine. */
5122 convert_optab tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
5124 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
5125 from
= convert_to_mode (SImode
, from
, unsignedp
);
5127 libfunc
= convert_optab_handler (tab
, GET_MODE (to
),
5128 GET_MODE (from
))->libfunc
;
5129 gcc_assert (libfunc
);
5133 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5134 GET_MODE (to
), 1, from
,
5136 insns
= get_insns ();
5139 emit_libcall_block (insns
, target
, value
,
5140 gen_rtx_FLOAT (GET_MODE (to
), from
));
5145 /* Copy result to requested destination
5146 if we have been computing in a temp location. */
5150 if (GET_MODE (target
) == GET_MODE (to
))
5151 emit_move_insn (to
, target
);
5153 convert_move (to
, target
, 0);
5157 /* Generate code to convert FROM to fixed point and store in TO. FROM
5158 must be floating point. */
5161 expand_fix (rtx to
, rtx from
, int unsignedp
)
5163 enum insn_code icode
;
5165 enum machine_mode fmode
, imode
;
5168 /* We first try to find a pair of modes, one real and one integer, at
5169 least as wide as FROM and TO, respectively, in which we can open-code
5170 this conversion. If the integer mode is wider than the mode of TO,
5171 we can do the conversion either signed or unsigned. */
5173 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5174 fmode
= GET_MODE_WIDER_MODE (fmode
))
5175 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
5176 imode
= GET_MODE_WIDER_MODE (imode
))
5178 int doing_unsigned
= unsignedp
;
5180 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
5181 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
5182 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
5184 if (icode
!= CODE_FOR_nothing
)
5186 if (fmode
!= GET_MODE (from
))
5187 from
= convert_to_mode (fmode
, from
, 0);
5191 rtx temp
= gen_reg_rtx (GET_MODE (from
));
5192 from
= expand_unop (GET_MODE (from
), ftrunc_optab
, from
,
5196 if (imode
!= GET_MODE (to
))
5197 target
= gen_reg_rtx (imode
);
5199 emit_unop_insn (icode
, target
, from
,
5200 doing_unsigned
? UNSIGNED_FIX
: FIX
);
5202 convert_move (to
, target
, unsignedp
);
5207 /* For an unsigned conversion, there is one more way to do it.
5208 If we have a signed conversion, we generate code that compares
5209 the real value to the largest representable positive number. If if
5210 is smaller, the conversion is done normally. Otherwise, subtract
5211 one plus the highest signed number, convert, and add it back.
5213 We only need to check all real modes, since we know we didn't find
5214 anything with a wider integer mode.
5216 This code used to extend FP value into mode wider than the destination.
5217 This is not needed. Consider, for instance conversion from SFmode
5220 The hot path through the code is dealing with inputs smaller than 2^63
5221 and doing just the conversion, so there is no bits to lose.
5223 In the other path we know the value is positive in the range 2^63..2^64-1
5224 inclusive. (as for other imput overflow happens and result is undefined)
5225 So we know that the most important bit set in mantissa corresponds to
5226 2^63. The subtraction of 2^63 should not generate any rounding as it
5227 simply clears out that bit. The rest is trivial. */
5229 if (unsignedp
&& GET_MODE_BITSIZE (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
5230 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5231 fmode
= GET_MODE_WIDER_MODE (fmode
))
5232 if (CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0,
5236 REAL_VALUE_TYPE offset
;
5237 rtx limit
, lab1
, lab2
, insn
;
5239 bitsize
= GET_MODE_BITSIZE (GET_MODE (to
));
5240 real_2expN (&offset
, bitsize
- 1);
5241 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
5242 lab1
= gen_label_rtx ();
5243 lab2
= gen_label_rtx ();
5245 if (fmode
!= GET_MODE (from
))
5246 from
= convert_to_mode (fmode
, from
, 0);
5248 /* See if we need to do the subtraction. */
5249 do_pending_stack_adjust ();
5250 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
),
5253 /* If not, do the signed "fix" and branch around fixup code. */
5254 expand_fix (to
, from
, 0);
5255 emit_jump_insn (gen_jump (lab2
));
5258 /* Otherwise, subtract 2**(N-1), convert to signed number,
5259 then add 2**(N-1). Do the addition using XOR since this
5260 will often generate better code. */
5262 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
5263 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
5264 expand_fix (to
, target
, 0);
5265 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
5267 ((HOST_WIDE_INT
) 1 << (bitsize
- 1),
5269 to
, 1, OPTAB_LIB_WIDEN
);
5272 emit_move_insn (to
, target
);
5276 if (optab_handler (mov_optab
, GET_MODE (to
))->insn_code
5277 != CODE_FOR_nothing
)
5279 /* Make a place for a REG_NOTE and add it. */
5280 insn
= emit_move_insn (to
, to
);
5281 set_unique_reg_note (insn
,
5283 gen_rtx_fmt_e (UNSIGNED_FIX
,
5291 /* We can't do it with an insn, so use a library call. But first ensure
5292 that the mode of TO is at least as wide as SImode, since those are the
5293 only library calls we know about. */
5295 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
5297 target
= gen_reg_rtx (SImode
);
5299 expand_fix (target
, from
, unsignedp
);
5307 convert_optab tab
= unsignedp
? ufix_optab
: sfix_optab
;
5308 libfunc
= convert_optab_handler (tab
, GET_MODE (to
),
5309 GET_MODE (from
))->libfunc
;
5310 gcc_assert (libfunc
);
5314 value
= emit_library_call_value (libfunc
, NULL_RTX
, LCT_CONST
,
5315 GET_MODE (to
), 1, from
,
5317 insns
= get_insns ();
5320 emit_libcall_block (insns
, target
, value
,
5321 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
5322 GET_MODE (to
), from
));
5327 if (GET_MODE (to
) == GET_MODE (target
))
5328 emit_move_insn (to
, target
);
5330 convert_move (to
, target
, 0);
5334 /* Generate code to convert FROM to fixed point and store in TO. FROM
5335 must be floating point, TO must be signed. Use the conversion optab
5336 TAB to do the conversion. */
5339 expand_sfix_optab (rtx to
, rtx from
, convert_optab tab
)
5341 enum insn_code icode
;
5343 enum machine_mode fmode
, imode
;
5345 /* We first try to find a pair of modes, one real and one integer, at
5346 least as wide as FROM and TO, respectively, in which we can open-code
5347 this conversion. If the integer mode is wider than the mode of TO,
5348 we can do the conversion either signed or unsigned. */
5350 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
5351 fmode
= GET_MODE_WIDER_MODE (fmode
))
5352 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
5353 imode
= GET_MODE_WIDER_MODE (imode
))
5355 icode
= convert_optab_handler (tab
, imode
, fmode
)->insn_code
;
5356 if (icode
!= CODE_FOR_nothing
)
5358 if (fmode
!= GET_MODE (from
))
5359 from
= convert_to_mode (fmode
, from
, 0);
5361 if (imode
!= GET_MODE (to
))
5362 target
= gen_reg_rtx (imode
);
5364 emit_unop_insn (icode
, target
, from
, UNKNOWN
);
5366 convert_move (to
, target
, 0);
5374 /* Report whether we have an instruction to perform the operation
5375 specified by CODE on operands of mode MODE. */
5377 have_insn_for (enum rtx_code code
, enum machine_mode mode
)
5379 return (code_to_optab
[(int) code
] != 0
5380 && (optab_handler (code_to_optab
[(int) code
], mode
)->insn_code
5381 != CODE_FOR_nothing
));
5384 /* Create a blank optab. */
5389 optab op
= ggc_alloc (sizeof (struct optab
));
5390 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
5392 optab_handler (op
, i
)->insn_code
= CODE_FOR_nothing
;
5393 optab_handler (op
, i
)->libfunc
= 0;
5399 static convert_optab
5400 new_convert_optab (void)
5403 convert_optab op
= ggc_alloc (sizeof (struct convert_optab
));
5404 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
5405 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
5407 convert_optab_handler (op
, i
, j
)->insn_code
= CODE_FOR_nothing
;
5408 convert_optab_handler (op
, i
, j
)->libfunc
= 0;
5413 /* Same, but fill in its code as CODE, and write it into the
5414 code_to_optab table. */
5416 init_optab (enum rtx_code code
)
5418 optab op
= new_optab ();
5420 code_to_optab
[(int) code
] = op
;
5424 /* Same, but fill in its code as CODE, and do _not_ write it into
5425 the code_to_optab table. */
5427 init_optabv (enum rtx_code code
)
5429 optab op
= new_optab ();
5434 /* Conversion optabs never go in the code_to_optab table. */
5435 static inline convert_optab
5436 init_convert_optab (enum rtx_code code
)
5438 convert_optab op
= new_convert_optab ();
5443 /* Initialize the libfunc fields of an entire group of entries in some
5444 optab. Each entry is set equal to a string consisting of a leading
5445 pair of underscores followed by a generic operation name followed by
5446 a mode name (downshifted to lowercase) followed by a single character
5447 representing the number of operands for the given operation (which is
5448 usually one of the characters '2', '3', or '4').
5450 OPTABLE is the table in which libfunc fields are to be initialized.
5451 FIRST_MODE is the first machine mode index in the given optab to
5453 LAST_MODE is the last machine mode index in the given optab to
5455 OPNAME is the generic (string) name of the operation.
5456 SUFFIX is the character which specifies the number of operands for
5457 the given generic operation.
5461 init_libfuncs (optab optable
, int first_mode
, int last_mode
,
5462 const char *opname
, int suffix
)
5465 unsigned opname_len
= strlen (opname
);
5467 for (mode
= first_mode
; (int) mode
<= (int) last_mode
;
5468 mode
= (enum machine_mode
) ((int) mode
+ 1))
5470 const char *mname
= GET_MODE_NAME (mode
);
5471 unsigned mname_len
= strlen (mname
);
5472 char *libfunc_name
= alloca (2 + opname_len
+ mname_len
+ 1 + 1);
5479 for (q
= opname
; *q
; )
5481 for (q
= mname
; *q
; q
++)
5482 *p
++ = TOLOWER (*q
);
5486 optab_handler (optable
, mode
)->libfunc
5487 = init_one_libfunc (ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
5491 /* Initialize the libfunc fields of an entire group of entries in some
5492 optab which correspond to all integer mode operations. The parameters
5493 have the same meaning as similarly named ones for the `init_libfuncs'
5494 routine. (See above). */
5497 init_integral_libfuncs (optab optable
, const char *opname
, int suffix
)
5499 int maxsize
= 2*BITS_PER_WORD
;
5500 if (maxsize
< LONG_LONG_TYPE_SIZE
)
5501 maxsize
= LONG_LONG_TYPE_SIZE
;
5502 init_libfuncs (optable
, word_mode
,
5503 mode_for_size (maxsize
, MODE_INT
, 0),
5507 /* Initialize the libfunc fields of an entire group of entries in some
5508 optab which correspond to all real mode operations. The parameters
5509 have the same meaning as similarly named ones for the `init_libfuncs'
5510 routine. (See above). */
5513 init_floating_libfuncs (optab optable
, const char *opname
, int suffix
)
5515 char *dec_opname
= alloca (sizeof (DECIMAL_PREFIX
) + strlen (opname
));
5517 /* For BID support, change the name to have either a bid_ or dpd_ prefix
5518 depending on the low level floating format used. */
5519 memcpy (dec_opname
, DECIMAL_PREFIX
, sizeof (DECIMAL_PREFIX
) - 1);
5520 strcpy (dec_opname
+ sizeof (DECIMAL_PREFIX
) - 1, opname
);
5522 init_libfuncs (optable
, MIN_MODE_FLOAT
, MAX_MODE_FLOAT
, opname
, suffix
);
5523 init_libfuncs (optable
, MIN_MODE_DECIMAL_FLOAT
, MAX_MODE_DECIMAL_FLOAT
,
5524 dec_opname
, suffix
);
5527 /* Initialize the libfunc fields of an entire group of entries of an
5528 inter-mode-class conversion optab. The string formation rules are
5529 similar to the ones for init_libfuncs, above, but instead of having
5530 a mode name and an operand count these functions have two mode names
5531 and no operand count. */
5533 init_interclass_conv_libfuncs (convert_optab tab
, const char *opname
,
5534 enum mode_class from_class
,
5535 enum mode_class to_class
)
5537 enum machine_mode first_from_mode
= GET_CLASS_NARROWEST_MODE (from_class
);
5538 enum machine_mode first_to_mode
= GET_CLASS_NARROWEST_MODE (to_class
);
5539 size_t opname_len
= strlen (opname
);
5540 size_t max_mname_len
= 0;
5542 enum machine_mode fmode
, tmode
;
5543 const char *fname
, *tname
;
5545 char *libfunc_name
, *suffix
;
5546 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
5549 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5550 depends on which underlying decimal floating point format is used. */
5551 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
5553 for (fmode
= first_from_mode
;
5555 fmode
= GET_MODE_WIDER_MODE (fmode
))
5556 max_mname_len
= MAX (max_mname_len
, strlen (GET_MODE_NAME (fmode
)));
5558 for (tmode
= first_to_mode
;
5560 tmode
= GET_MODE_WIDER_MODE (tmode
))
5561 max_mname_len
= MAX (max_mname_len
, strlen (GET_MODE_NAME (tmode
)));
5563 nondec_name
= alloca (2 + opname_len
+ 2*max_mname_len
+ 1 + 1);
5564 nondec_name
[0] = '_';
5565 nondec_name
[1] = '_';
5566 memcpy (&nondec_name
[2], opname
, opname_len
);
5567 nondec_suffix
= nondec_name
+ opname_len
+ 2;
5569 dec_name
= alloca (2 + dec_len
+ opname_len
+ 2*max_mname_len
+ 1 + 1);
5572 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
5573 memcpy (&dec_name
[2+dec_len
], opname
, opname_len
);
5574 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
5576 for (fmode
= first_from_mode
; fmode
!= VOIDmode
;
5577 fmode
= GET_MODE_WIDER_MODE (fmode
))
5578 for (tmode
= first_to_mode
; tmode
!= VOIDmode
;
5579 tmode
= GET_MODE_WIDER_MODE (tmode
))
5581 fname
= GET_MODE_NAME (fmode
);
5582 tname
= GET_MODE_NAME (tmode
);
5584 if (DECIMAL_FLOAT_MODE_P(fmode
) || DECIMAL_FLOAT_MODE_P(tmode
))
5586 libfunc_name
= dec_name
;
5587 suffix
= dec_suffix
;
5591 libfunc_name
= nondec_name
;
5592 suffix
= nondec_suffix
;
5596 for (q
= fname
; *q
; p
++, q
++)
5598 for (q
= tname
; *q
; p
++, q
++)
5603 convert_optab_handler (tab
, tmode
, fmode
)->libfunc
5604 = init_one_libfunc (ggc_alloc_string (libfunc_name
,
5609 /* Initialize the libfunc fields of an entire group of entries of an
5610 intra-mode-class conversion optab. The string formation rules are
5611 similar to the ones for init_libfunc, above. WIDENING says whether
5612 the optab goes from narrow to wide modes or vice versa. These functions
5613 have two mode names _and_ an operand count. */
5615 init_intraclass_conv_libfuncs (convert_optab tab
, const char *opname
,
5616 enum mode_class
class, bool widening
)
5618 enum machine_mode first_mode
= GET_CLASS_NARROWEST_MODE (class);
5619 size_t opname_len
= strlen (opname
);
5620 size_t max_mname_len
= 0;
5622 enum machine_mode nmode
, wmode
;
5623 const char *nname
, *wname
;
5625 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
5626 char *libfunc_name
, *suffix
;
5629 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5630 depends on which underlying decimal floating point format is used. */
5631 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
5633 for (nmode
= first_mode
; nmode
!= VOIDmode
;
5634 nmode
= GET_MODE_WIDER_MODE (nmode
))
5635 max_mname_len
= MAX (max_mname_len
, strlen (GET_MODE_NAME (nmode
)));
5637 nondec_name
= alloca (2 + opname_len
+ 2*max_mname_len
+ 1 + 1);
5638 nondec_name
[0] = '_';
5639 nondec_name
[1] = '_';
5640 memcpy (&nondec_name
[2], opname
, opname_len
);
5641 nondec_suffix
= nondec_name
+ opname_len
+ 2;
5643 dec_name
= alloca (2 + dec_len
+ opname_len
+ 2*max_mname_len
+ 1 + 1);
5646 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
5647 memcpy (&dec_name
[2 + dec_len
], opname
, opname_len
);
5648 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
5650 for (nmode
= first_mode
; nmode
!= VOIDmode
;
5651 nmode
= GET_MODE_WIDER_MODE (nmode
))
5652 for (wmode
= GET_MODE_WIDER_MODE (nmode
); wmode
!= VOIDmode
;
5653 wmode
= GET_MODE_WIDER_MODE (wmode
))
5655 nname
= GET_MODE_NAME (nmode
);
5656 wname
= GET_MODE_NAME (wmode
);
5658 if (DECIMAL_FLOAT_MODE_P(nmode
) || DECIMAL_FLOAT_MODE_P(wmode
))
5660 libfunc_name
= dec_name
;
5661 suffix
= dec_suffix
;
5665 libfunc_name
= nondec_name
;
5666 suffix
= nondec_suffix
;
5670 for (q
= widening
? nname
: wname
; *q
; p
++, q
++)
5672 for (q
= widening
? wname
: nname
; *q
; p
++, q
++)
5678 convert_optab_handler(tab
, widening
? wmode
: nmode
,
5679 widening
? nmode
: wmode
)->libfunc
5680 = init_one_libfunc (ggc_alloc_string (libfunc_name
,
5687 init_one_libfunc (const char *name
)
5691 /* Create a FUNCTION_DECL that can be passed to
5692 targetm.encode_section_info. */
5693 /* ??? We don't have any type information except for this is
5694 a function. Pretend this is "int foo()". */
5695 tree decl
= build_decl (FUNCTION_DECL
, get_identifier (name
),
5696 build_function_type (integer_type_node
, NULL_TREE
));
5697 DECL_ARTIFICIAL (decl
) = 1;
5698 DECL_EXTERNAL (decl
) = 1;
5699 TREE_PUBLIC (decl
) = 1;
5701 symbol
= XEXP (DECL_RTL (decl
), 0);
5703 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
5704 are the flags assigned by targetm.encode_section_info. */
5705 SET_SYMBOL_REF_DECL (symbol
, 0);
5710 /* Call this to reset the function entry for one optab (OPTABLE) in mode
5711 MODE to NAME, which should be either 0 or a string constant. */
5713 set_optab_libfunc (optab optable
, enum machine_mode mode
, const char *name
)
5716 optab_handler (optable
, mode
)->libfunc
= init_one_libfunc (name
);
5718 optab_handler (optable
, mode
)->libfunc
= 0;
5721 /* Call this to reset the function entry for one conversion optab
5722 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
5723 either 0 or a string constant. */
5725 set_conv_libfunc (convert_optab optable
, enum machine_mode tmode
,
5726 enum machine_mode fmode
, const char *name
)
5729 convert_optab_handler (optable
, tmode
, fmode
)->libfunc
5730 = init_one_libfunc (name
);
5732 convert_optab_handler (optable
, tmode
, fmode
)->libfunc
= 0;
5735 /* Call this to initialize the contents of the optabs
5736 appropriately for the current target machine. */
5742 enum machine_mode int_mode
;
5744 /* Start by initializing all tables to contain CODE_FOR_nothing. */
5746 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
5747 setcc_gen_code
[i
] = CODE_FOR_nothing
;
5749 #ifdef HAVE_conditional_move
5750 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
5751 movcc_gen_code
[i
] = CODE_FOR_nothing
;
5754 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
5756 vcond_gen_code
[i
] = CODE_FOR_nothing
;
5757 vcondu_gen_code
[i
] = CODE_FOR_nothing
;
5760 add_optab
= init_optab (PLUS
);
5761 addv_optab
= init_optabv (PLUS
);
5762 sub_optab
= init_optab (MINUS
);
5763 subv_optab
= init_optabv (MINUS
);
5764 smul_optab
= init_optab (MULT
);
5765 smulv_optab
= init_optabv (MULT
);
5766 smul_highpart_optab
= init_optab (UNKNOWN
);
5767 umul_highpart_optab
= init_optab (UNKNOWN
);
5768 smul_widen_optab
= init_optab (UNKNOWN
);
5769 umul_widen_optab
= init_optab (UNKNOWN
);
5770 usmul_widen_optab
= init_optab (UNKNOWN
);
5771 smadd_widen_optab
= init_optab (UNKNOWN
);
5772 umadd_widen_optab
= init_optab (UNKNOWN
);
5773 smsub_widen_optab
= init_optab (UNKNOWN
);
5774 umsub_widen_optab
= init_optab (UNKNOWN
);
5775 sdiv_optab
= init_optab (DIV
);
5776 sdivv_optab
= init_optabv (DIV
);
5777 sdivmod_optab
= init_optab (UNKNOWN
);
5778 udiv_optab
= init_optab (UDIV
);
5779 udivmod_optab
= init_optab (UNKNOWN
);
5780 smod_optab
= init_optab (MOD
);
5781 umod_optab
= init_optab (UMOD
);
5782 fmod_optab
= init_optab (UNKNOWN
);
5783 remainder_optab
= init_optab (UNKNOWN
);
5784 ftrunc_optab
= init_optab (UNKNOWN
);
5785 and_optab
= init_optab (AND
);
5786 ior_optab
= init_optab (IOR
);
5787 xor_optab
= init_optab (XOR
);
5788 ashl_optab
= init_optab (ASHIFT
);
5789 ashr_optab
= init_optab (ASHIFTRT
);
5790 lshr_optab
= init_optab (LSHIFTRT
);
5791 rotl_optab
= init_optab (ROTATE
);
5792 rotr_optab
= init_optab (ROTATERT
);
5793 smin_optab
= init_optab (SMIN
);
5794 smax_optab
= init_optab (SMAX
);
5795 umin_optab
= init_optab (UMIN
);
5796 umax_optab
= init_optab (UMAX
);
5797 pow_optab
= init_optab (UNKNOWN
);
5798 atan2_optab
= init_optab (UNKNOWN
);
5800 /* These three have codes assigned exclusively for the sake of
5802 mov_optab
= init_optab (SET
);
5803 movstrict_optab
= init_optab (STRICT_LOW_PART
);
5804 cmp_optab
= init_optab (COMPARE
);
5806 storent_optab
= init_optab (UNKNOWN
);
5808 ucmp_optab
= init_optab (UNKNOWN
);
5809 tst_optab
= init_optab (UNKNOWN
);
5811 eq_optab
= init_optab (EQ
);
5812 ne_optab
= init_optab (NE
);
5813 gt_optab
= init_optab (GT
);
5814 ge_optab
= init_optab (GE
);
5815 lt_optab
= init_optab (LT
);
5816 le_optab
= init_optab (LE
);
5817 unord_optab
= init_optab (UNORDERED
);
5819 neg_optab
= init_optab (NEG
);
5820 negv_optab
= init_optabv (NEG
);
5821 abs_optab
= init_optab (ABS
);
5822 absv_optab
= init_optabv (ABS
);
5823 addcc_optab
= init_optab (UNKNOWN
);
5824 one_cmpl_optab
= init_optab (NOT
);
5825 bswap_optab
= init_optab (BSWAP
);
5826 ffs_optab
= init_optab (FFS
);
5827 clz_optab
= init_optab (CLZ
);
5828 ctz_optab
= init_optab (CTZ
);
5829 popcount_optab
= init_optab (POPCOUNT
);
5830 parity_optab
= init_optab (PARITY
);
5831 sqrt_optab
= init_optab (SQRT
);
5832 floor_optab
= init_optab (UNKNOWN
);
5833 ceil_optab
= init_optab (UNKNOWN
);
5834 round_optab
= init_optab (UNKNOWN
);
5835 btrunc_optab
= init_optab (UNKNOWN
);
5836 nearbyint_optab
= init_optab (UNKNOWN
);
5837 rint_optab
= init_optab (UNKNOWN
);
5838 sincos_optab
= init_optab (UNKNOWN
);
5839 sin_optab
= init_optab (UNKNOWN
);
5840 asin_optab
= init_optab (UNKNOWN
);
5841 cos_optab
= init_optab (UNKNOWN
);
5842 acos_optab
= init_optab (UNKNOWN
);
5843 exp_optab
= init_optab (UNKNOWN
);
5844 exp10_optab
= init_optab (UNKNOWN
);
5845 exp2_optab
= init_optab (UNKNOWN
);
5846 expm1_optab
= init_optab (UNKNOWN
);
5847 ldexp_optab
= init_optab (UNKNOWN
);
5848 scalb_optab
= init_optab (UNKNOWN
);
5849 logb_optab
= init_optab (UNKNOWN
);
5850 ilogb_optab
= init_optab (UNKNOWN
);
5851 log_optab
= init_optab (UNKNOWN
);
5852 log10_optab
= init_optab (UNKNOWN
);
5853 log2_optab
= init_optab (UNKNOWN
);
5854 log1p_optab
= init_optab (UNKNOWN
);
5855 tan_optab
= init_optab (UNKNOWN
);
5856 atan_optab
= init_optab (UNKNOWN
);
5857 copysign_optab
= init_optab (UNKNOWN
);
5858 signbit_optab
= init_optab (UNKNOWN
);
5860 isinf_optab
= init_optab (UNKNOWN
);
5862 strlen_optab
= init_optab (UNKNOWN
);
5863 cbranch_optab
= init_optab (UNKNOWN
);
5864 cmov_optab
= init_optab (UNKNOWN
);
5865 cstore_optab
= init_optab (UNKNOWN
);
5866 push_optab
= init_optab (UNKNOWN
);
5868 reduc_smax_optab
= init_optab (UNKNOWN
);
5869 reduc_umax_optab
= init_optab (UNKNOWN
);
5870 reduc_smin_optab
= init_optab (UNKNOWN
);
5871 reduc_umin_optab
= init_optab (UNKNOWN
);
5872 reduc_splus_optab
= init_optab (UNKNOWN
);
5873 reduc_uplus_optab
= init_optab (UNKNOWN
);
5875 ssum_widen_optab
= init_optab (UNKNOWN
);
5876 usum_widen_optab
= init_optab (UNKNOWN
);
5877 sdot_prod_optab
= init_optab (UNKNOWN
);
5878 udot_prod_optab
= init_optab (UNKNOWN
);
5880 vec_extract_optab
= init_optab (UNKNOWN
);
5881 vec_extract_even_optab
= init_optab (UNKNOWN
);
5882 vec_extract_odd_optab
= init_optab (UNKNOWN
);
5883 vec_interleave_high_optab
= init_optab (UNKNOWN
);
5884 vec_interleave_low_optab
= init_optab (UNKNOWN
);
5885 vec_set_optab
= init_optab (UNKNOWN
);
5886 vec_init_optab
= init_optab (UNKNOWN
);
5887 vec_shl_optab
= init_optab (UNKNOWN
);
5888 vec_shr_optab
= init_optab (UNKNOWN
);
5889 vec_realign_load_optab
= init_optab (UNKNOWN
);
5890 movmisalign_optab
= init_optab (UNKNOWN
);
5891 vec_widen_umult_hi_optab
= init_optab (UNKNOWN
);
5892 vec_widen_umult_lo_optab
= init_optab (UNKNOWN
);
5893 vec_widen_smult_hi_optab
= init_optab (UNKNOWN
);
5894 vec_widen_smult_lo_optab
= init_optab (UNKNOWN
);
5895 vec_unpacks_hi_optab
= init_optab (UNKNOWN
);
5896 vec_unpacks_lo_optab
= init_optab (UNKNOWN
);
5897 vec_unpacku_hi_optab
= init_optab (UNKNOWN
);
5898 vec_unpacku_lo_optab
= init_optab (UNKNOWN
);
5899 vec_unpacks_float_hi_optab
= init_optab (UNKNOWN
);
5900 vec_unpacks_float_lo_optab
= init_optab (UNKNOWN
);
5901 vec_unpacku_float_hi_optab
= init_optab (UNKNOWN
);
5902 vec_unpacku_float_lo_optab
= init_optab (UNKNOWN
);
5903 vec_pack_trunc_optab
= init_optab (UNKNOWN
);
5904 vec_pack_usat_optab
= init_optab (UNKNOWN
);
5905 vec_pack_ssat_optab
= init_optab (UNKNOWN
);
5906 vec_pack_ufix_trunc_optab
= init_optab (UNKNOWN
);
5907 vec_pack_sfix_trunc_optab
= init_optab (UNKNOWN
);
5909 powi_optab
= init_optab (UNKNOWN
);
5912 sext_optab
= init_convert_optab (SIGN_EXTEND
);
5913 zext_optab
= init_convert_optab (ZERO_EXTEND
);
5914 trunc_optab
= init_convert_optab (TRUNCATE
);
5915 sfix_optab
= init_convert_optab (FIX
);
5916 ufix_optab
= init_convert_optab (UNSIGNED_FIX
);
5917 sfixtrunc_optab
= init_convert_optab (UNKNOWN
);
5918 ufixtrunc_optab
= init_convert_optab (UNKNOWN
);
5919 sfloat_optab
= init_convert_optab (FLOAT
);
5920 ufloat_optab
= init_convert_optab (UNSIGNED_FLOAT
);
5921 lrint_optab
= init_convert_optab (UNKNOWN
);
5922 lround_optab
= init_convert_optab (UNKNOWN
);
5923 lfloor_optab
= init_convert_optab (UNKNOWN
);
5924 lceil_optab
= init_convert_optab (UNKNOWN
);
5926 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
5928 movmem_optab
[i
] = CODE_FOR_nothing
;
5929 cmpstr_optab
[i
] = CODE_FOR_nothing
;
5930 cmpstrn_optab
[i
] = CODE_FOR_nothing
;
5931 cmpmem_optab
[i
] = CODE_FOR_nothing
;
5932 setmem_optab
[i
] = CODE_FOR_nothing
;
5934 sync_add_optab
[i
] = CODE_FOR_nothing
;
5935 sync_sub_optab
[i
] = CODE_FOR_nothing
;
5936 sync_ior_optab
[i
] = CODE_FOR_nothing
;
5937 sync_and_optab
[i
] = CODE_FOR_nothing
;
5938 sync_xor_optab
[i
] = CODE_FOR_nothing
;
5939 sync_nand_optab
[i
] = CODE_FOR_nothing
;
5940 sync_old_add_optab
[i
] = CODE_FOR_nothing
;
5941 sync_old_sub_optab
[i
] = CODE_FOR_nothing
;
5942 sync_old_ior_optab
[i
] = CODE_FOR_nothing
;
5943 sync_old_and_optab
[i
] = CODE_FOR_nothing
;
5944 sync_old_xor_optab
[i
] = CODE_FOR_nothing
;
5945 sync_old_nand_optab
[i
] = CODE_FOR_nothing
;
5946 sync_new_add_optab
[i
] = CODE_FOR_nothing
;
5947 sync_new_sub_optab
[i
] = CODE_FOR_nothing
;
5948 sync_new_ior_optab
[i
] = CODE_FOR_nothing
;
5949 sync_new_and_optab
[i
] = CODE_FOR_nothing
;
5950 sync_new_xor_optab
[i
] = CODE_FOR_nothing
;
5951 sync_new_nand_optab
[i
] = CODE_FOR_nothing
;
5952 sync_compare_and_swap
[i
] = CODE_FOR_nothing
;
5953 sync_compare_and_swap_cc
[i
] = CODE_FOR_nothing
;
5954 sync_lock_test_and_set
[i
] = CODE_FOR_nothing
;
5955 sync_lock_release
[i
] = CODE_FOR_nothing
;
5957 reload_in_optab
[i
] = reload_out_optab
[i
] = CODE_FOR_nothing
;
5960 /* Fill in the optabs with the insns we support. */
5963 /* The ffs function operates on `int'. Fall back on it if we do not
5964 have a libgcc2 function for that width. */
5965 int_mode
= mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0);
5966 optab_handler (ffs_optab
, int_mode
)->libfunc
= init_one_libfunc ("ffs");
5968 /* Initialize the optabs with the names of the library functions. */
5969 init_integral_libfuncs (add_optab
, "add", '3');
5970 init_floating_libfuncs (add_optab
, "add", '3');
5971 init_integral_libfuncs (addv_optab
, "addv", '3');
5972 init_floating_libfuncs (addv_optab
, "add", '3');
5973 init_integral_libfuncs (sub_optab
, "sub", '3');
5974 init_floating_libfuncs (sub_optab
, "sub", '3');
5975 init_integral_libfuncs (subv_optab
, "subv", '3');
5976 init_floating_libfuncs (subv_optab
, "sub", '3');
5977 init_integral_libfuncs (smul_optab
, "mul", '3');
5978 init_floating_libfuncs (smul_optab
, "mul", '3');
5979 init_integral_libfuncs (smulv_optab
, "mulv", '3');
5980 init_floating_libfuncs (smulv_optab
, "mul", '3');
5981 init_integral_libfuncs (sdiv_optab
, "div", '3');
5982 init_floating_libfuncs (sdiv_optab
, "div", '3');
5983 init_integral_libfuncs (sdivv_optab
, "divv", '3');
5984 init_integral_libfuncs (udiv_optab
, "udiv", '3');
5985 init_integral_libfuncs (sdivmod_optab
, "divmod", '4');
5986 init_integral_libfuncs (udivmod_optab
, "udivmod", '4');
5987 init_integral_libfuncs (smod_optab
, "mod", '3');
5988 init_integral_libfuncs (umod_optab
, "umod", '3');
5989 init_floating_libfuncs (ftrunc_optab
, "ftrunc", '2');
5990 init_integral_libfuncs (and_optab
, "and", '3');
5991 init_integral_libfuncs (ior_optab
, "ior", '3');
5992 init_integral_libfuncs (xor_optab
, "xor", '3');
5993 init_integral_libfuncs (ashl_optab
, "ashl", '3');
5994 init_integral_libfuncs (ashr_optab
, "ashr", '3');
5995 init_integral_libfuncs (lshr_optab
, "lshr", '3');
5996 init_integral_libfuncs (smin_optab
, "min", '3');
5997 init_floating_libfuncs (smin_optab
, "min", '3');
5998 init_integral_libfuncs (smax_optab
, "max", '3');
5999 init_floating_libfuncs (smax_optab
, "max", '3');
6000 init_integral_libfuncs (umin_optab
, "umin", '3');
6001 init_integral_libfuncs (umax_optab
, "umax", '3');
6002 init_integral_libfuncs (neg_optab
, "neg", '2');
6003 init_floating_libfuncs (neg_optab
, "neg", '2');
6004 init_integral_libfuncs (negv_optab
, "negv", '2');
6005 init_floating_libfuncs (negv_optab
, "neg", '2');
6006 init_integral_libfuncs (one_cmpl_optab
, "one_cmpl", '2');
6007 init_integral_libfuncs (ffs_optab
, "ffs", '2');
6008 init_integral_libfuncs (clz_optab
, "clz", '2');
6009 init_integral_libfuncs (ctz_optab
, "ctz", '2');
6010 init_integral_libfuncs (popcount_optab
, "popcount", '2');
6011 init_integral_libfuncs (parity_optab
, "parity", '2');
6013 /* Comparison libcalls for integers MUST come in pairs,
6015 init_integral_libfuncs (cmp_optab
, "cmp", '2');
6016 init_integral_libfuncs (ucmp_optab
, "ucmp", '2');
6017 init_floating_libfuncs (cmp_optab
, "cmp", '2');
6019 /* EQ etc are floating point only. */
6020 init_floating_libfuncs (eq_optab
, "eq", '2');
6021 init_floating_libfuncs (ne_optab
, "ne", '2');
6022 init_floating_libfuncs (gt_optab
, "gt", '2');
6023 init_floating_libfuncs (ge_optab
, "ge", '2');
6024 init_floating_libfuncs (lt_optab
, "lt", '2');
6025 init_floating_libfuncs (le_optab
, "le", '2');
6026 init_floating_libfuncs (unord_optab
, "unord", '2');
6028 init_floating_libfuncs (powi_optab
, "powi", '2');
6031 init_interclass_conv_libfuncs (sfloat_optab
, "float",
6032 MODE_INT
, MODE_FLOAT
);
6033 init_interclass_conv_libfuncs (sfloat_optab
, "float",
6034 MODE_INT
, MODE_DECIMAL_FLOAT
);
6035 init_interclass_conv_libfuncs (ufloat_optab
, "floatun",
6036 MODE_INT
, MODE_FLOAT
);
6037 init_interclass_conv_libfuncs (ufloat_optab
, "floatun",
6038 MODE_INT
, MODE_DECIMAL_FLOAT
);
6039 init_interclass_conv_libfuncs (sfix_optab
, "fix",
6040 MODE_FLOAT
, MODE_INT
);
6041 init_interclass_conv_libfuncs (sfix_optab
, "fix",
6042 MODE_DECIMAL_FLOAT
, MODE_INT
);
6043 init_interclass_conv_libfuncs (ufix_optab
, "fixuns",
6044 MODE_FLOAT
, MODE_INT
);
6045 init_interclass_conv_libfuncs (ufix_optab
, "fixuns",
6046 MODE_DECIMAL_FLOAT
, MODE_INT
);
6047 init_interclass_conv_libfuncs (ufloat_optab
, "floatuns",
6048 MODE_INT
, MODE_DECIMAL_FLOAT
);
6049 init_interclass_conv_libfuncs (lrint_optab
, "lrint",
6050 MODE_INT
, MODE_FLOAT
);
6051 init_interclass_conv_libfuncs (lround_optab
, "lround",
6052 MODE_INT
, MODE_FLOAT
);
6053 init_interclass_conv_libfuncs (lfloor_optab
, "lfloor",
6054 MODE_INT
, MODE_FLOAT
);
6055 init_interclass_conv_libfuncs (lceil_optab
, "lceil",
6056 MODE_INT
, MODE_FLOAT
);
6058 /* sext_optab is also used for FLOAT_EXTEND. */
6059 init_intraclass_conv_libfuncs (sext_optab
, "extend", MODE_FLOAT
, true);
6060 init_intraclass_conv_libfuncs (sext_optab
, "extend", MODE_DECIMAL_FLOAT
, true);
6061 init_interclass_conv_libfuncs (sext_optab
, "extend", MODE_FLOAT
, MODE_DECIMAL_FLOAT
);
6062 init_interclass_conv_libfuncs (sext_optab
, "extend", MODE_DECIMAL_FLOAT
, MODE_FLOAT
);
6063 init_intraclass_conv_libfuncs (trunc_optab
, "trunc", MODE_FLOAT
, false);
6064 init_intraclass_conv_libfuncs (trunc_optab
, "trunc", MODE_DECIMAL_FLOAT
, false);
6065 init_interclass_conv_libfuncs (trunc_optab
, "trunc", MODE_FLOAT
, MODE_DECIMAL_FLOAT
);
6066 init_interclass_conv_libfuncs (trunc_optab
, "trunc", MODE_DECIMAL_FLOAT
, MODE_FLOAT
);
6068 /* Explicitly initialize the bswap libfuncs since we need them to be
6069 valid for things other than word_mode. */
6070 set_optab_libfunc (bswap_optab
, SImode
, "__bswapsi2");
6071 set_optab_libfunc (bswap_optab
, DImode
, "__bswapdi2");
6073 /* Use cabs for double complex abs, since systems generally have cabs.
6074 Don't define any libcall for float complex, so that cabs will be used. */
6075 if (complex_double_type_node
)
6076 optab_handler (abs_optab
, TYPE_MODE (complex_double_type_node
))->libfunc
6077 = init_one_libfunc ("cabs");
6079 abort_libfunc
= init_one_libfunc ("abort");
6080 memcpy_libfunc
= init_one_libfunc ("memcpy");
6081 memmove_libfunc
= init_one_libfunc ("memmove");
6082 memcmp_libfunc
= init_one_libfunc ("memcmp");
6083 memset_libfunc
= init_one_libfunc ("memset");
6084 setbits_libfunc
= init_one_libfunc ("__setbits");
6086 #ifndef DONT_USE_BUILTIN_SETJMP
6087 setjmp_libfunc
= init_one_libfunc ("__builtin_setjmp");
6088 longjmp_libfunc
= init_one_libfunc ("__builtin_longjmp");
6090 setjmp_libfunc
= init_one_libfunc ("setjmp");
6091 longjmp_libfunc
= init_one_libfunc ("longjmp");
6093 unwind_sjlj_register_libfunc
= init_one_libfunc ("_Unwind_SjLj_Register");
6094 unwind_sjlj_unregister_libfunc
6095 = init_one_libfunc ("_Unwind_SjLj_Unregister");
6097 /* For function entry/exit instrumentation. */
6098 profile_function_entry_libfunc
6099 = init_one_libfunc ("__cyg_profile_func_enter");
6100 profile_function_exit_libfunc
6101 = init_one_libfunc ("__cyg_profile_func_exit");
6103 gcov_flush_libfunc
= init_one_libfunc ("__gcov_flush");
6105 if (HAVE_conditional_trap
)
6106 trap_rtx
= gen_rtx_fmt_ee (EQ
, VOIDmode
, NULL_RTX
, NULL_RTX
);
6108 /* Allow the target to add more libcalls or rename some, etc. */
6109 targetm
.init_libfuncs ();
6114 /* Print information about the current contents of the optabs on
6118 debug_optab_libfuncs (void)
6124 /* Dump the arithmetic optabs. */
6125 for (i
= 0; i
!= (int) OTI_MAX
; i
++)
6126 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
6129 struct optab_handlers
*h
;
6132 h
= optab_handler (o
, j
);
6135 gcc_assert (GET_CODE (h
->libfunc
) == SYMBOL_REF
);
6136 fprintf (stderr
, "%s\t%s:\t%s\n",
6137 GET_RTX_NAME (o
->code
),
6139 XSTR (h
->libfunc
, 0));
6143 /* Dump the conversion optabs. */
6144 for (i
= 0; i
< (int) COI_MAX
; ++i
)
6145 for (j
= 0; j
< NUM_MACHINE_MODES
; ++j
)
6146 for (k
= 0; k
< NUM_MACHINE_MODES
; ++k
)
6149 struct optab_handlers
*h
;
6151 o
= &convert_optab_table
[i
];
6152 h
= convert_optab_handler(o
, j
, k
);
6155 gcc_assert (GET_CODE (h
->libfunc
) == SYMBOL_REF
);
6156 fprintf (stderr
, "%s\t%s\t%s:\t%s\n",
6157 GET_RTX_NAME (o
->code
),
6160 XSTR (h
->libfunc
, 0));
6168 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6169 CODE. Return 0 on failure. */
6172 gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED
, rtx op1
,
6173 rtx op2 ATTRIBUTE_UNUSED
, rtx tcode ATTRIBUTE_UNUSED
)
6175 enum machine_mode mode
= GET_MODE (op1
);
6176 enum insn_code icode
;
6179 if (!HAVE_conditional_trap
)
6182 if (mode
== VOIDmode
)
6185 icode
= optab_handler (cmp_optab
, mode
)->insn_code
;
6186 if (icode
== CODE_FOR_nothing
)
6190 op1
= prepare_operand (icode
, op1
, 0, mode
, mode
, 0);
6191 op2
= prepare_operand (icode
, op2
, 1, mode
, mode
, 0);
6197 emit_insn (GEN_FCN (icode
) (op1
, op2
));
6199 PUT_CODE (trap_rtx
, code
);
6200 gcc_assert (HAVE_conditional_trap
);
6201 insn
= gen_conditional_trap (trap_rtx
, tcode
);
6205 insn
= get_insns ();
6212 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6213 or unsigned operation code. */
6215 static enum rtx_code
6216 get_rtx_code (enum tree_code tcode
, bool unsignedp
)
6228 code
= unsignedp
? LTU
: LT
;
6231 code
= unsignedp
? LEU
: LE
;
6234 code
= unsignedp
? GTU
: GT
;
6237 code
= unsignedp
? GEU
: GE
;
6240 case UNORDERED_EXPR
:
6271 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6272 unsigned operators. Do not generate compare instruction. */
6275 vector_compare_rtx (tree cond
, bool unsignedp
, enum insn_code icode
)
6277 enum rtx_code rcode
;
6279 rtx rtx_op0
, rtx_op1
;
6281 /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
6282 ensures that condition is a relational operation. */
6283 gcc_assert (COMPARISON_CLASS_P (cond
));
6285 rcode
= get_rtx_code (TREE_CODE (cond
), unsignedp
);
6286 t_op0
= TREE_OPERAND (cond
, 0);
6287 t_op1
= TREE_OPERAND (cond
, 1);
6289 /* Expand operands. */
6290 rtx_op0
= expand_expr (t_op0
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op0
)),
6292 rtx_op1
= expand_expr (t_op1
, NULL_RTX
, TYPE_MODE (TREE_TYPE (t_op1
)),
6295 if (!insn_data
[icode
].operand
[4].predicate (rtx_op0
, GET_MODE (rtx_op0
))
6296 && GET_MODE (rtx_op0
) != VOIDmode
)
6297 rtx_op0
= force_reg (GET_MODE (rtx_op0
), rtx_op0
);
6299 if (!insn_data
[icode
].operand
[5].predicate (rtx_op1
, GET_MODE (rtx_op1
))
6300 && GET_MODE (rtx_op1
) != VOIDmode
)
6301 rtx_op1
= force_reg (GET_MODE (rtx_op1
), rtx_op1
);
6303 return gen_rtx_fmt_ee (rcode
, VOIDmode
, rtx_op0
, rtx_op1
);
6306 /* Return insn code for VEC_COND_EXPR EXPR. */
6308 static inline enum insn_code
6309 get_vcond_icode (tree expr
, enum machine_mode mode
)
6311 enum insn_code icode
= CODE_FOR_nothing
;
6313 if (TYPE_UNSIGNED (TREE_TYPE (expr
)))
6314 icode
= vcondu_gen_code
[mode
];
6316 icode
= vcond_gen_code
[mode
];
6320 /* Return TRUE iff, appropriate vector insns are available
6321 for vector cond expr expr in VMODE mode. */
6324 expand_vec_cond_expr_p (tree expr
, enum machine_mode vmode
)
6326 if (get_vcond_icode (expr
, vmode
) == CODE_FOR_nothing
)
6331 /* Generate insns for VEC_COND_EXPR. */
6334 expand_vec_cond_expr (tree vec_cond_expr
, rtx target
)
6336 enum insn_code icode
;
6337 rtx comparison
, rtx_op1
, rtx_op2
, cc_op0
, cc_op1
;
6338 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (vec_cond_expr
));
6339 bool unsignedp
= TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr
));
6341 icode
= get_vcond_icode (vec_cond_expr
, mode
);
6342 if (icode
== CODE_FOR_nothing
)
6345 if (!target
|| !insn_data
[icode
].operand
[0].predicate (target
, mode
))
6346 target
= gen_reg_rtx (mode
);
6348 /* Get comparison rtx. First expand both cond expr operands. */
6349 comparison
= vector_compare_rtx (TREE_OPERAND (vec_cond_expr
, 0),
6351 cc_op0
= XEXP (comparison
, 0);
6352 cc_op1
= XEXP (comparison
, 1);
6353 /* Expand both operands and force them in reg, if required. */
6354 rtx_op1
= expand_normal (TREE_OPERAND (vec_cond_expr
, 1));
6355 if (!insn_data
[icode
].operand
[1].predicate (rtx_op1
, mode
)
6356 && mode
!= VOIDmode
)
6357 rtx_op1
= force_reg (mode
, rtx_op1
);
6359 rtx_op2
= expand_normal (TREE_OPERAND (vec_cond_expr
, 2));
6360 if (!insn_data
[icode
].operand
[2].predicate (rtx_op2
, mode
)
6361 && mode
!= VOIDmode
)
6362 rtx_op2
= force_reg (mode
, rtx_op2
);
6364 /* Emit instruction! */
6365 emit_insn (GEN_FCN (icode
) (target
, rtx_op1
, rtx_op2
,
6366 comparison
, cc_op0
, cc_op1
));
6372 /* This is an internal subroutine of the other compare_and_swap expanders.
6373 MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
6374 operation. TARGET is an optional place to store the value result of
6375 the operation. ICODE is the particular instruction to expand. Return
6376 the result of the operation. */
6379 expand_val_compare_and_swap_1 (rtx mem
, rtx old_val
, rtx new_val
,
6380 rtx target
, enum insn_code icode
)
6382 enum machine_mode mode
= GET_MODE (mem
);
6385 if (!target
|| !insn_data
[icode
].operand
[0].predicate (target
, mode
))
6386 target
= gen_reg_rtx (mode
);
6388 if (GET_MODE (old_val
) != VOIDmode
&& GET_MODE (old_val
) != mode
)
6389 old_val
= convert_modes (mode
, GET_MODE (old_val
), old_val
, 1);
6390 if (!insn_data
[icode
].operand
[2].predicate (old_val
, mode
))
6391 old_val
= force_reg (mode
, old_val
);
6393 if (GET_MODE (new_val
) != VOIDmode
&& GET_MODE (new_val
) != mode
)
6394 new_val
= convert_modes (mode
, GET_MODE (new_val
), new_val
, 1);
6395 if (!insn_data
[icode
].operand
[3].predicate (new_val
, mode
))
6396 new_val
= force_reg (mode
, new_val
);
6398 insn
= GEN_FCN (icode
) (target
, mem
, old_val
, new_val
);
6399 if (insn
== NULL_RTX
)
6406 /* Expand a compare-and-swap operation and return its value. */
6409 expand_val_compare_and_swap (rtx mem
, rtx old_val
, rtx new_val
, rtx target
)
6411 enum machine_mode mode
= GET_MODE (mem
);
6412 enum insn_code icode
= sync_compare_and_swap
[mode
];
6414 if (icode
== CODE_FOR_nothing
)
6417 return expand_val_compare_and_swap_1 (mem
, old_val
, new_val
, target
, icode
);
6420 /* Expand a compare-and-swap operation and store true into the result if
6421 the operation was successful and false otherwise. Return the result.
6422 Unlike other routines, TARGET is not optional. */
6425 expand_bool_compare_and_swap (rtx mem
, rtx old_val
, rtx new_val
, rtx target
)
6427 enum machine_mode mode
= GET_MODE (mem
);
6428 enum insn_code icode
;
6429 rtx subtarget
, label0
, label1
;
6431 /* If the target supports a compare-and-swap pattern that simultaneously
6432 sets some flag for success, then use it. Otherwise use the regular
6433 compare-and-swap and follow that immediately with a compare insn. */
6434 icode
= sync_compare_and_swap_cc
[mode
];
6438 subtarget
= expand_val_compare_and_swap_1 (mem
, old_val
, new_val
,
6440 if (subtarget
!= NULL_RTX
)
6444 case CODE_FOR_nothing
:
6445 icode
= sync_compare_and_swap
[mode
];
6446 if (icode
== CODE_FOR_nothing
)
6449 /* Ensure that if old_val == mem, that we're not comparing
6450 against an old value. */
6451 if (MEM_P (old_val
))
6452 old_val
= force_reg (mode
, old_val
);
6454 subtarget
= expand_val_compare_and_swap_1 (mem
, old_val
, new_val
,
6456 if (subtarget
== NULL_RTX
)
6459 emit_cmp_insn (subtarget
, old_val
, EQ
, const0_rtx
, mode
, true);
6462 /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
6463 setcc instruction from the beginning. We don't work too hard here,
6464 but it's nice to not be stupid about initial code gen either. */
6465 if (STORE_FLAG_VALUE
== 1)
6467 icode
= setcc_gen_code
[EQ
];
6468 if (icode
!= CODE_FOR_nothing
)
6470 enum machine_mode cmode
= insn_data
[icode
].operand
[0].mode
;
6474 if (!insn_data
[icode
].operand
[0].predicate (target
, cmode
))
6475 subtarget
= gen_reg_rtx (cmode
);
6477 insn
= GEN_FCN (icode
) (subtarget
);
6481 if (GET_MODE (target
) != GET_MODE (subtarget
))
6483 convert_move (target
, subtarget
, 1);
6491 /* Without an appropriate setcc instruction, use a set of branches to
6492 get 1 and 0 stored into target. Presumably if the target has a
6493 STORE_FLAG_VALUE that isn't 1, then this will get cleaned up by ifcvt. */
6495 label0
= gen_label_rtx ();
6496 label1
= gen_label_rtx ();
6498 emit_jump_insn (bcc_gen_fctn
[EQ
] (label0
));
6499 emit_move_insn (target
, const0_rtx
);
6500 emit_jump_insn (gen_jump (label1
));
6502 emit_label (label0
);
6503 emit_move_insn (target
, const1_rtx
);
6504 emit_label (label1
);
6509 /* This is a helper function for the other atomic operations. This function
6510 emits a loop that contains SEQ that iterates until a compare-and-swap
6511 operation at the end succeeds. MEM is the memory to be modified. SEQ is
6512 a set of instructions that takes a value from OLD_REG as an input and
6513 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
6514 set to the current contents of MEM. After SEQ, a compare-and-swap will
6515 attempt to update MEM with NEW_REG. The function returns true when the
6516 loop was generated successfully. */
6519 expand_compare_and_swap_loop (rtx mem
, rtx old_reg
, rtx new_reg
, rtx seq
)
6521 enum machine_mode mode
= GET_MODE (mem
);
6522 enum insn_code icode
;
6523 rtx label
, cmp_reg
, subtarget
;
6525 /* The loop we want to generate looks like
6531 cmp_reg = compare-and-swap(mem, old_reg, new_reg)
6532 if (cmp_reg != old_reg)
6535 Note that we only do the plain load from memory once. Subsequent
6536 iterations use the value loaded by the compare-and-swap pattern. */
6538 label
= gen_label_rtx ();
6539 cmp_reg
= gen_reg_rtx (mode
);
6541 emit_move_insn (cmp_reg
, mem
);
6543 emit_move_insn (old_reg
, cmp_reg
);
6547 /* If the target supports a compare-and-swap pattern that simultaneously
6548 sets some flag for success, then use it. Otherwise use the regular
6549 compare-and-swap and follow that immediately with a compare insn. */
6550 icode
= sync_compare_and_swap_cc
[mode
];
6554 subtarget
= expand_val_compare_and_swap_1 (mem
, old_reg
, new_reg
,
6556 if (subtarget
!= NULL_RTX
)
6558 gcc_assert (subtarget
== cmp_reg
);
6563 case CODE_FOR_nothing
:
6564 icode
= sync_compare_and_swap
[mode
];
6565 if (icode
== CODE_FOR_nothing
)
6568 subtarget
= expand_val_compare_and_swap_1 (mem
, old_reg
, new_reg
,
6570 if (subtarget
== NULL_RTX
)
6572 if (subtarget
!= cmp_reg
)
6573 emit_move_insn (cmp_reg
, subtarget
);
6575 emit_cmp_insn (cmp_reg
, old_reg
, EQ
, const0_rtx
, mode
, true);
6578 /* ??? Mark this jump predicted not taken? */
6579 emit_jump_insn (bcc_gen_fctn
[NE
] (label
));
6584 /* This function generates the atomic operation MEM CODE= VAL. In this
6585 case, we do not care about any resulting value. Returns NULL if we
6586 cannot generate the operation. */
6589 expand_sync_operation (rtx mem
, rtx val
, enum rtx_code code
)
6591 enum machine_mode mode
= GET_MODE (mem
);
6592 enum insn_code icode
;
6595 /* Look to see if the target supports the operation directly. */
6599 icode
= sync_add_optab
[mode
];
6602 icode
= sync_ior_optab
[mode
];
6605 icode
= sync_xor_optab
[mode
];
6608 icode
= sync_and_optab
[mode
];
6611 icode
= sync_nand_optab
[mode
];
6615 icode
= sync_sub_optab
[mode
];
6616 if (icode
== CODE_FOR_nothing
)
6618 icode
= sync_add_optab
[mode
];
6619 if (icode
!= CODE_FOR_nothing
)
6621 val
= expand_simple_unop (mode
, NEG
, val
, NULL_RTX
, 1);
6631 /* Generate the direct operation, if present. */
6632 if (icode
!= CODE_FOR_nothing
)
6634 if (GET_MODE (val
) != VOIDmode
&& GET_MODE (val
) != mode
)
6635 val
= convert_modes (mode
, GET_MODE (val
), val
, 1);
6636 if (!insn_data
[icode
].operand
[1].predicate (val
, mode
))
6637 val
= force_reg (mode
, val
);
6639 insn
= GEN_FCN (icode
) (mem
, val
);
6647 /* Failing that, generate a compare-and-swap loop in which we perform the
6648 operation with normal arithmetic instructions. */
6649 if (sync_compare_and_swap
[mode
] != CODE_FOR_nothing
)
6651 rtx t0
= gen_reg_rtx (mode
), t1
;
6658 t1
= expand_simple_unop (mode
, NOT
, t1
, NULL_RTX
, true);
6661 t1
= expand_simple_binop (mode
, code
, t1
, val
, NULL_RTX
,
6662 true, OPTAB_LIB_WIDEN
);
6664 insn
= get_insns ();
6667 if (t1
!= NULL
&& expand_compare_and_swap_loop (mem
, t0
, t1
, insn
))
6674 /* This function generates the atomic operation MEM CODE= VAL. In this
6675 case, we do care about the resulting value: if AFTER is true then
6676 return the value MEM holds after the operation, if AFTER is false
6677 then return the value MEM holds before the operation. TARGET is an
6678 optional place for the result value to be stored. */
6681 expand_sync_fetch_operation (rtx mem
, rtx val
, enum rtx_code code
,
6682 bool after
, rtx target
)
6684 enum machine_mode mode
= GET_MODE (mem
);
6685 enum insn_code old_code
, new_code
, icode
;
6689 /* Look to see if the target supports the operation directly. */
6693 old_code
= sync_old_add_optab
[mode
];
6694 new_code
= sync_new_add_optab
[mode
];
6697 old_code
= sync_old_ior_optab
[mode
];
6698 new_code
= sync_new_ior_optab
[mode
];
6701 old_code
= sync_old_xor_optab
[mode
];
6702 new_code
= sync_new_xor_optab
[mode
];
6705 old_code
= sync_old_and_optab
[mode
];
6706 new_code
= sync_new_and_optab
[mode
];
6709 old_code
= sync_old_nand_optab
[mode
];
6710 new_code
= sync_new_nand_optab
[mode
];
6714 old_code
= sync_old_sub_optab
[mode
];
6715 new_code
= sync_new_sub_optab
[mode
];
6716 if (old_code
== CODE_FOR_nothing
&& new_code
== CODE_FOR_nothing
)
6718 old_code
= sync_old_add_optab
[mode
];
6719 new_code
= sync_new_add_optab
[mode
];
6720 if (old_code
!= CODE_FOR_nothing
|| new_code
!= CODE_FOR_nothing
)
6722 val
= expand_simple_unop (mode
, NEG
, val
, NULL_RTX
, 1);
6732 /* If the target does supports the proper new/old operation, great. But
6733 if we only support the opposite old/new operation, check to see if we
6734 can compensate. In the case in which the old value is supported, then
6735 we can always perform the operation again with normal arithmetic. In
6736 the case in which the new value is supported, then we can only handle
6737 this in the case the operation is reversible. */
6742 if (icode
== CODE_FOR_nothing
)
6745 if (icode
!= CODE_FOR_nothing
)
6752 if (icode
== CODE_FOR_nothing
6753 && (code
== PLUS
|| code
== MINUS
|| code
== XOR
))
6756 if (icode
!= CODE_FOR_nothing
)
6761 /* If we found something supported, great. */
6762 if (icode
!= CODE_FOR_nothing
)
6764 if (!target
|| !insn_data
[icode
].operand
[0].predicate (target
, mode
))
6765 target
= gen_reg_rtx (mode
);
6767 if (GET_MODE (val
) != VOIDmode
&& GET_MODE (val
) != mode
)
6768 val
= convert_modes (mode
, GET_MODE (val
), val
, 1);
6769 if (!insn_data
[icode
].operand
[2].predicate (val
, mode
))
6770 val
= force_reg (mode
, val
);
6772 insn
= GEN_FCN (icode
) (target
, mem
, val
);
6777 /* If we need to compensate for using an operation with the
6778 wrong return value, do so now. */
6785 else if (code
== MINUS
)
6790 target
= expand_simple_unop (mode
, NOT
, target
, NULL_RTX
, true);
6791 target
= expand_simple_binop (mode
, code
, target
, val
, NULL_RTX
,
6792 true, OPTAB_LIB_WIDEN
);
6799 /* Failing that, generate a compare-and-swap loop in which we perform the
6800 operation with normal arithmetic instructions. */
6801 if (sync_compare_and_swap
[mode
] != CODE_FOR_nothing
)
6803 rtx t0
= gen_reg_rtx (mode
), t1
;
6805 if (!target
|| !register_operand (target
, mode
))
6806 target
= gen_reg_rtx (mode
);
6811 emit_move_insn (target
, t0
);
6815 t1
= expand_simple_unop (mode
, NOT
, t1
, NULL_RTX
, true);
6818 t1
= expand_simple_binop (mode
, code
, t1
, val
, NULL_RTX
,
6819 true, OPTAB_LIB_WIDEN
);
6821 emit_move_insn (target
, t1
);
6823 insn
= get_insns ();
6826 if (t1
!= NULL
&& expand_compare_and_swap_loop (mem
, t0
, t1
, insn
))
6833 /* This function expands a test-and-set operation. Ideally we atomically
6834 store VAL in MEM and return the previous value in MEM. Some targets
6835 may not support this operation and only support VAL with the constant 1;
6836 in this case while the return value will be 0/1, but the exact value
6837 stored in MEM is target defined. TARGET is an option place to stick
6838 the return value. */
6841 expand_sync_lock_test_and_set (rtx mem
, rtx val
, rtx target
)
6843 enum machine_mode mode
= GET_MODE (mem
);
6844 enum insn_code icode
;
6847 /* If the target supports the test-and-set directly, great. */
6848 icode
= sync_lock_test_and_set
[mode
];
6849 if (icode
!= CODE_FOR_nothing
)
6851 if (!target
|| !insn_data
[icode
].operand
[0].predicate (target
, mode
))
6852 target
= gen_reg_rtx (mode
);
6854 if (GET_MODE (val
) != VOIDmode
&& GET_MODE (val
) != mode
)
6855 val
= convert_modes (mode
, GET_MODE (val
), val
, 1);
6856 if (!insn_data
[icode
].operand
[2].predicate (val
, mode
))
6857 val
= force_reg (mode
, val
);
6859 insn
= GEN_FCN (icode
) (target
, mem
, val
);
6867 /* Otherwise, use a compare-and-swap loop for the exchange. */
6868 if (sync_compare_and_swap
[mode
] != CODE_FOR_nothing
)
6870 if (!target
|| !register_operand (target
, mode
))
6871 target
= gen_reg_rtx (mode
);
6872 if (GET_MODE (val
) != VOIDmode
&& GET_MODE (val
) != mode
)
6873 val
= convert_modes (mode
, GET_MODE (val
), val
, 1);
6874 if (expand_compare_and_swap_loop (mem
, target
, val
, NULL_RTX
))
6881 #include "gt-optabs.h"