2015-01-13 Paolo Carlini <paolo.carlini@oracle.com>
[official-gcc.git] / gcc / optabs.c
blob615199a6dc62ee27de4406c02452504260be92b7
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "diagnostic-core.h"
27 /* Include insn-config.h before expr.h so that HAVE_conditional_move
28 is properly defined. */
29 #include "insn-config.h"
30 #include "rtl.h"
31 #include "hash-set.h"
32 #include "machmode.h"
33 #include "vec.h"
34 #include "double-int.h"
35 #include "input.h"
36 #include "alias.h"
37 #include "symtab.h"
38 #include "wide-int.h"
39 #include "inchash.h"
40 #include "tree.h"
41 #include "tree-hasher.h"
42 #include "stor-layout.h"
43 #include "stringpool.h"
44 #include "varasm.h"
45 #include "tm_p.h"
46 #include "flags.h"
47 #include "hard-reg-set.h"
48 #include "input.h"
49 #include "function.h"
50 #include "except.h"
51 #include "expr.h"
52 #include "insn-codes.h"
53 #include "optabs.h"
54 #include "libfuncs.h"
55 #include "recog.h"
56 #include "reload.h"
57 #include "ggc.h"
58 #include "predict.h"
59 #include "dominance.h"
60 #include "cfg.h"
61 #include "basic-block.h"
62 #include "target.h"
64 struct target_optabs default_target_optabs;
65 struct target_libfuncs default_target_libfuncs;
66 struct target_optabs *this_fn_optabs = &default_target_optabs;
67 #if SWITCHABLE_TARGET
68 struct target_optabs *this_target_optabs = &default_target_optabs;
69 struct target_libfuncs *this_target_libfuncs = &default_target_libfuncs;
70 #endif
72 #define libfunc_hash \
73 (this_target_libfuncs->x_libfunc_hash)
75 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
76 machine_mode *);
77 static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int);
78 static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool);
80 /* Debug facility for use in GDB. */
81 void debug_optab_libfuncs (void);
83 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
84 #if ENABLE_DECIMAL_BID_FORMAT
85 #define DECIMAL_PREFIX "bid_"
86 #else
87 #define DECIMAL_PREFIX "dpd_"
88 #endif
90 /* Used for libfunc_hash. */
92 hashval_t
93 libfunc_hasher::hash (libfunc_entry *e)
95 return ((e->mode1 + e->mode2 * NUM_MACHINE_MODES) ^ e->op);
98 /* Used for libfunc_hash. */
100 bool
101 libfunc_hasher::equal (libfunc_entry *e1, libfunc_entry *e2)
103 return e1->op == e2->op && e1->mode1 == e2->mode1 && e1->mode2 == e2->mode2;
106 /* Return libfunc corresponding operation defined by OPTAB converting
107 from MODE2 to MODE1. Trigger lazy initialization if needed, return NULL
108 if no libfunc is available. */
110 convert_optab_libfunc (convert_optab optab, machine_mode mode1,
111 machine_mode mode2)
113 struct libfunc_entry e;
114 struct libfunc_entry **slot;
116 /* ??? This ought to be an assert, but not all of the places
117 that we expand optabs know about the optabs that got moved
118 to being direct. */
119 if (!(optab >= FIRST_CONV_OPTAB && optab <= LAST_CONVLIB_OPTAB))
120 return NULL_RTX;
122 e.op = optab;
123 e.mode1 = mode1;
124 e.mode2 = mode2;
125 slot = libfunc_hash->find_slot (&e, NO_INSERT);
126 if (!slot)
128 const struct convert_optab_libcall_d *d
129 = &convlib_def[optab - FIRST_CONV_OPTAB];
131 if (d->libcall_gen == NULL)
132 return NULL;
134 d->libcall_gen (optab, d->libcall_basename, mode1, mode2);
135 slot = libfunc_hash->find_slot (&e, NO_INSERT);
136 if (!slot)
137 return NULL;
139 return (*slot)->libfunc;
142 /* Return libfunc corresponding operation defined by OPTAB in MODE.
143 Trigger lazy initialization if needed, return NULL if no libfunc is
144 available. */
146 optab_libfunc (optab optab, machine_mode mode)
148 struct libfunc_entry e;
149 struct libfunc_entry **slot;
151 /* ??? This ought to be an assert, but not all of the places
152 that we expand optabs know about the optabs that got moved
153 to being direct. */
154 if (!(optab >= FIRST_NORM_OPTAB && optab <= LAST_NORMLIB_OPTAB))
155 return NULL_RTX;
157 e.op = optab;
158 e.mode1 = mode;
159 e.mode2 = VOIDmode;
160 slot = libfunc_hash->find_slot (&e, NO_INSERT);
161 if (!slot)
163 const struct optab_libcall_d *d
164 = &normlib_def[optab - FIRST_NORM_OPTAB];
166 if (d->libcall_gen == NULL)
167 return NULL;
169 d->libcall_gen (optab, d->libcall_basename, d->libcall_suffix, mode);
170 slot = libfunc_hash->find_slot (&e, NO_INSERT);
171 if (!slot)
172 return NULL;
174 return (*slot)->libfunc;
178 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
179 the result of operation CODE applied to OP0 (and OP1 if it is a binary
180 operation).
182 If the last insn does not set TARGET, don't do anything, but return 1.
184 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
185 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
186 try again, ensuring that TARGET is not one of the operands. */
188 static int
189 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
191 rtx_insn *last_insn;
192 rtx set;
193 rtx note;
195 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
197 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
198 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
199 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
200 && GET_RTX_CLASS (code) != RTX_COMPARE
201 && GET_RTX_CLASS (code) != RTX_UNARY)
202 return 1;
204 if (GET_CODE (target) == ZERO_EXTRACT)
205 return 1;
207 for (last_insn = insns;
208 NEXT_INSN (last_insn) != NULL_RTX;
209 last_insn = NEXT_INSN (last_insn))
212 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
213 a value changing in the insn, so the note would be invalid for CSE. */
214 if (reg_overlap_mentioned_p (target, op0)
215 || (op1 && reg_overlap_mentioned_p (target, op1)))
217 if (MEM_P (target)
218 && (rtx_equal_p (target, op0)
219 || (op1 && rtx_equal_p (target, op1))))
221 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
222 over expanding it as temp = MEM op X, MEM = temp. If the target
223 supports MEM = MEM op X instructions, it is sometimes too hard
224 to reconstruct that form later, especially if X is also a memory,
225 and due to multiple occurrences of addresses the address might
226 be forced into register unnecessarily.
227 Note that not emitting the REG_EQUIV note might inhibit
228 CSE in some cases. */
229 set = single_set (last_insn);
230 if (set
231 && GET_CODE (SET_SRC (set)) == code
232 && MEM_P (SET_DEST (set))
233 && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
234 || (op1 && rtx_equal_p (SET_DEST (set),
235 XEXP (SET_SRC (set), 1)))))
236 return 1;
238 return 0;
241 set = set_for_reg_notes (last_insn);
242 if (set == NULL_RTX)
243 return 1;
245 if (! rtx_equal_p (SET_DEST (set), target)
246 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
247 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
248 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
249 return 1;
251 if (GET_RTX_CLASS (code) == RTX_UNARY)
252 switch (code)
254 case FFS:
255 case CLZ:
256 case CTZ:
257 case CLRSB:
258 case POPCOUNT:
259 case PARITY:
260 case BSWAP:
261 if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
263 note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
264 if (GET_MODE_SIZE (GET_MODE (op0))
265 > GET_MODE_SIZE (GET_MODE (target)))
266 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
267 note, GET_MODE (op0));
268 else
269 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
270 note, GET_MODE (op0));
271 break;
273 /* FALLTHRU */
274 default:
275 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
276 break;
278 else
279 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
281 set_unique_reg_note (last_insn, REG_EQUAL, note);
283 return 1;
286 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
287 for a widening operation would be. In most cases this would be OP0, but if
288 that's a constant it'll be VOIDmode, which isn't useful. */
290 static machine_mode
291 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
293 machine_mode m0 = GET_MODE (op0);
294 machine_mode m1 = GET_MODE (op1);
295 machine_mode result;
297 if (m0 == VOIDmode && m1 == VOIDmode)
298 return to_mode;
299 else if (m0 == VOIDmode || GET_MODE_SIZE (m0) < GET_MODE_SIZE (m1))
300 result = m1;
301 else
302 result = m0;
304 if (GET_MODE_SIZE (result) > GET_MODE_SIZE (to_mode))
305 return to_mode;
307 return result;
310 /* Like optab_handler, but for widening_operations that have a
311 TO_MODE and a FROM_MODE. */
313 enum insn_code
314 widening_optab_handler (optab op, machine_mode to_mode,
315 machine_mode from_mode)
317 unsigned scode = (op << 16) | to_mode;
318 if (to_mode != from_mode && from_mode != VOIDmode)
320 /* ??? Why does find_widening_optab_handler_and_mode attempt to
321 widen things that can't be widened? E.g. add_optab... */
322 if (op > LAST_CONV_OPTAB)
323 return CODE_FOR_nothing;
324 scode |= from_mode << 8;
326 return raw_optab_handler (scode);
329 /* Find a widening optab even if it doesn't widen as much as we want.
330 E.g. if from_mode is HImode, and to_mode is DImode, and there is no
331 direct HI->SI insn, then return SI->DI, if that exists.
332 If PERMIT_NON_WIDENING is non-zero then this can be used with
333 non-widening optabs also. */
335 enum insn_code
336 find_widening_optab_handler_and_mode (optab op, machine_mode to_mode,
337 machine_mode from_mode,
338 int permit_non_widening,
339 machine_mode *found_mode)
341 for (; (permit_non_widening || from_mode != to_mode)
342 && GET_MODE_SIZE (from_mode) <= GET_MODE_SIZE (to_mode)
343 && from_mode != VOIDmode;
344 from_mode = GET_MODE_WIDER_MODE (from_mode))
346 enum insn_code handler = widening_optab_handler (op, to_mode,
347 from_mode);
349 if (handler != CODE_FOR_nothing)
351 if (found_mode)
352 *found_mode = from_mode;
353 return handler;
357 return CODE_FOR_nothing;
360 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
361 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
362 not actually do a sign-extend or zero-extend, but can leave the
363 higher-order bits of the result rtx undefined, for example, in the case
364 of logical operations, but not right shifts. */
366 static rtx
367 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
368 int unsignedp, int no_extend)
370 rtx result;
372 /* If we don't have to extend and this is a constant, return it. */
373 if (no_extend && GET_MODE (op) == VOIDmode)
374 return op;
376 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
377 extend since it will be more efficient to do so unless the signedness of
378 a promoted object differs from our extension. */
379 if (! no_extend
380 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
381 && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
382 return convert_modes (mode, oldmode, op, unsignedp);
384 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
385 SUBREG. */
386 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
387 return gen_lowpart (mode, force_reg (GET_MODE (op), op));
389 /* Otherwise, get an object of MODE, clobber it, and set the low-order
390 part to OP. */
392 result = gen_reg_rtx (mode);
393 emit_clobber (result);
394 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
395 return result;
398 /* Return the optab used for computing the operation given by the tree code,
399 CODE and the tree EXP. This function is not always usable (for example, it
400 cannot give complete results for multiplication or division) but probably
401 ought to be relied on more widely throughout the expander. */
402 optab
403 optab_for_tree_code (enum tree_code code, const_tree type,
404 enum optab_subtype subtype)
406 bool trapv;
407 switch (code)
409 case BIT_AND_EXPR:
410 return and_optab;
412 case BIT_IOR_EXPR:
413 return ior_optab;
415 case BIT_NOT_EXPR:
416 return one_cmpl_optab;
418 case BIT_XOR_EXPR:
419 return xor_optab;
421 case MULT_HIGHPART_EXPR:
422 return TYPE_UNSIGNED (type) ? umul_highpart_optab : smul_highpart_optab;
424 case TRUNC_MOD_EXPR:
425 case CEIL_MOD_EXPR:
426 case FLOOR_MOD_EXPR:
427 case ROUND_MOD_EXPR:
428 return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
430 case RDIV_EXPR:
431 case TRUNC_DIV_EXPR:
432 case CEIL_DIV_EXPR:
433 case FLOOR_DIV_EXPR:
434 case ROUND_DIV_EXPR:
435 case EXACT_DIV_EXPR:
436 if (TYPE_SATURATING (type))
437 return TYPE_UNSIGNED (type) ? usdiv_optab : ssdiv_optab;
438 return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
440 case LSHIFT_EXPR:
441 if (TREE_CODE (type) == VECTOR_TYPE)
443 if (subtype == optab_vector)
444 return TYPE_SATURATING (type) ? unknown_optab : vashl_optab;
446 gcc_assert (subtype == optab_scalar);
448 if (TYPE_SATURATING (type))
449 return TYPE_UNSIGNED (type) ? usashl_optab : ssashl_optab;
450 return ashl_optab;
452 case RSHIFT_EXPR:
453 if (TREE_CODE (type) == VECTOR_TYPE)
455 if (subtype == optab_vector)
456 return TYPE_UNSIGNED (type) ? vlshr_optab : vashr_optab;
458 gcc_assert (subtype == optab_scalar);
460 return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
462 case LROTATE_EXPR:
463 if (TREE_CODE (type) == VECTOR_TYPE)
465 if (subtype == optab_vector)
466 return vrotl_optab;
468 gcc_assert (subtype == optab_scalar);
470 return rotl_optab;
472 case RROTATE_EXPR:
473 if (TREE_CODE (type) == VECTOR_TYPE)
475 if (subtype == optab_vector)
476 return vrotr_optab;
478 gcc_assert (subtype == optab_scalar);
480 return rotr_optab;
482 case MAX_EXPR:
483 return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
485 case MIN_EXPR:
486 return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
488 case REALIGN_LOAD_EXPR:
489 return vec_realign_load_optab;
491 case WIDEN_SUM_EXPR:
492 return TYPE_UNSIGNED (type) ? usum_widen_optab : ssum_widen_optab;
494 case DOT_PROD_EXPR:
495 return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
497 case SAD_EXPR:
498 return TYPE_UNSIGNED (type) ? usad_optab : ssad_optab;
500 case WIDEN_MULT_PLUS_EXPR:
501 return (TYPE_UNSIGNED (type)
502 ? (TYPE_SATURATING (type)
503 ? usmadd_widen_optab : umadd_widen_optab)
504 : (TYPE_SATURATING (type)
505 ? ssmadd_widen_optab : smadd_widen_optab));
507 case WIDEN_MULT_MINUS_EXPR:
508 return (TYPE_UNSIGNED (type)
509 ? (TYPE_SATURATING (type)
510 ? usmsub_widen_optab : umsub_widen_optab)
511 : (TYPE_SATURATING (type)
512 ? ssmsub_widen_optab : smsub_widen_optab));
514 case FMA_EXPR:
515 return fma_optab;
517 case REDUC_MAX_EXPR:
518 return TYPE_UNSIGNED (type)
519 ? reduc_umax_scal_optab : reduc_smax_scal_optab;
521 case REDUC_MIN_EXPR:
522 return TYPE_UNSIGNED (type)
523 ? reduc_umin_scal_optab : reduc_smin_scal_optab;
525 case REDUC_PLUS_EXPR:
526 return reduc_plus_scal_optab;
528 case VEC_WIDEN_MULT_HI_EXPR:
529 return TYPE_UNSIGNED (type) ?
530 vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
532 case VEC_WIDEN_MULT_LO_EXPR:
533 return TYPE_UNSIGNED (type) ?
534 vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
536 case VEC_WIDEN_MULT_EVEN_EXPR:
537 return TYPE_UNSIGNED (type) ?
538 vec_widen_umult_even_optab : vec_widen_smult_even_optab;
540 case VEC_WIDEN_MULT_ODD_EXPR:
541 return TYPE_UNSIGNED (type) ?
542 vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
544 case VEC_WIDEN_LSHIFT_HI_EXPR:
545 return TYPE_UNSIGNED (type) ?
546 vec_widen_ushiftl_hi_optab : vec_widen_sshiftl_hi_optab;
548 case VEC_WIDEN_LSHIFT_LO_EXPR:
549 return TYPE_UNSIGNED (type) ?
550 vec_widen_ushiftl_lo_optab : vec_widen_sshiftl_lo_optab;
552 case VEC_UNPACK_HI_EXPR:
553 return TYPE_UNSIGNED (type) ?
554 vec_unpacku_hi_optab : vec_unpacks_hi_optab;
556 case VEC_UNPACK_LO_EXPR:
557 return TYPE_UNSIGNED (type) ?
558 vec_unpacku_lo_optab : vec_unpacks_lo_optab;
560 case VEC_UNPACK_FLOAT_HI_EXPR:
561 /* The signedness is determined from input operand. */
562 return TYPE_UNSIGNED (type) ?
563 vec_unpacku_float_hi_optab : vec_unpacks_float_hi_optab;
565 case VEC_UNPACK_FLOAT_LO_EXPR:
566 /* The signedness is determined from input operand. */
567 return TYPE_UNSIGNED (type) ?
568 vec_unpacku_float_lo_optab : vec_unpacks_float_lo_optab;
570 case VEC_PACK_TRUNC_EXPR:
571 return vec_pack_trunc_optab;
573 case VEC_PACK_SAT_EXPR:
574 return TYPE_UNSIGNED (type) ? vec_pack_usat_optab : vec_pack_ssat_optab;
576 case VEC_PACK_FIX_TRUNC_EXPR:
577 /* The signedness is determined from output operand. */
578 return TYPE_UNSIGNED (type) ?
579 vec_pack_ufix_trunc_optab : vec_pack_sfix_trunc_optab;
581 default:
582 break;
585 trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
586 switch (code)
588 case POINTER_PLUS_EXPR:
589 case PLUS_EXPR:
590 if (TYPE_SATURATING (type))
591 return TYPE_UNSIGNED (type) ? usadd_optab : ssadd_optab;
592 return trapv ? addv_optab : add_optab;
594 case MINUS_EXPR:
595 if (TYPE_SATURATING (type))
596 return TYPE_UNSIGNED (type) ? ussub_optab : sssub_optab;
597 return trapv ? subv_optab : sub_optab;
599 case MULT_EXPR:
600 if (TYPE_SATURATING (type))
601 return TYPE_UNSIGNED (type) ? usmul_optab : ssmul_optab;
602 return trapv ? smulv_optab : smul_optab;
604 case NEGATE_EXPR:
605 if (TYPE_SATURATING (type))
606 return TYPE_UNSIGNED (type) ? usneg_optab : ssneg_optab;
607 return trapv ? negv_optab : neg_optab;
609 case ABS_EXPR:
610 return trapv ? absv_optab : abs_optab;
612 default:
613 return unknown_optab;
617 /* Given optab UNOPTAB that reduces a vector to a scalar, find instead the old
618 optab that produces a vector with the reduction result in one element,
619 for a tree with type TYPE. */
621 optab
622 scalar_reduc_to_vector (optab unoptab, const_tree type)
624 switch (unoptab)
626 case reduc_plus_scal_optab:
627 return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
629 case reduc_smin_scal_optab: return reduc_smin_optab;
630 case reduc_umin_scal_optab: return reduc_umin_optab;
631 case reduc_smax_scal_optab: return reduc_smax_optab;
632 case reduc_umax_scal_optab: return reduc_umax_optab;
633 default: return unknown_optab;
637 /* Expand vector widening operations.
639 There are two different classes of operations handled here:
640 1) Operations whose result is wider than all the arguments to the operation.
641 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
642 In this case OP0 and optionally OP1 would be initialized,
643 but WIDE_OP wouldn't (not relevant for this case).
644 2) Operations whose result is of the same size as the last argument to the
645 operation, but wider than all the other arguments to the operation.
646 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
647 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
649 E.g, when called to expand the following operations, this is how
650 the arguments will be initialized:
651 nops OP0 OP1 WIDE_OP
652 widening-sum 2 oprnd0 - oprnd1
653 widening-dot-product 3 oprnd0 oprnd1 oprnd2
654 widening-mult 2 oprnd0 oprnd1 -
655 type-promotion (vec-unpack) 1 oprnd0 - - */
658 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
659 rtx target, int unsignedp)
661 struct expand_operand eops[4];
662 tree oprnd0, oprnd1, oprnd2;
663 machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
664 optab widen_pattern_optab;
665 enum insn_code icode;
666 int nops = TREE_CODE_LENGTH (ops->code);
667 int op;
669 oprnd0 = ops->op0;
670 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
671 widen_pattern_optab =
672 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
673 if (ops->code == WIDEN_MULT_PLUS_EXPR
674 || ops->code == WIDEN_MULT_MINUS_EXPR)
675 icode = find_widening_optab_handler (widen_pattern_optab,
676 TYPE_MODE (TREE_TYPE (ops->op2)),
677 tmode0, 0);
678 else
679 icode = optab_handler (widen_pattern_optab, tmode0);
680 gcc_assert (icode != CODE_FOR_nothing);
682 if (nops >= 2)
684 oprnd1 = ops->op1;
685 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
688 /* The last operand is of a wider mode than the rest of the operands. */
689 if (nops == 2)
690 wmode = tmode1;
691 else if (nops == 3)
693 gcc_assert (tmode1 == tmode0);
694 gcc_assert (op1);
695 oprnd2 = ops->op2;
696 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
699 op = 0;
700 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
701 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
702 if (op1)
703 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
704 if (wide_op)
705 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
706 expand_insn (icode, op, eops);
707 return eops[0].value;
710 /* Generate code to perform an operation specified by TERNARY_OPTAB
711 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
713 UNSIGNEDP is for the case where we have to widen the operands
714 to perform the operation. It says to use zero-extension.
716 If TARGET is nonzero, the value
717 is generated there, if it is convenient to do so.
718 In all cases an rtx is returned for the locus of the value;
719 this may or may not be TARGET. */
722 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
723 rtx op1, rtx op2, rtx target, int unsignedp)
725 struct expand_operand ops[4];
726 enum insn_code icode = optab_handler (ternary_optab, mode);
728 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
730 create_output_operand (&ops[0], target, mode);
731 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
732 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
733 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
734 expand_insn (icode, 4, ops);
735 return ops[0].value;
739 /* Like expand_binop, but return a constant rtx if the result can be
740 calculated at compile time. The arguments and return value are
741 otherwise the same as for expand_binop. */
744 simplify_expand_binop (machine_mode mode, optab binoptab,
745 rtx op0, rtx op1, rtx target, int unsignedp,
746 enum optab_methods methods)
748 if (CONSTANT_P (op0) && CONSTANT_P (op1))
750 rtx x = simplify_binary_operation (optab_to_code (binoptab),
751 mode, op0, op1);
752 if (x)
753 return x;
756 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
759 /* Like simplify_expand_binop, but always put the result in TARGET.
760 Return true if the expansion succeeded. */
762 bool
763 force_expand_binop (machine_mode mode, optab binoptab,
764 rtx op0, rtx op1, rtx target, int unsignedp,
765 enum optab_methods methods)
767 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
768 target, unsignedp, methods);
769 if (x == 0)
770 return false;
771 if (x != target)
772 emit_move_insn (target, x);
773 return true;
776 /* Create a new vector value in VMODE with all elements set to OP. The
777 mode of OP must be the element mode of VMODE. If OP is a constant,
778 then the return value will be a constant. */
780 static rtx
781 expand_vector_broadcast (machine_mode vmode, rtx op)
783 enum insn_code icode;
784 rtvec vec;
785 rtx ret;
786 int i, n;
788 gcc_checking_assert (VECTOR_MODE_P (vmode));
790 n = GET_MODE_NUNITS (vmode);
791 vec = rtvec_alloc (n);
792 for (i = 0; i < n; ++i)
793 RTVEC_ELT (vec, i) = op;
795 if (CONSTANT_P (op))
796 return gen_rtx_CONST_VECTOR (vmode, vec);
798 /* ??? If the target doesn't have a vec_init, then we have no easy way
799 of performing this operation. Most of this sort of generic support
800 is hidden away in the vector lowering support in gimple. */
801 icode = optab_handler (vec_init_optab, vmode);
802 if (icode == CODE_FOR_nothing)
803 return NULL;
805 ret = gen_reg_rtx (vmode);
806 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
808 return ret;
811 /* This subroutine of expand_doubleword_shift handles the cases in which
812 the effective shift value is >= BITS_PER_WORD. The arguments and return
813 value are the same as for the parent routine, except that SUPERWORD_OP1
814 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
815 INTO_TARGET may be null if the caller has decided to calculate it. */
817 static bool
818 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
819 rtx outof_target, rtx into_target,
820 int unsignedp, enum optab_methods methods)
822 if (into_target != 0)
823 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
824 into_target, unsignedp, methods))
825 return false;
827 if (outof_target != 0)
829 /* For a signed right shift, we must fill OUTOF_TARGET with copies
830 of the sign bit, otherwise we must fill it with zeros. */
831 if (binoptab != ashr_optab)
832 emit_move_insn (outof_target, CONST0_RTX (word_mode));
833 else
834 if (!force_expand_binop (word_mode, binoptab,
835 outof_input, GEN_INT (BITS_PER_WORD - 1),
836 outof_target, unsignedp, methods))
837 return false;
839 return true;
842 /* This subroutine of expand_doubleword_shift handles the cases in which
843 the effective shift value is < BITS_PER_WORD. The arguments and return
844 value are the same as for the parent routine. */
846 static bool
847 expand_subword_shift (machine_mode op1_mode, optab binoptab,
848 rtx outof_input, rtx into_input, rtx op1,
849 rtx outof_target, rtx into_target,
850 int unsignedp, enum optab_methods methods,
851 unsigned HOST_WIDE_INT shift_mask)
853 optab reverse_unsigned_shift, unsigned_shift;
854 rtx tmp, carries;
856 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
857 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
859 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
860 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
861 the opposite direction to BINOPTAB. */
862 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
864 carries = outof_input;
865 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
866 op1_mode), op1_mode);
867 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
868 0, true, methods);
870 else
872 /* We must avoid shifting by BITS_PER_WORD bits since that is either
873 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
874 has unknown behavior. Do a single shift first, then shift by the
875 remainder. It's OK to use ~OP1 as the remainder if shift counts
876 are truncated to the mode size. */
877 carries = expand_binop (word_mode, reverse_unsigned_shift,
878 outof_input, const1_rtx, 0, unsignedp, methods);
879 if (shift_mask == BITS_PER_WORD - 1)
881 tmp = immed_wide_int_const
882 (wi::minus_one (GET_MODE_PRECISION (op1_mode)), op1_mode);
883 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
884 0, true, methods);
886 else
888 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
889 op1_mode), op1_mode);
890 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
891 0, true, methods);
894 if (tmp == 0 || carries == 0)
895 return false;
896 carries = expand_binop (word_mode, reverse_unsigned_shift,
897 carries, tmp, 0, unsignedp, methods);
898 if (carries == 0)
899 return false;
901 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
902 so the result can go directly into INTO_TARGET if convenient. */
903 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
904 into_target, unsignedp, methods);
905 if (tmp == 0)
906 return false;
908 /* Now OR in the bits carried over from OUTOF_INPUT. */
909 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
910 into_target, unsignedp, methods))
911 return false;
913 /* Use a standard word_mode shift for the out-of half. */
914 if (outof_target != 0)
915 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
916 outof_target, unsignedp, methods))
917 return false;
919 return true;
923 #ifdef HAVE_conditional_move
924 /* Try implementing expand_doubleword_shift using conditional moves.
925 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
926 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
927 are the shift counts to use in the former and latter case. All other
928 arguments are the same as the parent routine. */
930 static bool
931 expand_doubleword_shift_condmove (machine_mode op1_mode, optab binoptab,
932 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
933 rtx outof_input, rtx into_input,
934 rtx subword_op1, rtx superword_op1,
935 rtx outof_target, rtx into_target,
936 int unsignedp, enum optab_methods methods,
937 unsigned HOST_WIDE_INT shift_mask)
939 rtx outof_superword, into_superword;
941 /* Put the superword version of the output into OUTOF_SUPERWORD and
942 INTO_SUPERWORD. */
943 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
944 if (outof_target != 0 && subword_op1 == superword_op1)
946 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
947 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
948 into_superword = outof_target;
949 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
950 outof_superword, 0, unsignedp, methods))
951 return false;
953 else
955 into_superword = gen_reg_rtx (word_mode);
956 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
957 outof_superword, into_superword,
958 unsignedp, methods))
959 return false;
962 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
963 if (!expand_subword_shift (op1_mode, binoptab,
964 outof_input, into_input, subword_op1,
965 outof_target, into_target,
966 unsignedp, methods, shift_mask))
967 return false;
969 /* Select between them. Do the INTO half first because INTO_SUPERWORD
970 might be the current value of OUTOF_TARGET. */
971 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
972 into_target, into_superword, word_mode, false))
973 return false;
975 if (outof_target != 0)
976 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
977 outof_target, outof_superword,
978 word_mode, false))
979 return false;
981 return true;
983 #endif
985 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
986 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
987 input operand; the shift moves bits in the direction OUTOF_INPUT->
988 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
989 of the target. OP1 is the shift count and OP1_MODE is its mode.
990 If OP1 is constant, it will have been truncated as appropriate
991 and is known to be nonzero.
993 If SHIFT_MASK is zero, the result of word shifts is undefined when the
994 shift count is outside the range [0, BITS_PER_WORD). This routine must
995 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
997 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
998 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
999 fill with zeros or sign bits as appropriate.
1001 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
1002 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
1003 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
1004 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
1005 are undefined.
1007 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
1008 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
1009 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
1010 function wants to calculate it itself.
1012 Return true if the shift could be successfully synthesized. */
1014 static bool
1015 expand_doubleword_shift (machine_mode op1_mode, optab binoptab,
1016 rtx outof_input, rtx into_input, rtx op1,
1017 rtx outof_target, rtx into_target,
1018 int unsignedp, enum optab_methods methods,
1019 unsigned HOST_WIDE_INT shift_mask)
1021 rtx superword_op1, tmp, cmp1, cmp2;
1022 enum rtx_code cmp_code;
1024 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
1025 fill the result with sign or zero bits as appropriate. If so, the value
1026 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
1027 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
1028 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
1030 This isn't worthwhile for constant shifts since the optimizers will
1031 cope better with in-range shift counts. */
1032 if (shift_mask >= BITS_PER_WORD
1033 && outof_target != 0
1034 && !CONSTANT_P (op1))
1036 if (!expand_doubleword_shift (op1_mode, binoptab,
1037 outof_input, into_input, op1,
1038 0, into_target,
1039 unsignedp, methods, shift_mask))
1040 return false;
1041 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
1042 outof_target, unsignedp, methods))
1043 return false;
1044 return true;
1047 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
1048 is true when the effective shift value is less than BITS_PER_WORD.
1049 Set SUPERWORD_OP1 to the shift count that should be used to shift
1050 OUTOF_INPUT into INTO_TARGET when the condition is false. */
1051 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
1052 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
1054 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
1055 is a subword shift count. */
1056 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
1057 0, true, methods);
1058 cmp2 = CONST0_RTX (op1_mode);
1059 cmp_code = EQ;
1060 superword_op1 = op1;
1062 else
1064 /* Set CMP1 to OP1 - BITS_PER_WORD. */
1065 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
1066 0, true, methods);
1067 cmp2 = CONST0_RTX (op1_mode);
1068 cmp_code = LT;
1069 superword_op1 = cmp1;
1071 if (cmp1 == 0)
1072 return false;
1074 /* If we can compute the condition at compile time, pick the
1075 appropriate subroutine. */
1076 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
1077 if (tmp != 0 && CONST_INT_P (tmp))
1079 if (tmp == const0_rtx)
1080 return expand_superword_shift (binoptab, outof_input, superword_op1,
1081 outof_target, into_target,
1082 unsignedp, methods);
1083 else
1084 return expand_subword_shift (op1_mode, binoptab,
1085 outof_input, into_input, op1,
1086 outof_target, into_target,
1087 unsignedp, methods, shift_mask);
1090 #ifdef HAVE_conditional_move
1091 /* Try using conditional moves to generate straight-line code. */
1093 rtx_insn *start = get_last_insn ();
1094 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
1095 cmp_code, cmp1, cmp2,
1096 outof_input, into_input,
1097 op1, superword_op1,
1098 outof_target, into_target,
1099 unsignedp, methods, shift_mask))
1100 return true;
1101 delete_insns_since (start);
1103 #endif
1105 /* As a last resort, use branches to select the correct alternative. */
1106 rtx_code_label *subword_label = gen_label_rtx ();
1107 rtx_code_label *done_label = gen_label_rtx ();
1109 NO_DEFER_POP;
1110 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
1111 0, 0, subword_label, -1);
1112 OK_DEFER_POP;
1114 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
1115 outof_target, into_target,
1116 unsignedp, methods))
1117 return false;
1119 emit_jump_insn (gen_jump (done_label));
1120 emit_barrier ();
1121 emit_label (subword_label);
1123 if (!expand_subword_shift (op1_mode, binoptab,
1124 outof_input, into_input, op1,
1125 outof_target, into_target,
1126 unsignedp, methods, shift_mask))
1127 return false;
1129 emit_label (done_label);
1130 return true;
1133 /* Subroutine of expand_binop. Perform a double word multiplication of
1134 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1135 as the target's word_mode. This function return NULL_RTX if anything
1136 goes wrong, in which case it may have already emitted instructions
1137 which need to be deleted.
1139 If we want to multiply two two-word values and have normal and widening
1140 multiplies of single-word values, we can do this with three smaller
1141 multiplications.
1143 The multiplication proceeds as follows:
1144 _______________________
1145 [__op0_high_|__op0_low__]
1146 _______________________
1147 * [__op1_high_|__op1_low__]
1148 _______________________________________________
1149 _______________________
1150 (1) [__op0_low__*__op1_low__]
1151 _______________________
1152 (2a) [__op0_low__*__op1_high_]
1153 _______________________
1154 (2b) [__op0_high_*__op1_low__]
1155 _______________________
1156 (3) [__op0_high_*__op1_high_]
1159 This gives a 4-word result. Since we are only interested in the
1160 lower 2 words, partial result (3) and the upper words of (2a) and
1161 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1162 calculated using non-widening multiplication.
1164 (1), however, needs to be calculated with an unsigned widening
1165 multiplication. If this operation is not directly supported we
1166 try using a signed widening multiplication and adjust the result.
1167 This adjustment works as follows:
1169 If both operands are positive then no adjustment is needed.
1171 If the operands have different signs, for example op0_low < 0 and
1172 op1_low >= 0, the instruction treats the most significant bit of
1173 op0_low as a sign bit instead of a bit with significance
1174 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1175 with 2**BITS_PER_WORD - op0_low, and two's complements the
1176 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1177 the result.
1179 Similarly, if both operands are negative, we need to add
1180 (op0_low + op1_low) * 2**BITS_PER_WORD.
1182 We use a trick to adjust quickly. We logically shift op0_low right
1183 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1184 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1185 logical shift exists, we do an arithmetic right shift and subtract
1186 the 0 or -1. */
1188 static rtx
1189 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
1190 bool umulp, enum optab_methods methods)
1192 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1193 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1194 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
1195 rtx product, adjust, product_high, temp;
1197 rtx op0_high = operand_subword_force (op0, high, mode);
1198 rtx op0_low = operand_subword_force (op0, low, mode);
1199 rtx op1_high = operand_subword_force (op1, high, mode);
1200 rtx op1_low = operand_subword_force (op1, low, mode);
1202 /* If we're using an unsigned multiply to directly compute the product
1203 of the low-order words of the operands and perform any required
1204 adjustments of the operands, we begin by trying two more multiplications
1205 and then computing the appropriate sum.
1207 We have checked above that the required addition is provided.
1208 Full-word addition will normally always succeed, especially if
1209 it is provided at all, so we don't worry about its failure. The
1210 multiplication may well fail, however, so we do handle that. */
1212 if (!umulp)
1214 /* ??? This could be done with emit_store_flag where available. */
1215 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1216 NULL_RTX, 1, methods);
1217 if (temp)
1218 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
1219 NULL_RTX, 0, OPTAB_DIRECT);
1220 else
1222 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1223 NULL_RTX, 0, methods);
1224 if (!temp)
1225 return NULL_RTX;
1226 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
1227 NULL_RTX, 0, OPTAB_DIRECT);
1230 if (!op0_high)
1231 return NULL_RTX;
1234 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
1235 NULL_RTX, 0, OPTAB_DIRECT);
1236 if (!adjust)
1237 return NULL_RTX;
1239 /* OP0_HIGH should now be dead. */
1241 if (!umulp)
1243 /* ??? This could be done with emit_store_flag where available. */
1244 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1245 NULL_RTX, 1, methods);
1246 if (temp)
1247 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
1248 NULL_RTX, 0, OPTAB_DIRECT);
1249 else
1251 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1252 NULL_RTX, 0, methods);
1253 if (!temp)
1254 return NULL_RTX;
1255 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
1256 NULL_RTX, 0, OPTAB_DIRECT);
1259 if (!op1_high)
1260 return NULL_RTX;
1263 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
1264 NULL_RTX, 0, OPTAB_DIRECT);
1265 if (!temp)
1266 return NULL_RTX;
1268 /* OP1_HIGH should now be dead. */
1270 adjust = expand_binop (word_mode, add_optab, adjust, temp,
1271 NULL_RTX, 0, OPTAB_DIRECT);
1273 if (target && !REG_P (target))
1274 target = NULL_RTX;
1276 if (umulp)
1277 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1278 target, 1, OPTAB_DIRECT);
1279 else
1280 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1281 target, 1, OPTAB_DIRECT);
1283 if (!product)
1284 return NULL_RTX;
1286 product_high = operand_subword (product, high, 1, mode);
1287 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
1288 NULL_RTX, 0, OPTAB_DIRECT);
1289 emit_move_insn (product_high, adjust);
1290 return product;
1293 /* Wrapper around expand_binop which takes an rtx code to specify
1294 the operation to perform, not an optab pointer. All other
1295 arguments are the same. */
1297 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
1298 rtx op1, rtx target, int unsignedp,
1299 enum optab_methods methods)
1301 optab binop = code_to_optab (code);
1302 gcc_assert (binop);
1304 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1307 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1308 binop. Order them according to commutative_operand_precedence and, if
1309 possible, try to put TARGET or a pseudo first. */
1310 static bool
1311 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1313 int op0_prec = commutative_operand_precedence (op0);
1314 int op1_prec = commutative_operand_precedence (op1);
1316 if (op0_prec < op1_prec)
1317 return true;
1319 if (op0_prec > op1_prec)
1320 return false;
1322 /* With equal precedence, both orders are ok, but it is better if the
1323 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1324 if (target == 0 || REG_P (target))
1325 return (REG_P (op1) && !REG_P (op0)) || target == op1;
1326 else
1327 return rtx_equal_p (op1, target);
1330 /* Return true if BINOPTAB implements a shift operation. */
1332 static bool
1333 shift_optab_p (optab binoptab)
1335 switch (optab_to_code (binoptab))
1337 case ASHIFT:
1338 case SS_ASHIFT:
1339 case US_ASHIFT:
1340 case ASHIFTRT:
1341 case LSHIFTRT:
1342 case ROTATE:
1343 case ROTATERT:
1344 return true;
1346 default:
1347 return false;
1351 /* Return true if BINOPTAB implements a commutative binary operation. */
1353 static bool
1354 commutative_optab_p (optab binoptab)
1356 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
1357 || binoptab == smul_widen_optab
1358 || binoptab == umul_widen_optab
1359 || binoptab == smul_highpart_optab
1360 || binoptab == umul_highpart_optab);
1363 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
1364 optimizing, and if the operand is a constant that costs more than
1365 1 instruction, force the constant into a register and return that
1366 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1368 static rtx
1369 avoid_expensive_constant (machine_mode mode, optab binoptab,
1370 int opn, rtx x, bool unsignedp)
1372 bool speed = optimize_insn_for_speed_p ();
1374 if (mode != VOIDmode
1375 && optimize
1376 && CONSTANT_P (x)
1377 && (rtx_cost (x, optab_to_code (binoptab), opn, speed)
1378 > set_src_cost (x, speed)))
1380 if (CONST_INT_P (x))
1382 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
1383 if (intval != INTVAL (x))
1384 x = GEN_INT (intval);
1386 else
1387 x = convert_modes (mode, VOIDmode, x, unsignedp);
1388 x = force_reg (mode, x);
1390 return x;
1393 /* Helper function for expand_binop: handle the case where there
1394 is an insn that directly implements the indicated operation.
1395 Returns null if this is not possible. */
1396 static rtx
1397 expand_binop_directly (machine_mode mode, optab binoptab,
1398 rtx op0, rtx op1,
1399 rtx target, int unsignedp, enum optab_methods methods,
1400 rtx_insn *last)
1402 machine_mode from_mode = widened_mode (mode, op0, op1);
1403 enum insn_code icode = find_widening_optab_handler (binoptab, mode,
1404 from_mode, 1);
1405 machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
1406 machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
1407 machine_mode mode0, mode1, tmp_mode;
1408 struct expand_operand ops[3];
1409 bool commutative_p;
1410 rtx pat;
1411 rtx xop0 = op0, xop1 = op1;
1412 rtx swap;
1414 /* If it is a commutative operator and the modes would match
1415 if we would swap the operands, we can save the conversions. */
1416 commutative_p = commutative_optab_p (binoptab);
1417 if (commutative_p
1418 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1419 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode1)
1421 swap = xop0;
1422 xop0 = xop1;
1423 xop1 = swap;
1426 /* If we are optimizing, force expensive constants into a register. */
1427 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1428 if (!shift_optab_p (binoptab))
1429 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1431 /* In case the insn wants input operands in modes different from
1432 those of the actual operands, convert the operands. It would
1433 seem that we don't need to convert CONST_INTs, but we do, so
1434 that they're properly zero-extended, sign-extended or truncated
1435 for their mode. */
1437 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1438 if (xmode0 != VOIDmode && xmode0 != mode0)
1440 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1441 mode0 = xmode0;
1444 mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
1445 if (xmode1 != VOIDmode && xmode1 != mode1)
1447 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1448 mode1 = xmode1;
1451 /* If operation is commutative,
1452 try to make the first operand a register.
1453 Even better, try to make it the same as the target.
1454 Also try to make the last operand a constant. */
1455 if (commutative_p
1456 && swap_commutative_operands_with_target (target, xop0, xop1))
1458 swap = xop1;
1459 xop1 = xop0;
1460 xop0 = swap;
1463 /* Now, if insn's predicates don't allow our operands, put them into
1464 pseudo regs. */
1466 if (binoptab == vec_pack_trunc_optab
1467 || binoptab == vec_pack_usat_optab
1468 || binoptab == vec_pack_ssat_optab
1469 || binoptab == vec_pack_ufix_trunc_optab
1470 || binoptab == vec_pack_sfix_trunc_optab)
1472 /* The mode of the result is different then the mode of the
1473 arguments. */
1474 tmp_mode = insn_data[(int) icode].operand[0].mode;
1475 if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1477 delete_insns_since (last);
1478 return NULL_RTX;
1481 else
1482 tmp_mode = mode;
1484 create_output_operand (&ops[0], target, tmp_mode);
1485 create_input_operand (&ops[1], xop0, mode0);
1486 create_input_operand (&ops[2], xop1, mode1);
1487 pat = maybe_gen_insn (icode, 3, ops);
1488 if (pat)
1490 /* If PAT is composed of more than one insn, try to add an appropriate
1491 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1492 operand, call expand_binop again, this time without a target. */
1493 if (INSN_P (pat) && NEXT_INSN (as_a <rtx_insn *> (pat)) != NULL_RTX
1494 && ! add_equal_note (as_a <rtx_insn *> (pat), ops[0].value,
1495 optab_to_code (binoptab),
1496 ops[1].value, ops[2].value))
1498 delete_insns_since (last);
1499 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1500 unsignedp, methods);
1503 emit_insn (pat);
1504 return ops[0].value;
1506 delete_insns_since (last);
1507 return NULL_RTX;
1510 /* Generate code to perform an operation specified by BINOPTAB
1511 on operands OP0 and OP1, with result having machine-mode MODE.
1513 UNSIGNEDP is for the case where we have to widen the operands
1514 to perform the operation. It says to use zero-extension.
1516 If TARGET is nonzero, the value
1517 is generated there, if it is convenient to do so.
1518 In all cases an rtx is returned for the locus of the value;
1519 this may or may not be TARGET. */
1522 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
1523 rtx target, int unsignedp, enum optab_methods methods)
1525 enum optab_methods next_methods
1526 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1527 ? OPTAB_WIDEN : methods);
1528 enum mode_class mclass;
1529 machine_mode wider_mode;
1530 rtx libfunc;
1531 rtx temp;
1532 rtx_insn *entry_last = get_last_insn ();
1533 rtx_insn *last;
1535 mclass = GET_MODE_CLASS (mode);
1537 /* If subtracting an integer constant, convert this into an addition of
1538 the negated constant. */
1540 if (binoptab == sub_optab && CONST_INT_P (op1))
1542 op1 = negate_rtx (mode, op1);
1543 binoptab = add_optab;
1546 /* Record where to delete back to if we backtrack. */
1547 last = get_last_insn ();
1549 /* If we can do it with a three-operand insn, do so. */
1551 if (methods != OPTAB_MUST_WIDEN
1552 && find_widening_optab_handler (binoptab, mode,
1553 widened_mode (mode, op0, op1), 1)
1554 != CODE_FOR_nothing)
1556 temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1557 unsignedp, methods, last);
1558 if (temp)
1559 return temp;
1562 /* If we were trying to rotate, and that didn't work, try rotating
1563 the other direction before falling back to shifts and bitwise-or. */
1564 if (((binoptab == rotl_optab
1565 && optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
1566 || (binoptab == rotr_optab
1567 && optab_handler (rotl_optab, mode) != CODE_FOR_nothing))
1568 && mclass == MODE_INT)
1570 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1571 rtx newop1;
1572 unsigned int bits = GET_MODE_PRECISION (mode);
1574 if (CONST_INT_P (op1))
1575 newop1 = GEN_INT (bits - INTVAL (op1));
1576 else if (targetm.shift_truncation_mask (mode) == bits - 1)
1577 newop1 = negate_rtx (GET_MODE (op1), op1);
1578 else
1579 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1580 gen_int_mode (bits, GET_MODE (op1)), op1,
1581 NULL_RTX, unsignedp, OPTAB_DIRECT);
1583 temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1584 target, unsignedp, methods, last);
1585 if (temp)
1586 return temp;
1589 /* If this is a multiply, see if we can do a widening operation that
1590 takes operands of this mode and makes a wider mode. */
1592 if (binoptab == smul_optab
1593 && GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1594 && (widening_optab_handler ((unsignedp ? umul_widen_optab
1595 : smul_widen_optab),
1596 GET_MODE_2XWIDER_MODE (mode), mode)
1597 != CODE_FOR_nothing))
1599 temp = expand_binop (GET_MODE_2XWIDER_MODE (mode),
1600 unsignedp ? umul_widen_optab : smul_widen_optab,
1601 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1603 if (temp != 0)
1605 if (GET_MODE_CLASS (mode) == MODE_INT
1606 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1607 return gen_lowpart (mode, temp);
1608 else
1609 return convert_to_mode (mode, temp, unsignedp);
1613 /* If this is a vector shift by a scalar, see if we can do a vector
1614 shift by a vector. If so, broadcast the scalar into a vector. */
1615 if (mclass == MODE_VECTOR_INT)
1617 optab otheroptab = unknown_optab;
1619 if (binoptab == ashl_optab)
1620 otheroptab = vashl_optab;
1621 else if (binoptab == ashr_optab)
1622 otheroptab = vashr_optab;
1623 else if (binoptab == lshr_optab)
1624 otheroptab = vlshr_optab;
1625 else if (binoptab == rotl_optab)
1626 otheroptab = vrotl_optab;
1627 else if (binoptab == rotr_optab)
1628 otheroptab = vrotr_optab;
1630 if (otheroptab && optab_handler (otheroptab, mode) != CODE_FOR_nothing)
1632 rtx vop1 = expand_vector_broadcast (mode, op1);
1633 if (vop1)
1635 temp = expand_binop_directly (mode, otheroptab, op0, vop1,
1636 target, unsignedp, methods, last);
1637 if (temp)
1638 return temp;
1643 /* Look for a wider mode of the same class for which we think we
1644 can open-code the operation. Check for a widening multiply at the
1645 wider mode as well. */
1647 if (CLASS_HAS_WIDER_MODES_P (mclass)
1648 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1649 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1650 wider_mode != VOIDmode;
1651 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1653 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1654 || (binoptab == smul_optab
1655 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1656 && (find_widening_optab_handler ((unsignedp
1657 ? umul_widen_optab
1658 : smul_widen_optab),
1659 GET_MODE_WIDER_MODE (wider_mode),
1660 mode, 0)
1661 != CODE_FOR_nothing)))
1663 rtx xop0 = op0, xop1 = op1;
1664 int no_extend = 0;
1666 /* For certain integer operations, we need not actually extend
1667 the narrow operands, as long as we will truncate
1668 the results to the same narrowness. */
1670 if ((binoptab == ior_optab || binoptab == and_optab
1671 || binoptab == xor_optab
1672 || binoptab == add_optab || binoptab == sub_optab
1673 || binoptab == smul_optab || binoptab == ashl_optab)
1674 && mclass == MODE_INT)
1676 no_extend = 1;
1677 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1678 xop0, unsignedp);
1679 if (binoptab != ashl_optab)
1680 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1681 xop1, unsignedp);
1684 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1686 /* The second operand of a shift must always be extended. */
1687 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1688 no_extend && binoptab != ashl_optab);
1690 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1691 unsignedp, OPTAB_DIRECT);
1692 if (temp)
1694 if (mclass != MODE_INT
1695 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1697 if (target == 0)
1698 target = gen_reg_rtx (mode);
1699 convert_move (target, temp, 0);
1700 return target;
1702 else
1703 return gen_lowpart (mode, temp);
1705 else
1706 delete_insns_since (last);
1710 /* If operation is commutative,
1711 try to make the first operand a register.
1712 Even better, try to make it the same as the target.
1713 Also try to make the last operand a constant. */
1714 if (commutative_optab_p (binoptab)
1715 && swap_commutative_operands_with_target (target, op0, op1))
1717 temp = op1;
1718 op1 = op0;
1719 op0 = temp;
1722 /* These can be done a word at a time. */
1723 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1724 && mclass == MODE_INT
1725 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1726 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1728 int i;
1729 rtx_insn *insns;
1731 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1732 won't be accurate, so use a new target. */
1733 if (target == 0
1734 || target == op0
1735 || target == op1
1736 || !valid_multiword_target_p (target))
1737 target = gen_reg_rtx (mode);
1739 start_sequence ();
1741 /* Do the actual arithmetic. */
1742 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1744 rtx target_piece = operand_subword (target, i, 1, mode);
1745 rtx x = expand_binop (word_mode, binoptab,
1746 operand_subword_force (op0, i, mode),
1747 operand_subword_force (op1, i, mode),
1748 target_piece, unsignedp, next_methods);
1750 if (x == 0)
1751 break;
1753 if (target_piece != x)
1754 emit_move_insn (target_piece, x);
1757 insns = get_insns ();
1758 end_sequence ();
1760 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1762 emit_insn (insns);
1763 return target;
1767 /* Synthesize double word shifts from single word shifts. */
1768 if ((binoptab == lshr_optab || binoptab == ashl_optab
1769 || binoptab == ashr_optab)
1770 && mclass == MODE_INT
1771 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1772 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1773 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode)
1774 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1775 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1776 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1778 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1779 machine_mode op1_mode;
1781 double_shift_mask = targetm.shift_truncation_mask (mode);
1782 shift_mask = targetm.shift_truncation_mask (word_mode);
1783 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1785 /* Apply the truncation to constant shifts. */
1786 if (double_shift_mask > 0 && CONST_INT_P (op1))
1787 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1789 if (op1 == CONST0_RTX (op1_mode))
1790 return op0;
1792 /* Make sure that this is a combination that expand_doubleword_shift
1793 can handle. See the comments there for details. */
1794 if (double_shift_mask == 0
1795 || (shift_mask == BITS_PER_WORD - 1
1796 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1798 rtx_insn *insns;
1799 rtx into_target, outof_target;
1800 rtx into_input, outof_input;
1801 int left_shift, outof_word;
1803 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1804 won't be accurate, so use a new target. */
1805 if (target == 0
1806 || target == op0
1807 || target == op1
1808 || !valid_multiword_target_p (target))
1809 target = gen_reg_rtx (mode);
1811 start_sequence ();
1813 /* OUTOF_* is the word we are shifting bits away from, and
1814 INTO_* is the word that we are shifting bits towards, thus
1815 they differ depending on the direction of the shift and
1816 WORDS_BIG_ENDIAN. */
1818 left_shift = binoptab == ashl_optab;
1819 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1821 outof_target = operand_subword (target, outof_word, 1, mode);
1822 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1824 outof_input = operand_subword_force (op0, outof_word, mode);
1825 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1827 if (expand_doubleword_shift (op1_mode, binoptab,
1828 outof_input, into_input, op1,
1829 outof_target, into_target,
1830 unsignedp, next_methods, shift_mask))
1832 insns = get_insns ();
1833 end_sequence ();
1835 emit_insn (insns);
1836 return target;
1838 end_sequence ();
1842 /* Synthesize double word rotates from single word shifts. */
1843 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1844 && mclass == MODE_INT
1845 && CONST_INT_P (op1)
1846 && GET_MODE_PRECISION (mode) == 2 * BITS_PER_WORD
1847 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1848 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1850 rtx_insn *insns;
1851 rtx into_target, outof_target;
1852 rtx into_input, outof_input;
1853 rtx inter;
1854 int shift_count, left_shift, outof_word;
1856 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1857 won't be accurate, so use a new target. Do this also if target is not
1858 a REG, first because having a register instead may open optimization
1859 opportunities, and second because if target and op0 happen to be MEMs
1860 designating the same location, we would risk clobbering it too early
1861 in the code sequence we generate below. */
1862 if (target == 0
1863 || target == op0
1864 || target == op1
1865 || !REG_P (target)
1866 || !valid_multiword_target_p (target))
1867 target = gen_reg_rtx (mode);
1869 start_sequence ();
1871 shift_count = INTVAL (op1);
1873 /* OUTOF_* is the word we are shifting bits away from, and
1874 INTO_* is the word that we are shifting bits towards, thus
1875 they differ depending on the direction of the shift and
1876 WORDS_BIG_ENDIAN. */
1878 left_shift = (binoptab == rotl_optab);
1879 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1881 outof_target = operand_subword (target, outof_word, 1, mode);
1882 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1884 outof_input = operand_subword_force (op0, outof_word, mode);
1885 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1887 if (shift_count == BITS_PER_WORD)
1889 /* This is just a word swap. */
1890 emit_move_insn (outof_target, into_input);
1891 emit_move_insn (into_target, outof_input);
1892 inter = const0_rtx;
1894 else
1896 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1897 rtx first_shift_count, second_shift_count;
1898 optab reverse_unsigned_shift, unsigned_shift;
1900 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1901 ? lshr_optab : ashl_optab);
1903 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1904 ? ashl_optab : lshr_optab);
1906 if (shift_count > BITS_PER_WORD)
1908 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1909 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1911 else
1913 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1914 second_shift_count = GEN_INT (shift_count);
1917 into_temp1 = expand_binop (word_mode, unsigned_shift,
1918 outof_input, first_shift_count,
1919 NULL_RTX, unsignedp, next_methods);
1920 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1921 into_input, second_shift_count,
1922 NULL_RTX, unsignedp, next_methods);
1924 if (into_temp1 != 0 && into_temp2 != 0)
1925 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1926 into_target, unsignedp, next_methods);
1927 else
1928 inter = 0;
1930 if (inter != 0 && inter != into_target)
1931 emit_move_insn (into_target, inter);
1933 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1934 into_input, first_shift_count,
1935 NULL_RTX, unsignedp, next_methods);
1936 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1937 outof_input, second_shift_count,
1938 NULL_RTX, unsignedp, next_methods);
1940 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1941 inter = expand_binop (word_mode, ior_optab,
1942 outof_temp1, outof_temp2,
1943 outof_target, unsignedp, next_methods);
1945 if (inter != 0 && inter != outof_target)
1946 emit_move_insn (outof_target, inter);
1949 insns = get_insns ();
1950 end_sequence ();
1952 if (inter != 0)
1954 emit_insn (insns);
1955 return target;
1959 /* These can be done a word at a time by propagating carries. */
1960 if ((binoptab == add_optab || binoptab == sub_optab)
1961 && mclass == MODE_INT
1962 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1963 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1965 unsigned int i;
1966 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1967 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1968 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1969 rtx xop0, xop1, xtarget;
1971 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1972 value is one of those, use it. Otherwise, use 1 since it is the
1973 one easiest to get. */
1974 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1975 int normalizep = STORE_FLAG_VALUE;
1976 #else
1977 int normalizep = 1;
1978 #endif
1980 /* Prepare the operands. */
1981 xop0 = force_reg (mode, op0);
1982 xop1 = force_reg (mode, op1);
1984 xtarget = gen_reg_rtx (mode);
1986 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1987 target = xtarget;
1989 /* Indicate for flow that the entire target reg is being set. */
1990 if (REG_P (target))
1991 emit_clobber (xtarget);
1993 /* Do the actual arithmetic. */
1994 for (i = 0; i < nwords; i++)
1996 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1997 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1998 rtx op0_piece = operand_subword_force (xop0, index, mode);
1999 rtx op1_piece = operand_subword_force (xop1, index, mode);
2000 rtx x;
2002 /* Main add/subtract of the input operands. */
2003 x = expand_binop (word_mode, binoptab,
2004 op0_piece, op1_piece,
2005 target_piece, unsignedp, next_methods);
2006 if (x == 0)
2007 break;
2009 if (i + 1 < nwords)
2011 /* Store carry from main add/subtract. */
2012 carry_out = gen_reg_rtx (word_mode);
2013 carry_out = emit_store_flag_force (carry_out,
2014 (binoptab == add_optab
2015 ? LT : GT),
2016 x, op0_piece,
2017 word_mode, 1, normalizep);
2020 if (i > 0)
2022 rtx newx;
2024 /* Add/subtract previous carry to main result. */
2025 newx = expand_binop (word_mode,
2026 normalizep == 1 ? binoptab : otheroptab,
2027 x, carry_in,
2028 NULL_RTX, 1, next_methods);
2030 if (i + 1 < nwords)
2032 /* Get out carry from adding/subtracting carry in. */
2033 rtx carry_tmp = gen_reg_rtx (word_mode);
2034 carry_tmp = emit_store_flag_force (carry_tmp,
2035 (binoptab == add_optab
2036 ? LT : GT),
2037 newx, x,
2038 word_mode, 1, normalizep);
2040 /* Logical-ior the two poss. carry together. */
2041 carry_out = expand_binop (word_mode, ior_optab,
2042 carry_out, carry_tmp,
2043 carry_out, 0, next_methods);
2044 if (carry_out == 0)
2045 break;
2047 emit_move_insn (target_piece, newx);
2049 else
2051 if (x != target_piece)
2052 emit_move_insn (target_piece, x);
2055 carry_in = carry_out;
2058 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
2060 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing
2061 || ! rtx_equal_p (target, xtarget))
2063 rtx temp = emit_move_insn (target, xtarget);
2065 set_dst_reg_note (temp, REG_EQUAL,
2066 gen_rtx_fmt_ee (optab_to_code (binoptab),
2067 mode, copy_rtx (xop0),
2068 copy_rtx (xop1)),
2069 target);
2071 else
2072 target = xtarget;
2074 return target;
2077 else
2078 delete_insns_since (last);
2081 /* Attempt to synthesize double word multiplies using a sequence of word
2082 mode multiplications. We first attempt to generate a sequence using a
2083 more efficient unsigned widening multiply, and if that fails we then
2084 try using a signed widening multiply. */
2086 if (binoptab == smul_optab
2087 && mclass == MODE_INT
2088 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2089 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
2090 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
2092 rtx product = NULL_RTX;
2093 if (widening_optab_handler (umul_widen_optab, mode, word_mode)
2094 != CODE_FOR_nothing)
2096 product = expand_doubleword_mult (mode, op0, op1, target,
2097 true, methods);
2098 if (!product)
2099 delete_insns_since (last);
2102 if (product == NULL_RTX
2103 && widening_optab_handler (smul_widen_optab, mode, word_mode)
2104 != CODE_FOR_nothing)
2106 product = expand_doubleword_mult (mode, op0, op1, target,
2107 false, methods);
2108 if (!product)
2109 delete_insns_since (last);
2112 if (product != NULL_RTX)
2114 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing)
2116 temp = emit_move_insn (target ? target : product, product);
2117 set_dst_reg_note (temp,
2118 REG_EQUAL,
2119 gen_rtx_fmt_ee (MULT, mode,
2120 copy_rtx (op0),
2121 copy_rtx (op1)),
2122 target ? target : product);
2124 return product;
2128 /* It can't be open-coded in this mode.
2129 Use a library call if one is available and caller says that's ok. */
2131 libfunc = optab_libfunc (binoptab, mode);
2132 if (libfunc
2133 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
2135 rtx_insn *insns;
2136 rtx op1x = op1;
2137 machine_mode op1_mode = mode;
2138 rtx value;
2140 start_sequence ();
2142 if (shift_optab_p (binoptab))
2144 op1_mode = targetm.libgcc_shift_count_mode ();
2145 /* Specify unsigned here,
2146 since negative shift counts are meaningless. */
2147 op1x = convert_to_mode (op1_mode, op1, 1);
2150 if (GET_MODE (op0) != VOIDmode
2151 && GET_MODE (op0) != mode)
2152 op0 = convert_to_mode (mode, op0, unsignedp);
2154 /* Pass 1 for NO_QUEUE so we don't lose any increments
2155 if the libcall is cse'd or moved. */
2156 value = emit_library_call_value (libfunc,
2157 NULL_RTX, LCT_CONST, mode, 2,
2158 op0, mode, op1x, op1_mode);
2160 insns = get_insns ();
2161 end_sequence ();
2163 target = gen_reg_rtx (mode);
2164 emit_libcall_block_1 (insns, target, value,
2165 gen_rtx_fmt_ee (optab_to_code (binoptab),
2166 mode, op0, op1),
2167 trapv_binoptab_p (binoptab));
2169 return target;
2172 delete_insns_since (last);
2174 /* It can't be done in this mode. Can we do it in a wider mode? */
2176 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
2177 || methods == OPTAB_MUST_WIDEN))
2179 /* Caller says, don't even try. */
2180 delete_insns_since (entry_last);
2181 return 0;
2184 /* Compute the value of METHODS to pass to recursive calls.
2185 Don't allow widening to be tried recursively. */
2187 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
2189 /* Look for a wider mode of the same class for which it appears we can do
2190 the operation. */
2192 if (CLASS_HAS_WIDER_MODES_P (mclass))
2194 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2195 wider_mode != VOIDmode;
2196 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2198 if (find_widening_optab_handler (binoptab, wider_mode, mode, 1)
2199 != CODE_FOR_nothing
2200 || (methods == OPTAB_LIB
2201 && optab_libfunc (binoptab, wider_mode)))
2203 rtx xop0 = op0, xop1 = op1;
2204 int no_extend = 0;
2206 /* For certain integer operations, we need not actually extend
2207 the narrow operands, as long as we will truncate
2208 the results to the same narrowness. */
2210 if ((binoptab == ior_optab || binoptab == and_optab
2211 || binoptab == xor_optab
2212 || binoptab == add_optab || binoptab == sub_optab
2213 || binoptab == smul_optab || binoptab == ashl_optab)
2214 && mclass == MODE_INT)
2215 no_extend = 1;
2217 xop0 = widen_operand (xop0, wider_mode, mode,
2218 unsignedp, no_extend);
2220 /* The second operand of a shift must always be extended. */
2221 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
2222 no_extend && binoptab != ashl_optab);
2224 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
2225 unsignedp, methods);
2226 if (temp)
2228 if (mclass != MODE_INT
2229 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2231 if (target == 0)
2232 target = gen_reg_rtx (mode);
2233 convert_move (target, temp, 0);
2234 return target;
2236 else
2237 return gen_lowpart (mode, temp);
2239 else
2240 delete_insns_since (last);
2245 delete_insns_since (entry_last);
2246 return 0;
2249 /* Expand a binary operator which has both signed and unsigned forms.
2250 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2251 signed operations.
2253 If we widen unsigned operands, we may use a signed wider operation instead
2254 of an unsigned wider operation, since the result would be the same. */
2257 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
2258 rtx op0, rtx op1, rtx target, int unsignedp,
2259 enum optab_methods methods)
2261 rtx temp;
2262 optab direct_optab = unsignedp ? uoptab : soptab;
2263 bool save_enable;
2265 /* Do it without widening, if possible. */
2266 temp = expand_binop (mode, direct_optab, op0, op1, target,
2267 unsignedp, OPTAB_DIRECT);
2268 if (temp || methods == OPTAB_DIRECT)
2269 return temp;
2271 /* Try widening to a signed int. Disable any direct use of any
2272 signed insn in the current mode. */
2273 save_enable = swap_optab_enable (soptab, mode, false);
2275 temp = expand_binop (mode, soptab, op0, op1, target,
2276 unsignedp, OPTAB_WIDEN);
2278 /* For unsigned operands, try widening to an unsigned int. */
2279 if (!temp && unsignedp)
2280 temp = expand_binop (mode, uoptab, op0, op1, target,
2281 unsignedp, OPTAB_WIDEN);
2282 if (temp || methods == OPTAB_WIDEN)
2283 goto egress;
2285 /* Use the right width libcall if that exists. */
2286 temp = expand_binop (mode, direct_optab, op0, op1, target,
2287 unsignedp, OPTAB_LIB);
2288 if (temp || methods == OPTAB_LIB)
2289 goto egress;
2291 /* Must widen and use a libcall, use either signed or unsigned. */
2292 temp = expand_binop (mode, soptab, op0, op1, target,
2293 unsignedp, methods);
2294 if (!temp && unsignedp)
2295 temp = expand_binop (mode, uoptab, op0, op1, target,
2296 unsignedp, methods);
2298 egress:
2299 /* Undo the fiddling above. */
2300 if (save_enable)
2301 swap_optab_enable (soptab, mode, true);
2302 return temp;
2305 /* Generate code to perform an operation specified by UNOPPTAB
2306 on operand OP0, with two results to TARG0 and TARG1.
2307 We assume that the order of the operands for the instruction
2308 is TARG0, TARG1, OP0.
2310 Either TARG0 or TARG1 may be zero, but what that means is that
2311 the result is not actually wanted. We will generate it into
2312 a dummy pseudo-reg and discard it. They may not both be zero.
2314 Returns 1 if this operation can be performed; 0 if not. */
2317 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2318 int unsignedp)
2320 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2321 enum mode_class mclass;
2322 machine_mode wider_mode;
2323 rtx_insn *entry_last = get_last_insn ();
2324 rtx_insn *last;
2326 mclass = GET_MODE_CLASS (mode);
2328 if (!targ0)
2329 targ0 = gen_reg_rtx (mode);
2330 if (!targ1)
2331 targ1 = gen_reg_rtx (mode);
2333 /* Record where to go back to if we fail. */
2334 last = get_last_insn ();
2336 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2338 struct expand_operand ops[3];
2339 enum insn_code icode = optab_handler (unoptab, mode);
2341 create_fixed_operand (&ops[0], targ0);
2342 create_fixed_operand (&ops[1], targ1);
2343 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
2344 if (maybe_expand_insn (icode, 3, ops))
2345 return 1;
2348 /* It can't be done in this mode. Can we do it in a wider mode? */
2350 if (CLASS_HAS_WIDER_MODES_P (mclass))
2352 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2353 wider_mode != VOIDmode;
2354 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2356 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2358 rtx t0 = gen_reg_rtx (wider_mode);
2359 rtx t1 = gen_reg_rtx (wider_mode);
2360 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2362 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2364 convert_move (targ0, t0, unsignedp);
2365 convert_move (targ1, t1, unsignedp);
2366 return 1;
2368 else
2369 delete_insns_since (last);
2374 delete_insns_since (entry_last);
2375 return 0;
2378 /* Generate code to perform an operation specified by BINOPTAB
2379 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2380 We assume that the order of the operands for the instruction
2381 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2382 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2384 Either TARG0 or TARG1 may be zero, but what that means is that
2385 the result is not actually wanted. We will generate it into
2386 a dummy pseudo-reg and discard it. They may not both be zero.
2388 Returns 1 if this operation can be performed; 0 if not. */
2391 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2392 int unsignedp)
2394 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2395 enum mode_class mclass;
2396 machine_mode wider_mode;
2397 rtx_insn *entry_last = get_last_insn ();
2398 rtx_insn *last;
2400 mclass = GET_MODE_CLASS (mode);
2402 if (!targ0)
2403 targ0 = gen_reg_rtx (mode);
2404 if (!targ1)
2405 targ1 = gen_reg_rtx (mode);
2407 /* Record where to go back to if we fail. */
2408 last = get_last_insn ();
2410 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2412 struct expand_operand ops[4];
2413 enum insn_code icode = optab_handler (binoptab, mode);
2414 machine_mode mode0 = insn_data[icode].operand[1].mode;
2415 machine_mode mode1 = insn_data[icode].operand[2].mode;
2416 rtx xop0 = op0, xop1 = op1;
2418 /* If we are optimizing, force expensive constants into a register. */
2419 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2420 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2422 create_fixed_operand (&ops[0], targ0);
2423 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2424 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
2425 create_fixed_operand (&ops[3], targ1);
2426 if (maybe_expand_insn (icode, 4, ops))
2427 return 1;
2428 delete_insns_since (last);
2431 /* It can't be done in this mode. Can we do it in a wider mode? */
2433 if (CLASS_HAS_WIDER_MODES_P (mclass))
2435 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2436 wider_mode != VOIDmode;
2437 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2439 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2441 rtx t0 = gen_reg_rtx (wider_mode);
2442 rtx t1 = gen_reg_rtx (wider_mode);
2443 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2444 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2446 if (expand_twoval_binop (binoptab, cop0, cop1,
2447 t0, t1, unsignedp))
2449 convert_move (targ0, t0, unsignedp);
2450 convert_move (targ1, t1, unsignedp);
2451 return 1;
2453 else
2454 delete_insns_since (last);
2459 delete_insns_since (entry_last);
2460 return 0;
2463 /* Expand the two-valued library call indicated by BINOPTAB, but
2464 preserve only one of the values. If TARG0 is non-NULL, the first
2465 value is placed into TARG0; otherwise the second value is placed
2466 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2467 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2468 This routine assumes that the value returned by the library call is
2469 as if the return value was of an integral mode twice as wide as the
2470 mode of OP0. Returns 1 if the call was successful. */
2472 bool
2473 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2474 rtx targ0, rtx targ1, enum rtx_code code)
2476 machine_mode mode;
2477 machine_mode libval_mode;
2478 rtx libval;
2479 rtx_insn *insns;
2480 rtx libfunc;
2482 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2483 gcc_assert (!targ0 != !targ1);
2485 mode = GET_MODE (op0);
2486 libfunc = optab_libfunc (binoptab, mode);
2487 if (!libfunc)
2488 return false;
2490 /* The value returned by the library function will have twice as
2491 many bits as the nominal MODE. */
2492 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2493 MODE_INT);
2494 start_sequence ();
2495 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2496 libval_mode, 2,
2497 op0, mode,
2498 op1, mode);
2499 /* Get the part of VAL containing the value that we want. */
2500 libval = simplify_gen_subreg (mode, libval, libval_mode,
2501 targ0 ? 0 : GET_MODE_SIZE (mode));
2502 insns = get_insns ();
2503 end_sequence ();
2504 /* Move the into the desired location. */
2505 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2506 gen_rtx_fmt_ee (code, mode, op0, op1));
2508 return true;
2512 /* Wrapper around expand_unop which takes an rtx code to specify
2513 the operation to perform, not an optab pointer. All other
2514 arguments are the same. */
2516 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
2517 rtx target, int unsignedp)
2519 optab unop = code_to_optab (code);
2520 gcc_assert (unop);
2522 return expand_unop (mode, unop, op0, target, unsignedp);
2525 /* Try calculating
2526 (clz:narrow x)
2528 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2530 A similar operation can be used for clrsb. UNOPTAB says which operation
2531 we are trying to expand. */
2532 static rtx
2533 widen_leading (machine_mode mode, rtx op0, rtx target, optab unoptab)
2535 enum mode_class mclass = GET_MODE_CLASS (mode);
2536 if (CLASS_HAS_WIDER_MODES_P (mclass))
2538 machine_mode wider_mode;
2539 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2540 wider_mode != VOIDmode;
2541 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2543 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2545 rtx xop0, temp;
2546 rtx_insn *last;
2548 last = get_last_insn ();
2550 if (target == 0)
2551 target = gen_reg_rtx (mode);
2552 xop0 = widen_operand (op0, wider_mode, mode,
2553 unoptab != clrsb_optab, false);
2554 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2555 unoptab != clrsb_optab);
2556 if (temp != 0)
2557 temp = expand_binop
2558 (wider_mode, sub_optab, temp,
2559 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2560 - GET_MODE_PRECISION (mode),
2561 wider_mode),
2562 target, true, OPTAB_DIRECT);
2563 if (temp == 0)
2564 delete_insns_since (last);
2566 return temp;
2570 return 0;
2573 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2574 quantities, choosing which based on whether the high word is nonzero. */
2575 static rtx
2576 expand_doubleword_clz (machine_mode mode, rtx op0, rtx target)
2578 rtx xop0 = force_reg (mode, op0);
2579 rtx subhi = gen_highpart (word_mode, xop0);
2580 rtx sublo = gen_lowpart (word_mode, xop0);
2581 rtx_code_label *hi0_label = gen_label_rtx ();
2582 rtx_code_label *after_label = gen_label_rtx ();
2583 rtx_insn *seq;
2584 rtx temp, result;
2586 /* If we were not given a target, use a word_mode register, not a
2587 'mode' register. The result will fit, and nobody is expecting
2588 anything bigger (the return type of __builtin_clz* is int). */
2589 if (!target)
2590 target = gen_reg_rtx (word_mode);
2592 /* In any case, write to a word_mode scratch in both branches of the
2593 conditional, so we can ensure there is a single move insn setting
2594 'target' to tag a REG_EQUAL note on. */
2595 result = gen_reg_rtx (word_mode);
2597 start_sequence ();
2599 /* If the high word is not equal to zero,
2600 then clz of the full value is clz of the high word. */
2601 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2602 word_mode, true, hi0_label);
2604 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2605 if (!temp)
2606 goto fail;
2608 if (temp != result)
2609 convert_move (result, temp, true);
2611 emit_jump_insn (gen_jump (after_label));
2612 emit_barrier ();
2614 /* Else clz of the full value is clz of the low word plus the number
2615 of bits in the high word. */
2616 emit_label (hi0_label);
2618 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2619 if (!temp)
2620 goto fail;
2621 temp = expand_binop (word_mode, add_optab, temp,
2622 gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode),
2623 result, true, OPTAB_DIRECT);
2624 if (!temp)
2625 goto fail;
2626 if (temp != result)
2627 convert_move (result, temp, true);
2629 emit_label (after_label);
2630 convert_move (target, result, true);
2632 seq = get_insns ();
2633 end_sequence ();
2635 add_equal_note (seq, target, CLZ, xop0, 0);
2636 emit_insn (seq);
2637 return target;
2639 fail:
2640 end_sequence ();
2641 return 0;
2644 /* Try calculating
2645 (bswap:narrow x)
2647 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2648 static rtx
2649 widen_bswap (machine_mode mode, rtx op0, rtx target)
2651 enum mode_class mclass = GET_MODE_CLASS (mode);
2652 machine_mode wider_mode;
2653 rtx x;
2654 rtx_insn *last;
2656 if (!CLASS_HAS_WIDER_MODES_P (mclass))
2657 return NULL_RTX;
2659 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2660 wider_mode != VOIDmode;
2661 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2662 if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing)
2663 goto found;
2664 return NULL_RTX;
2666 found:
2667 last = get_last_insn ();
2669 x = widen_operand (op0, wider_mode, mode, true, true);
2670 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2672 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2673 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2674 if (x != 0)
2675 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2676 GET_MODE_BITSIZE (wider_mode)
2677 - GET_MODE_BITSIZE (mode),
2678 NULL_RTX, true);
2680 if (x != 0)
2682 if (target == 0)
2683 target = gen_reg_rtx (mode);
2684 emit_move_insn (target, gen_lowpart (mode, x));
2686 else
2687 delete_insns_since (last);
2689 return target;
2692 /* Try calculating bswap as two bswaps of two word-sized operands. */
2694 static rtx
2695 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2697 rtx t0, t1;
2699 t1 = expand_unop (word_mode, bswap_optab,
2700 operand_subword_force (op, 0, mode), NULL_RTX, true);
2701 t0 = expand_unop (word_mode, bswap_optab,
2702 operand_subword_force (op, 1, mode), NULL_RTX, true);
2704 if (target == 0 || !valid_multiword_target_p (target))
2705 target = gen_reg_rtx (mode);
2706 if (REG_P (target))
2707 emit_clobber (target);
2708 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2709 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2711 return target;
2714 /* Try calculating (parity x) as (and (popcount x) 1), where
2715 popcount can also be done in a wider mode. */
2716 static rtx
2717 expand_parity (machine_mode mode, rtx op0, rtx target)
2719 enum mode_class mclass = GET_MODE_CLASS (mode);
2720 if (CLASS_HAS_WIDER_MODES_P (mclass))
2722 machine_mode wider_mode;
2723 for (wider_mode = mode; wider_mode != VOIDmode;
2724 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2726 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2728 rtx xop0, temp;
2729 rtx_insn *last;
2731 last = get_last_insn ();
2733 if (target == 0)
2734 target = gen_reg_rtx (mode);
2735 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2736 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2737 true);
2738 if (temp != 0)
2739 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2740 target, true, OPTAB_DIRECT);
2741 if (temp == 0)
2742 delete_insns_since (last);
2744 return temp;
2748 return 0;
2751 /* Try calculating ctz(x) as K - clz(x & -x) ,
2752 where K is GET_MODE_PRECISION(mode) - 1.
2754 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2755 don't have to worry about what the hardware does in that case. (If
2756 the clz instruction produces the usual value at 0, which is K, the
2757 result of this code sequence will be -1; expand_ffs, below, relies
2758 on this. It might be nice to have it be K instead, for consistency
2759 with the (very few) processors that provide a ctz with a defined
2760 value, but that would take one more instruction, and it would be
2761 less convenient for expand_ffs anyway. */
2763 static rtx
2764 expand_ctz (machine_mode mode, rtx op0, rtx target)
2766 rtx_insn *seq;
2767 rtx temp;
2769 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2770 return 0;
2772 start_sequence ();
2774 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2775 if (temp)
2776 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2777 true, OPTAB_DIRECT);
2778 if (temp)
2779 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2780 if (temp)
2781 temp = expand_binop (mode, sub_optab,
2782 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2783 temp, target,
2784 true, OPTAB_DIRECT);
2785 if (temp == 0)
2787 end_sequence ();
2788 return 0;
2791 seq = get_insns ();
2792 end_sequence ();
2794 add_equal_note (seq, temp, CTZ, op0, 0);
2795 emit_insn (seq);
2796 return temp;
2800 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2801 else with the sequence used by expand_clz.
2803 The ffs builtin promises to return zero for a zero value and ctz/clz
2804 may have an undefined value in that case. If they do not give us a
2805 convenient value, we have to generate a test and branch. */
2806 static rtx
2807 expand_ffs (machine_mode mode, rtx op0, rtx target)
2809 HOST_WIDE_INT val = 0;
2810 bool defined_at_zero = false;
2811 rtx temp;
2812 rtx_insn *seq;
2814 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2816 start_sequence ();
2818 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2819 if (!temp)
2820 goto fail;
2822 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2824 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2826 start_sequence ();
2827 temp = expand_ctz (mode, op0, 0);
2828 if (!temp)
2829 goto fail;
2831 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2833 defined_at_zero = true;
2834 val = (GET_MODE_PRECISION (mode) - 1) - val;
2837 else
2838 return 0;
2840 if (defined_at_zero && val == -1)
2841 /* No correction needed at zero. */;
2842 else
2844 /* We don't try to do anything clever with the situation found
2845 on some processors (eg Alpha) where ctz(0:mode) ==
2846 bitsize(mode). If someone can think of a way to send N to -1
2847 and leave alone all values in the range 0..N-1 (where N is a
2848 power of two), cheaper than this test-and-branch, please add it.
2850 The test-and-branch is done after the operation itself, in case
2851 the operation sets condition codes that can be recycled for this.
2852 (This is true on i386, for instance.) */
2854 rtx_code_label *nonzero_label = gen_label_rtx ();
2855 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2856 mode, true, nonzero_label);
2858 convert_move (temp, GEN_INT (-1), false);
2859 emit_label (nonzero_label);
2862 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2863 to produce a value in the range 0..bitsize. */
2864 temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
2865 target, false, OPTAB_DIRECT);
2866 if (!temp)
2867 goto fail;
2869 seq = get_insns ();
2870 end_sequence ();
2872 add_equal_note (seq, temp, FFS, op0, 0);
2873 emit_insn (seq);
2874 return temp;
2876 fail:
2877 end_sequence ();
2878 return 0;
2881 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2882 conditions, VAL may already be a SUBREG against which we cannot generate
2883 a further SUBREG. In this case, we expect forcing the value into a
2884 register will work around the situation. */
2886 static rtx
2887 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
2888 machine_mode imode)
2890 rtx ret;
2891 ret = lowpart_subreg (omode, val, imode);
2892 if (ret == NULL)
2894 val = force_reg (imode, val);
2895 ret = lowpart_subreg (omode, val, imode);
2896 gcc_assert (ret != NULL);
2898 return ret;
2901 /* Expand a floating point absolute value or negation operation via a
2902 logical operation on the sign bit. */
2904 static rtx
2905 expand_absneg_bit (enum rtx_code code, machine_mode mode,
2906 rtx op0, rtx target)
2908 const struct real_format *fmt;
2909 int bitpos, word, nwords, i;
2910 machine_mode imode;
2911 rtx temp;
2912 rtx_insn *insns;
2914 /* The format has to have a simple sign bit. */
2915 fmt = REAL_MODE_FORMAT (mode);
2916 if (fmt == NULL)
2917 return NULL_RTX;
2919 bitpos = fmt->signbit_rw;
2920 if (bitpos < 0)
2921 return NULL_RTX;
2923 /* Don't create negative zeros if the format doesn't support them. */
2924 if (code == NEG && !fmt->has_signed_zero)
2925 return NULL_RTX;
2927 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2929 imode = int_mode_for_mode (mode);
2930 if (imode == BLKmode)
2931 return NULL_RTX;
2932 word = 0;
2933 nwords = 1;
2935 else
2937 imode = word_mode;
2939 if (FLOAT_WORDS_BIG_ENDIAN)
2940 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2941 else
2942 word = bitpos / BITS_PER_WORD;
2943 bitpos = bitpos % BITS_PER_WORD;
2944 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2947 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
2948 if (code == ABS)
2949 mask = ~mask;
2951 if (target == 0
2952 || target == op0
2953 || (nwords > 1 && !valid_multiword_target_p (target)))
2954 target = gen_reg_rtx (mode);
2956 if (nwords > 1)
2958 start_sequence ();
2960 for (i = 0; i < nwords; ++i)
2962 rtx targ_piece = operand_subword (target, i, 1, mode);
2963 rtx op0_piece = operand_subword_force (op0, i, mode);
2965 if (i == word)
2967 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2968 op0_piece,
2969 immed_wide_int_const (mask, imode),
2970 targ_piece, 1, OPTAB_LIB_WIDEN);
2971 if (temp != targ_piece)
2972 emit_move_insn (targ_piece, temp);
2974 else
2975 emit_move_insn (targ_piece, op0_piece);
2978 insns = get_insns ();
2979 end_sequence ();
2981 emit_insn (insns);
2983 else
2985 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2986 gen_lowpart (imode, op0),
2987 immed_wide_int_const (mask, imode),
2988 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2989 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2991 set_dst_reg_note (get_last_insn (), REG_EQUAL,
2992 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
2993 target);
2996 return target;
2999 /* As expand_unop, but will fail rather than attempt the operation in a
3000 different mode or with a libcall. */
3001 static rtx
3002 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
3003 int unsignedp)
3005 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
3007 struct expand_operand ops[2];
3008 enum insn_code icode = optab_handler (unoptab, mode);
3009 rtx_insn *last = get_last_insn ();
3010 rtx pat;
3012 create_output_operand (&ops[0], target, mode);
3013 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
3014 pat = maybe_gen_insn (icode, 2, ops);
3015 if (pat)
3017 if (INSN_P (pat) && NEXT_INSN (as_a <rtx_insn *> (pat)) != NULL_RTX
3018 && ! add_equal_note (as_a <rtx_insn *> (pat), ops[0].value,
3019 optab_to_code (unoptab),
3020 ops[1].value, NULL_RTX))
3022 delete_insns_since (last);
3023 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
3026 emit_insn (pat);
3028 return ops[0].value;
3031 return 0;
3034 /* Generate code to perform an operation specified by UNOPTAB
3035 on operand OP0, with result having machine-mode MODE.
3037 UNSIGNEDP is for the case where we have to widen the operands
3038 to perform the operation. It says to use zero-extension.
3040 If TARGET is nonzero, the value
3041 is generated there, if it is convenient to do so.
3042 In all cases an rtx is returned for the locus of the value;
3043 this may or may not be TARGET. */
3046 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
3047 int unsignedp)
3049 enum mode_class mclass = GET_MODE_CLASS (mode);
3050 machine_mode wider_mode;
3051 rtx temp;
3052 rtx libfunc;
3054 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
3055 if (temp)
3056 return temp;
3058 /* It can't be done in this mode. Can we open-code it in a wider mode? */
3060 /* Widening (or narrowing) clz needs special treatment. */
3061 if (unoptab == clz_optab)
3063 temp = widen_leading (mode, op0, target, unoptab);
3064 if (temp)
3065 return temp;
3067 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
3068 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3070 temp = expand_doubleword_clz (mode, op0, target);
3071 if (temp)
3072 return temp;
3075 goto try_libcall;
3078 if (unoptab == clrsb_optab)
3080 temp = widen_leading (mode, op0, target, unoptab);
3081 if (temp)
3082 return temp;
3083 goto try_libcall;
3086 /* Widening (or narrowing) bswap needs special treatment. */
3087 if (unoptab == bswap_optab)
3089 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
3090 or ROTATERT. First try these directly; if this fails, then try the
3091 obvious pair of shifts with allowed widening, as this will probably
3092 be always more efficient than the other fallback methods. */
3093 if (mode == HImode)
3095 rtx_insn *last;
3096 rtx temp1, temp2;
3098 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
3100 temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target,
3101 unsignedp, OPTAB_DIRECT);
3102 if (temp)
3103 return temp;
3106 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
3108 temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target,
3109 unsignedp, OPTAB_DIRECT);
3110 if (temp)
3111 return temp;
3114 last = get_last_insn ();
3116 temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX,
3117 unsignedp, OPTAB_WIDEN);
3118 temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX,
3119 unsignedp, OPTAB_WIDEN);
3120 if (temp1 && temp2)
3122 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
3123 unsignedp, OPTAB_WIDEN);
3124 if (temp)
3125 return temp;
3128 delete_insns_since (last);
3131 temp = widen_bswap (mode, op0, target);
3132 if (temp)
3133 return temp;
3135 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
3136 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3138 temp = expand_doubleword_bswap (mode, op0, target);
3139 if (temp)
3140 return temp;
3143 goto try_libcall;
3146 if (CLASS_HAS_WIDER_MODES_P (mclass))
3147 for (wider_mode = GET_MODE_WIDER_MODE (mode);
3148 wider_mode != VOIDmode;
3149 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3151 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
3153 rtx xop0 = op0;
3154 rtx_insn *last = get_last_insn ();
3156 /* For certain operations, we need not actually extend
3157 the narrow operand, as long as we will truncate the
3158 results to the same narrowness. */
3160 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3161 (unoptab == neg_optab
3162 || unoptab == one_cmpl_optab)
3163 && mclass == MODE_INT);
3165 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3166 unsignedp);
3168 if (temp)
3170 if (mclass != MODE_INT
3171 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
3173 if (target == 0)
3174 target = gen_reg_rtx (mode);
3175 convert_move (target, temp, 0);
3176 return target;
3178 else
3179 return gen_lowpart (mode, temp);
3181 else
3182 delete_insns_since (last);
3186 /* These can be done a word at a time. */
3187 if (unoptab == one_cmpl_optab
3188 && mclass == MODE_INT
3189 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
3190 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3192 int i;
3193 rtx_insn *insns;
3195 if (target == 0 || target == op0 || !valid_multiword_target_p (target))
3196 target = gen_reg_rtx (mode);
3198 start_sequence ();
3200 /* Do the actual arithmetic. */
3201 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
3203 rtx target_piece = operand_subword (target, i, 1, mode);
3204 rtx x = expand_unop (word_mode, unoptab,
3205 operand_subword_force (op0, i, mode),
3206 target_piece, unsignedp);
3208 if (target_piece != x)
3209 emit_move_insn (target_piece, x);
3212 insns = get_insns ();
3213 end_sequence ();
3215 emit_insn (insns);
3216 return target;
3219 if (optab_to_code (unoptab) == NEG)
3221 /* Try negating floating point values by flipping the sign bit. */
3222 if (SCALAR_FLOAT_MODE_P (mode))
3224 temp = expand_absneg_bit (NEG, mode, op0, target);
3225 if (temp)
3226 return temp;
3229 /* If there is no negation pattern, and we have no negative zero,
3230 try subtracting from zero. */
3231 if (!HONOR_SIGNED_ZEROS (mode))
3233 temp = expand_binop (mode, (unoptab == negv_optab
3234 ? subv_optab : sub_optab),
3235 CONST0_RTX (mode), op0, target,
3236 unsignedp, OPTAB_DIRECT);
3237 if (temp)
3238 return temp;
3242 /* Try calculating parity (x) as popcount (x) % 2. */
3243 if (unoptab == parity_optab)
3245 temp = expand_parity (mode, op0, target);
3246 if (temp)
3247 return temp;
3250 /* Try implementing ffs (x) in terms of clz (x). */
3251 if (unoptab == ffs_optab)
3253 temp = expand_ffs (mode, op0, target);
3254 if (temp)
3255 return temp;
3258 /* Try implementing ctz (x) in terms of clz (x). */
3259 if (unoptab == ctz_optab)
3261 temp = expand_ctz (mode, op0, target);
3262 if (temp)
3263 return temp;
3266 try_libcall:
3267 /* Now try a library call in this mode. */
3268 libfunc = optab_libfunc (unoptab, mode);
3269 if (libfunc)
3271 rtx_insn *insns;
3272 rtx value;
3273 rtx eq_value;
3274 machine_mode outmode = mode;
3276 /* All of these functions return small values. Thus we choose to
3277 have them return something that isn't a double-word. */
3278 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3279 || unoptab == clrsb_optab || unoptab == popcount_optab
3280 || unoptab == parity_optab)
3281 outmode
3282 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
3283 optab_libfunc (unoptab, mode)));
3285 start_sequence ();
3287 /* Pass 1 for NO_QUEUE so we don't lose any increments
3288 if the libcall is cse'd or moved. */
3289 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
3290 1, op0, mode);
3291 insns = get_insns ();
3292 end_sequence ();
3294 target = gen_reg_rtx (outmode);
3295 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
3296 if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode))
3297 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
3298 else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
3299 eq_value = simplify_gen_unary (ZERO_EXTEND, outmode, eq_value, mode);
3300 emit_libcall_block_1 (insns, target, value, eq_value,
3301 trapv_unoptab_p (unoptab));
3303 return target;
3306 /* It can't be done in this mode. Can we do it in a wider mode? */
3308 if (CLASS_HAS_WIDER_MODES_P (mclass))
3310 for (wider_mode = GET_MODE_WIDER_MODE (mode);
3311 wider_mode != VOIDmode;
3312 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3314 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
3315 || optab_libfunc (unoptab, wider_mode))
3317 rtx xop0 = op0;
3318 rtx_insn *last = get_last_insn ();
3320 /* For certain operations, we need not actually extend
3321 the narrow operand, as long as we will truncate the
3322 results to the same narrowness. */
3323 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3324 (unoptab == neg_optab
3325 || unoptab == one_cmpl_optab
3326 || unoptab == bswap_optab)
3327 && mclass == MODE_INT);
3329 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3330 unsignedp);
3332 /* If we are generating clz using wider mode, adjust the
3333 result. Similarly for clrsb. */
3334 if ((unoptab == clz_optab || unoptab == clrsb_optab)
3335 && temp != 0)
3336 temp = expand_binop
3337 (wider_mode, sub_optab, temp,
3338 gen_int_mode (GET_MODE_PRECISION (wider_mode)
3339 - GET_MODE_PRECISION (mode),
3340 wider_mode),
3341 target, true, OPTAB_DIRECT);
3343 /* Likewise for bswap. */
3344 if (unoptab == bswap_optab && temp != 0)
3346 gcc_assert (GET_MODE_PRECISION (wider_mode)
3347 == GET_MODE_BITSIZE (wider_mode)
3348 && GET_MODE_PRECISION (mode)
3349 == GET_MODE_BITSIZE (mode));
3351 temp = expand_shift (RSHIFT_EXPR, wider_mode, temp,
3352 GET_MODE_BITSIZE (wider_mode)
3353 - GET_MODE_BITSIZE (mode),
3354 NULL_RTX, true);
3357 if (temp)
3359 if (mclass != MODE_INT)
3361 if (target == 0)
3362 target = gen_reg_rtx (mode);
3363 convert_move (target, temp, 0);
3364 return target;
3366 else
3367 return gen_lowpart (mode, temp);
3369 else
3370 delete_insns_since (last);
3375 /* One final attempt at implementing negation via subtraction,
3376 this time allowing widening of the operand. */
3377 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
3379 rtx temp;
3380 temp = expand_binop (mode,
3381 unoptab == negv_optab ? subv_optab : sub_optab,
3382 CONST0_RTX (mode), op0,
3383 target, unsignedp, OPTAB_LIB_WIDEN);
3384 if (temp)
3385 return temp;
3388 return 0;
3391 /* Emit code to compute the absolute value of OP0, with result to
3392 TARGET if convenient. (TARGET may be 0.) The return value says
3393 where the result actually is to be found.
3395 MODE is the mode of the operand; the mode of the result is
3396 different but can be deduced from MODE.
3401 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
3402 int result_unsignedp)
3404 rtx temp;
3406 if (GET_MODE_CLASS (mode) != MODE_INT
3407 || ! flag_trapv)
3408 result_unsignedp = 1;
3410 /* First try to do it with a special abs instruction. */
3411 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3412 op0, target, 0);
3413 if (temp != 0)
3414 return temp;
3416 /* For floating point modes, try clearing the sign bit. */
3417 if (SCALAR_FLOAT_MODE_P (mode))
3419 temp = expand_absneg_bit (ABS, mode, op0, target);
3420 if (temp)
3421 return temp;
3424 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3425 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3426 && !HONOR_SIGNED_ZEROS (mode))
3428 rtx_insn *last = get_last_insn ();
3430 temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3431 op0, NULL_RTX, 0);
3432 if (temp != 0)
3433 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3434 OPTAB_WIDEN);
3436 if (temp != 0)
3437 return temp;
3439 delete_insns_since (last);
3442 /* If this machine has expensive jumps, we can do integer absolute
3443 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3444 where W is the width of MODE. */
3446 if (GET_MODE_CLASS (mode) == MODE_INT
3447 && BRANCH_COST (optimize_insn_for_speed_p (),
3448 false) >= 2)
3450 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3451 GET_MODE_PRECISION (mode) - 1,
3452 NULL_RTX, 0);
3454 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3455 OPTAB_LIB_WIDEN);
3456 if (temp != 0)
3457 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3458 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3460 if (temp != 0)
3461 return temp;
3464 return NULL_RTX;
3468 expand_abs (machine_mode mode, rtx op0, rtx target,
3469 int result_unsignedp, int safe)
3471 rtx temp;
3472 rtx_code_label *op1;
3474 if (GET_MODE_CLASS (mode) != MODE_INT
3475 || ! flag_trapv)
3476 result_unsignedp = 1;
3478 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3479 if (temp != 0)
3480 return temp;
3482 /* If that does not win, use conditional jump and negate. */
3484 /* It is safe to use the target if it is the same
3485 as the source if this is also a pseudo register */
3486 if (op0 == target && REG_P (op0)
3487 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3488 safe = 1;
3490 op1 = gen_label_rtx ();
3491 if (target == 0 || ! safe
3492 || GET_MODE (target) != mode
3493 || (MEM_P (target) && MEM_VOLATILE_P (target))
3494 || (REG_P (target)
3495 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3496 target = gen_reg_rtx (mode);
3498 emit_move_insn (target, op0);
3499 NO_DEFER_POP;
3501 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3502 NULL_RTX, NULL_RTX, op1, -1);
3504 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3505 target, target, 0);
3506 if (op0 != target)
3507 emit_move_insn (target, op0);
3508 emit_label (op1);
3509 OK_DEFER_POP;
3510 return target;
3513 /* Emit code to compute the one's complement absolute value of OP0
3514 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3515 (TARGET may be NULL_RTX.) The return value says where the result
3516 actually is to be found.
3518 MODE is the mode of the operand; the mode of the result is
3519 different but can be deduced from MODE. */
3522 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
3524 rtx temp;
3526 /* Not applicable for floating point modes. */
3527 if (FLOAT_MODE_P (mode))
3528 return NULL_RTX;
3530 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3531 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3533 rtx_insn *last = get_last_insn ();
3535 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3536 if (temp != 0)
3537 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3538 OPTAB_WIDEN);
3540 if (temp != 0)
3541 return temp;
3543 delete_insns_since (last);
3546 /* If this machine has expensive jumps, we can do one's complement
3547 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3549 if (GET_MODE_CLASS (mode) == MODE_INT
3550 && BRANCH_COST (optimize_insn_for_speed_p (),
3551 false) >= 2)
3553 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3554 GET_MODE_PRECISION (mode) - 1,
3555 NULL_RTX, 0);
3557 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3558 OPTAB_LIB_WIDEN);
3560 if (temp != 0)
3561 return temp;
3564 return NULL_RTX;
3567 /* A subroutine of expand_copysign, perform the copysign operation using the
3568 abs and neg primitives advertised to exist on the target. The assumption
3569 is that we have a split register file, and leaving op0 in fp registers,
3570 and not playing with subregs so much, will help the register allocator. */
3572 static rtx
3573 expand_copysign_absneg (machine_mode mode, rtx op0, rtx op1, rtx target,
3574 int bitpos, bool op0_is_abs)
3576 machine_mode imode;
3577 enum insn_code icode;
3578 rtx sign;
3579 rtx_code_label *label;
3581 if (target == op1)
3582 target = NULL_RTX;
3584 /* Check if the back end provides an insn that handles signbit for the
3585 argument's mode. */
3586 icode = optab_handler (signbit_optab, mode);
3587 if (icode != CODE_FOR_nothing)
3589 imode = insn_data[(int) icode].operand[0].mode;
3590 sign = gen_reg_rtx (imode);
3591 emit_unop_insn (icode, sign, op1, UNKNOWN);
3593 else
3595 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3597 imode = int_mode_for_mode (mode);
3598 if (imode == BLKmode)
3599 return NULL_RTX;
3600 op1 = gen_lowpart (imode, op1);
3602 else
3604 int word;
3606 imode = word_mode;
3607 if (FLOAT_WORDS_BIG_ENDIAN)
3608 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3609 else
3610 word = bitpos / BITS_PER_WORD;
3611 bitpos = bitpos % BITS_PER_WORD;
3612 op1 = operand_subword_force (op1, word, mode);
3615 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3616 sign = expand_binop (imode, and_optab, op1,
3617 immed_wide_int_const (mask, imode),
3618 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3621 if (!op0_is_abs)
3623 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3624 if (op0 == NULL)
3625 return NULL_RTX;
3626 target = op0;
3628 else
3630 if (target == NULL_RTX)
3631 target = copy_to_reg (op0);
3632 else
3633 emit_move_insn (target, op0);
3636 label = gen_label_rtx ();
3637 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3639 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3640 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3641 else
3642 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3643 if (op0 != target)
3644 emit_move_insn (target, op0);
3646 emit_label (label);
3648 return target;
3652 /* A subroutine of expand_copysign, perform the entire copysign operation
3653 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3654 is true if op0 is known to have its sign bit clear. */
3656 static rtx
3657 expand_copysign_bit (machine_mode mode, rtx op0, rtx op1, rtx target,
3658 int bitpos, bool op0_is_abs)
3660 machine_mode imode;
3661 int word, nwords, i;
3662 rtx temp;
3663 rtx_insn *insns;
3665 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3667 imode = int_mode_for_mode (mode);
3668 if (imode == BLKmode)
3669 return NULL_RTX;
3670 word = 0;
3671 nwords = 1;
3673 else
3675 imode = word_mode;
3677 if (FLOAT_WORDS_BIG_ENDIAN)
3678 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3679 else
3680 word = bitpos / BITS_PER_WORD;
3681 bitpos = bitpos % BITS_PER_WORD;
3682 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3685 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3687 if (target == 0
3688 || target == op0
3689 || target == op1
3690 || (nwords > 1 && !valid_multiword_target_p (target)))
3691 target = gen_reg_rtx (mode);
3693 if (nwords > 1)
3695 start_sequence ();
3697 for (i = 0; i < nwords; ++i)
3699 rtx targ_piece = operand_subword (target, i, 1, mode);
3700 rtx op0_piece = operand_subword_force (op0, i, mode);
3702 if (i == word)
3704 if (!op0_is_abs)
3705 op0_piece
3706 = expand_binop (imode, and_optab, op0_piece,
3707 immed_wide_int_const (~mask, imode),
3708 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3709 op1 = expand_binop (imode, and_optab,
3710 operand_subword_force (op1, i, mode),
3711 immed_wide_int_const (mask, imode),
3712 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3714 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3715 targ_piece, 1, OPTAB_LIB_WIDEN);
3716 if (temp != targ_piece)
3717 emit_move_insn (targ_piece, temp);
3719 else
3720 emit_move_insn (targ_piece, op0_piece);
3723 insns = get_insns ();
3724 end_sequence ();
3726 emit_insn (insns);
3728 else
3730 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3731 immed_wide_int_const (mask, imode),
3732 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3734 op0 = gen_lowpart (imode, op0);
3735 if (!op0_is_abs)
3736 op0 = expand_binop (imode, and_optab, op0,
3737 immed_wide_int_const (~mask, imode),
3738 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3740 temp = expand_binop (imode, ior_optab, op0, op1,
3741 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3742 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3745 return target;
3748 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3749 scalar floating point mode. Return NULL if we do not know how to
3750 expand the operation inline. */
3753 expand_copysign (rtx op0, rtx op1, rtx target)
3755 machine_mode mode = GET_MODE (op0);
3756 const struct real_format *fmt;
3757 bool op0_is_abs;
3758 rtx temp;
3760 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3761 gcc_assert (GET_MODE (op1) == mode);
3763 /* First try to do it with a special instruction. */
3764 temp = expand_binop (mode, copysign_optab, op0, op1,
3765 target, 0, OPTAB_DIRECT);
3766 if (temp)
3767 return temp;
3769 fmt = REAL_MODE_FORMAT (mode);
3770 if (fmt == NULL || !fmt->has_signed_zero)
3771 return NULL_RTX;
3773 op0_is_abs = false;
3774 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3776 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3777 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3778 op0_is_abs = true;
3781 if (fmt->signbit_ro >= 0
3782 && (CONST_DOUBLE_AS_FLOAT_P (op0)
3783 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3784 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3786 temp = expand_copysign_absneg (mode, op0, op1, target,
3787 fmt->signbit_ro, op0_is_abs);
3788 if (temp)
3789 return temp;
3792 if (fmt->signbit_rw < 0)
3793 return NULL_RTX;
3794 return expand_copysign_bit (mode, op0, op1, target,
3795 fmt->signbit_rw, op0_is_abs);
3798 /* Generate an instruction whose insn-code is INSN_CODE,
3799 with two operands: an output TARGET and an input OP0.
3800 TARGET *must* be nonzero, and the output is always stored there.
3801 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3802 the value that is stored into TARGET.
3804 Return false if expansion failed. */
3806 bool
3807 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3808 enum rtx_code code)
3810 struct expand_operand ops[2];
3811 rtx pat;
3813 create_output_operand (&ops[0], target, GET_MODE (target));
3814 create_input_operand (&ops[1], op0, GET_MODE (op0));
3815 pat = maybe_gen_insn (icode, 2, ops);
3816 if (!pat)
3817 return false;
3819 if (INSN_P (pat) && NEXT_INSN (as_a <rtx_insn *> (pat)) != NULL_RTX
3820 && code != UNKNOWN)
3821 add_equal_note (as_a <rtx_insn *> (pat), ops[0].value, code, ops[1].value,
3822 NULL_RTX);
3824 emit_insn (pat);
3826 if (ops[0].value != target)
3827 emit_move_insn (target, ops[0].value);
3828 return true;
3830 /* Generate an instruction whose insn-code is INSN_CODE,
3831 with two operands: an output TARGET and an input OP0.
3832 TARGET *must* be nonzero, and the output is always stored there.
3833 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3834 the value that is stored into TARGET. */
3836 void
3837 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3839 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3840 gcc_assert (ok);
3843 struct no_conflict_data
3845 rtx target;
3846 rtx_insn *first, *insn;
3847 bool must_stay;
3850 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3851 the currently examined clobber / store has to stay in the list of
3852 insns that constitute the actual libcall block. */
3853 static void
3854 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3856 struct no_conflict_data *p= (struct no_conflict_data *) p0;
3858 /* If this inns directly contributes to setting the target, it must stay. */
3859 if (reg_overlap_mentioned_p (p->target, dest))
3860 p->must_stay = true;
3861 /* If we haven't committed to keeping any other insns in the list yet,
3862 there is nothing more to check. */
3863 else if (p->insn == p->first)
3864 return;
3865 /* If this insn sets / clobbers a register that feeds one of the insns
3866 already in the list, this insn has to stay too. */
3867 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3868 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3869 || reg_used_between_p (dest, p->first, p->insn)
3870 /* Likewise if this insn depends on a register set by a previous
3871 insn in the list, or if it sets a result (presumably a hard
3872 register) that is set or clobbered by a previous insn.
3873 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3874 SET_DEST perform the former check on the address, and the latter
3875 check on the MEM. */
3876 || (GET_CODE (set) == SET
3877 && (modified_in_p (SET_SRC (set), p->first)
3878 || modified_in_p (SET_DEST (set), p->first)
3879 || modified_between_p (SET_SRC (set), p->first, p->insn)
3880 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3881 p->must_stay = true;
3885 /* Emit code to make a call to a constant function or a library call.
3887 INSNS is a list containing all insns emitted in the call.
3888 These insns leave the result in RESULT. Our block is to copy RESULT
3889 to TARGET, which is logically equivalent to EQUIV.
3891 We first emit any insns that set a pseudo on the assumption that these are
3892 loading constants into registers; doing so allows them to be safely cse'ed
3893 between blocks. Then we emit all the other insns in the block, followed by
3894 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3895 note with an operand of EQUIV. */
3897 static void
3898 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
3899 bool equiv_may_trap)
3901 rtx final_dest = target;
3902 rtx_insn *next, *last, *insn;
3904 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3905 into a MEM later. Protect the libcall block from this change. */
3906 if (! REG_P (target) || REG_USERVAR_P (target))
3907 target = gen_reg_rtx (GET_MODE (target));
3909 /* If we're using non-call exceptions, a libcall corresponding to an
3910 operation that may trap may also trap. */
3911 /* ??? See the comment in front of make_reg_eh_region_note. */
3912 if (cfun->can_throw_non_call_exceptions
3913 && (equiv_may_trap || may_trap_p (equiv)))
3915 for (insn = insns; insn; insn = NEXT_INSN (insn))
3916 if (CALL_P (insn))
3918 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3919 if (note)
3921 int lp_nr = INTVAL (XEXP (note, 0));
3922 if (lp_nr == 0 || lp_nr == INT_MIN)
3923 remove_note (insn, note);
3927 else
3929 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3930 reg note to indicate that this call cannot throw or execute a nonlocal
3931 goto (unless there is already a REG_EH_REGION note, in which case
3932 we update it). */
3933 for (insn = insns; insn; insn = NEXT_INSN (insn))
3934 if (CALL_P (insn))
3935 make_reg_eh_region_note_nothrow_nononlocal (insn);
3938 /* First emit all insns that set pseudos. Remove them from the list as
3939 we go. Avoid insns that set pseudos which were referenced in previous
3940 insns. These can be generated by move_by_pieces, for example,
3941 to update an address. Similarly, avoid insns that reference things
3942 set in previous insns. */
3944 for (insn = insns; insn; insn = next)
3946 rtx set = single_set (insn);
3948 next = NEXT_INSN (insn);
3950 if (set != 0 && REG_P (SET_DEST (set))
3951 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3953 struct no_conflict_data data;
3955 data.target = const0_rtx;
3956 data.first = insns;
3957 data.insn = insn;
3958 data.must_stay = 0;
3959 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3960 if (! data.must_stay)
3962 if (PREV_INSN (insn))
3963 SET_NEXT_INSN (PREV_INSN (insn)) = next;
3964 else
3965 insns = next;
3967 if (next)
3968 SET_PREV_INSN (next) = PREV_INSN (insn);
3970 add_insn (insn);
3974 /* Some ports use a loop to copy large arguments onto the stack.
3975 Don't move anything outside such a loop. */
3976 if (LABEL_P (insn))
3977 break;
3980 /* Write the remaining insns followed by the final copy. */
3981 for (insn = insns; insn; insn = next)
3983 next = NEXT_INSN (insn);
3985 add_insn (insn);
3988 last = emit_move_insn (target, result);
3989 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
3991 if (final_dest != target)
3992 emit_move_insn (final_dest, target);
3995 void
3996 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3998 emit_libcall_block_1 (safe_as_a <rtx_insn *> (insns),
3999 target, result, equiv, false);
4002 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
4003 PURPOSE describes how this comparison will be used. CODE is the rtx
4004 comparison code we will be using.
4006 ??? Actually, CODE is slightly weaker than that. A target is still
4007 required to implement all of the normal bcc operations, but not
4008 required to implement all (or any) of the unordered bcc operations. */
4011 can_compare_p (enum rtx_code code, machine_mode mode,
4012 enum can_compare_purpose purpose)
4014 rtx test;
4015 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
4018 enum insn_code icode;
4020 if (purpose == ccp_jump
4021 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
4022 && insn_operand_matches (icode, 0, test))
4023 return 1;
4024 if (purpose == ccp_store_flag
4025 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
4026 && insn_operand_matches (icode, 1, test))
4027 return 1;
4028 if (purpose == ccp_cmov
4029 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
4030 return 1;
4032 mode = GET_MODE_WIDER_MODE (mode);
4033 PUT_MODE (test, mode);
4035 while (mode != VOIDmode);
4037 return 0;
4040 /* This function is called when we are going to emit a compare instruction that
4041 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
4043 *PMODE is the mode of the inputs (in case they are const_int).
4044 *PUNSIGNEDP nonzero says that the operands are unsigned;
4045 this matters if they need to be widened (as given by METHODS).
4047 If they have mode BLKmode, then SIZE specifies the size of both operands.
4049 This function performs all the setup necessary so that the caller only has
4050 to emit a single comparison insn. This setup can involve doing a BLKmode
4051 comparison or emitting a library call to perform the comparison if no insn
4052 is available to handle it.
4053 The values which are passed in through pointers can be modified; the caller
4054 should perform the comparison on the modified values. Constant
4055 comparisons must have already been folded. */
4057 static void
4058 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4059 int unsignedp, enum optab_methods methods,
4060 rtx *ptest, machine_mode *pmode)
4062 machine_mode mode = *pmode;
4063 rtx libfunc, test;
4064 machine_mode cmp_mode;
4065 enum mode_class mclass;
4067 /* The other methods are not needed. */
4068 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
4069 || methods == OPTAB_LIB_WIDEN);
4071 /* If we are optimizing, force expensive constants into a register. */
4072 if (CONSTANT_P (x) && optimize
4073 && (rtx_cost (x, COMPARE, 0, optimize_insn_for_speed_p ())
4074 > COSTS_N_INSNS (1)))
4075 x = force_reg (mode, x);
4077 if (CONSTANT_P (y) && optimize
4078 && (rtx_cost (y, COMPARE, 1, optimize_insn_for_speed_p ())
4079 > COSTS_N_INSNS (1)))
4080 y = force_reg (mode, y);
4082 #ifdef HAVE_cc0
4083 /* Make sure if we have a canonical comparison. The RTL
4084 documentation states that canonical comparisons are required only
4085 for targets which have cc0. */
4086 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
4087 #endif
4089 /* Don't let both operands fail to indicate the mode. */
4090 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
4091 x = force_reg (mode, x);
4092 if (mode == VOIDmode)
4093 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
4095 /* Handle all BLKmode compares. */
4097 if (mode == BLKmode)
4099 machine_mode result_mode;
4100 enum insn_code cmp_code;
4101 tree length_type;
4102 rtx libfunc;
4103 rtx result;
4104 rtx opalign
4105 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
4107 gcc_assert (size);
4109 /* Try to use a memory block compare insn - either cmpstr
4110 or cmpmem will do. */
4111 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
4112 cmp_mode != VOIDmode;
4113 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
4115 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
4116 if (cmp_code == CODE_FOR_nothing)
4117 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
4118 if (cmp_code == CODE_FOR_nothing)
4119 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
4120 if (cmp_code == CODE_FOR_nothing)
4121 continue;
4123 /* Must make sure the size fits the insn's mode. */
4124 if ((CONST_INT_P (size)
4125 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
4126 || (GET_MODE_BITSIZE (GET_MODE (size))
4127 > GET_MODE_BITSIZE (cmp_mode)))
4128 continue;
4130 result_mode = insn_data[cmp_code].operand[0].mode;
4131 result = gen_reg_rtx (result_mode);
4132 size = convert_to_mode (cmp_mode, size, 1);
4133 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
4135 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
4136 *pmode = result_mode;
4137 return;
4140 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
4141 goto fail;
4143 /* Otherwise call a library function, memcmp. */
4144 libfunc = memcmp_libfunc;
4145 length_type = sizetype;
4146 result_mode = TYPE_MODE (integer_type_node);
4147 cmp_mode = TYPE_MODE (length_type);
4148 size = convert_to_mode (TYPE_MODE (length_type), size,
4149 TYPE_UNSIGNED (length_type));
4151 result = emit_library_call_value (libfunc, 0, LCT_PURE,
4152 result_mode, 3,
4153 XEXP (x, 0), Pmode,
4154 XEXP (y, 0), Pmode,
4155 size, cmp_mode);
4156 x = result;
4157 y = const0_rtx;
4158 mode = result_mode;
4159 methods = OPTAB_LIB_WIDEN;
4160 unsignedp = false;
4163 /* Don't allow operands to the compare to trap, as that can put the
4164 compare and branch in different basic blocks. */
4165 if (cfun->can_throw_non_call_exceptions)
4167 if (may_trap_p (x))
4168 x = force_reg (mode, x);
4169 if (may_trap_p (y))
4170 y = force_reg (mode, y);
4173 if (GET_MODE_CLASS (mode) == MODE_CC)
4175 enum insn_code icode = optab_handler (cbranch_optab, CCmode);
4176 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4177 gcc_assert (icode != CODE_FOR_nothing
4178 && insn_operand_matches (icode, 0, test));
4179 *ptest = test;
4180 return;
4183 mclass = GET_MODE_CLASS (mode);
4184 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4185 cmp_mode = mode;
4188 enum insn_code icode;
4189 icode = optab_handler (cbranch_optab, cmp_mode);
4190 if (icode != CODE_FOR_nothing
4191 && insn_operand_matches (icode, 0, test))
4193 rtx_insn *last = get_last_insn ();
4194 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
4195 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
4196 if (op0 && op1
4197 && insn_operand_matches (icode, 1, op0)
4198 && insn_operand_matches (icode, 2, op1))
4200 XEXP (test, 0) = op0;
4201 XEXP (test, 1) = op1;
4202 *ptest = test;
4203 *pmode = cmp_mode;
4204 return;
4206 delete_insns_since (last);
4209 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
4210 break;
4211 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode);
4213 while (cmp_mode != VOIDmode);
4215 if (methods != OPTAB_LIB_WIDEN)
4216 goto fail;
4218 if (!SCALAR_FLOAT_MODE_P (mode))
4220 rtx result;
4221 machine_mode ret_mode;
4223 /* Handle a libcall just for the mode we are using. */
4224 libfunc = optab_libfunc (cmp_optab, mode);
4225 gcc_assert (libfunc);
4227 /* If we want unsigned, and this mode has a distinct unsigned
4228 comparison routine, use that. */
4229 if (unsignedp)
4231 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
4232 if (ulibfunc)
4233 libfunc = ulibfunc;
4236 ret_mode = targetm.libgcc_cmp_return_mode ();
4237 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4238 ret_mode, 2, x, mode, y, mode);
4240 /* There are two kinds of comparison routines. Biased routines
4241 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4242 of gcc expect that the comparison operation is equivalent
4243 to the modified comparison. For signed comparisons compare the
4244 result against 1 in the biased case, and zero in the unbiased
4245 case. For unsigned comparisons always compare against 1 after
4246 biasing the unbiased result by adding 1. This gives us a way to
4247 represent LTU.
4248 The comparisons in the fixed-point helper library are always
4249 biased. */
4250 x = result;
4251 y = const1_rtx;
4253 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
4255 if (unsignedp)
4256 x = plus_constant (ret_mode, result, 1);
4257 else
4258 y = const0_rtx;
4261 *pmode = ret_mode;
4262 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
4263 ptest, pmode);
4265 else
4266 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
4268 return;
4270 fail:
4271 *ptest = NULL_RTX;
4274 /* Before emitting an insn with code ICODE, make sure that X, which is going
4275 to be used for operand OPNUM of the insn, is converted from mode MODE to
4276 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4277 that it is accepted by the operand predicate. Return the new value. */
4280 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
4281 machine_mode wider_mode, int unsignedp)
4283 if (mode != wider_mode)
4284 x = convert_modes (wider_mode, mode, x, unsignedp);
4286 if (!insn_operand_matches (icode, opnum, x))
4288 machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
4289 if (reload_completed)
4290 return NULL_RTX;
4291 if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
4292 return NULL_RTX;
4293 x = copy_to_mode_reg (op_mode, x);
4296 return x;
4299 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4300 we can do the branch. */
4302 static void
4303 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, int prob)
4305 machine_mode optab_mode;
4306 enum mode_class mclass;
4307 enum insn_code icode;
4308 rtx_insn *insn;
4310 mclass = GET_MODE_CLASS (mode);
4311 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
4312 icode = optab_handler (cbranch_optab, optab_mode);
4314 gcc_assert (icode != CODE_FOR_nothing);
4315 gcc_assert (insn_operand_matches (icode, 0, test));
4316 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
4317 XEXP (test, 1), label));
4318 if (prob != -1
4319 && profile_status_for_fn (cfun) != PROFILE_ABSENT
4320 && insn
4321 && JUMP_P (insn)
4322 && any_condjump_p (insn)
4323 && !find_reg_note (insn, REG_BR_PROB, 0))
4324 add_int_reg_note (insn, REG_BR_PROB, prob);
4327 /* Generate code to compare X with Y so that the condition codes are
4328 set and to jump to LABEL if the condition is true. If X is a
4329 constant and Y is not a constant, then the comparison is swapped to
4330 ensure that the comparison RTL has the canonical form.
4332 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4333 need to be widened. UNSIGNEDP is also used to select the proper
4334 branch condition code.
4336 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4338 MODE is the mode of the inputs (in case they are const_int).
4340 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4341 It will be potentially converted into an unsigned variant based on
4342 UNSIGNEDP to select a proper jump instruction.
4344 PROB is the probability of jumping to LABEL. */
4346 void
4347 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4348 machine_mode mode, int unsignedp, rtx label,
4349 int prob)
4351 rtx op0 = x, op1 = y;
4352 rtx test;
4354 /* Swap operands and condition to ensure canonical RTL. */
4355 if (swap_commutative_operands_p (x, y)
4356 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4358 op0 = y, op1 = x;
4359 comparison = swap_condition (comparison);
4362 /* If OP0 is still a constant, then both X and Y must be constants
4363 or the opposite comparison is not supported. Force X into a register
4364 to create canonical RTL. */
4365 if (CONSTANT_P (op0))
4366 op0 = force_reg (mode, op0);
4368 if (unsignedp)
4369 comparison = unsigned_condition (comparison);
4371 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4372 &test, &mode);
4373 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
4377 /* Emit a library call comparison between floating point X and Y.
4378 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4380 static void
4381 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4382 rtx *ptest, machine_mode *pmode)
4384 enum rtx_code swapped = swap_condition (comparison);
4385 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4386 machine_mode orig_mode = GET_MODE (x);
4387 machine_mode mode, cmp_mode;
4388 rtx true_rtx, false_rtx;
4389 rtx value, target, equiv;
4390 rtx_insn *insns;
4391 rtx libfunc = 0;
4392 bool reversed_p = false;
4393 cmp_mode = targetm.libgcc_cmp_return_mode ();
4395 for (mode = orig_mode;
4396 mode != VOIDmode;
4397 mode = GET_MODE_WIDER_MODE (mode))
4399 if (code_to_optab (comparison)
4400 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
4401 break;
4403 if (code_to_optab (swapped)
4404 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
4406 rtx tmp;
4407 tmp = x; x = y; y = tmp;
4408 comparison = swapped;
4409 break;
4412 if (code_to_optab (reversed)
4413 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4415 comparison = reversed;
4416 reversed_p = true;
4417 break;
4421 gcc_assert (mode != VOIDmode);
4423 if (mode != orig_mode)
4425 x = convert_to_mode (mode, x, 0);
4426 y = convert_to_mode (mode, y, 0);
4429 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4430 the RTL. The allows the RTL optimizers to delete the libcall if the
4431 condition can be determined at compile-time. */
4432 if (comparison == UNORDERED
4433 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4435 true_rtx = const_true_rtx;
4436 false_rtx = const0_rtx;
4438 else
4440 switch (comparison)
4442 case EQ:
4443 true_rtx = const0_rtx;
4444 false_rtx = const_true_rtx;
4445 break;
4447 case NE:
4448 true_rtx = const_true_rtx;
4449 false_rtx = const0_rtx;
4450 break;
4452 case GT:
4453 true_rtx = const1_rtx;
4454 false_rtx = const0_rtx;
4455 break;
4457 case GE:
4458 true_rtx = const0_rtx;
4459 false_rtx = constm1_rtx;
4460 break;
4462 case LT:
4463 true_rtx = constm1_rtx;
4464 false_rtx = const0_rtx;
4465 break;
4467 case LE:
4468 true_rtx = const0_rtx;
4469 false_rtx = const1_rtx;
4470 break;
4472 default:
4473 gcc_unreachable ();
4477 if (comparison == UNORDERED)
4479 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4480 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4481 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4482 temp, const_true_rtx, equiv);
4484 else
4486 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4487 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4488 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4489 equiv, true_rtx, false_rtx);
4492 start_sequence ();
4493 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4494 cmp_mode, 2, x, mode, y, mode);
4495 insns = get_insns ();
4496 end_sequence ();
4498 target = gen_reg_rtx (cmp_mode);
4499 emit_libcall_block (insns, target, value, equiv);
4501 if (comparison == UNORDERED
4502 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4503 || reversed_p)
4504 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4505 else
4506 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4508 *pmode = cmp_mode;
4511 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4513 void
4514 emit_indirect_jump (rtx loc ATTRIBUTE_UNUSED)
4516 #ifndef HAVE_indirect_jump
4517 sorry ("indirect jumps are not available on this target");
4518 #else
4519 struct expand_operand ops[1];
4520 create_address_operand (&ops[0], loc);
4521 expand_jump_insn (CODE_FOR_indirect_jump, 1, ops);
4522 emit_barrier ();
4523 #endif
4526 #ifdef HAVE_conditional_move
4528 /* Emit a conditional move instruction if the machine supports one for that
4529 condition and machine mode.
4531 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4532 the mode to use should they be constants. If it is VOIDmode, they cannot
4533 both be constants.
4535 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4536 should be stored there. MODE is the mode to use should they be constants.
4537 If it is VOIDmode, they cannot both be constants.
4539 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4540 is not supported. */
4543 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4544 machine_mode cmode, rtx op2, rtx op3,
4545 machine_mode mode, int unsignedp)
4547 rtx tem, comparison;
4548 rtx_insn *last;
4549 enum insn_code icode;
4550 enum rtx_code reversed;
4552 /* If one operand is constant, make it the second one. Only do this
4553 if the other operand is not constant as well. */
4555 if (swap_commutative_operands_p (op0, op1))
4557 tem = op0;
4558 op0 = op1;
4559 op1 = tem;
4560 code = swap_condition (code);
4563 /* get_condition will prefer to generate LT and GT even if the old
4564 comparison was against zero, so undo that canonicalization here since
4565 comparisons against zero are cheaper. */
4566 if (code == LT && op1 == const1_rtx)
4567 code = LE, op1 = const0_rtx;
4568 else if (code == GT && op1 == constm1_rtx)
4569 code = GE, op1 = const0_rtx;
4571 if (cmode == VOIDmode)
4572 cmode = GET_MODE (op0);
4574 if (swap_commutative_operands_p (op2, op3)
4575 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4576 != UNKNOWN))
4578 tem = op2;
4579 op2 = op3;
4580 op3 = tem;
4581 code = reversed;
4584 if (mode == VOIDmode)
4585 mode = GET_MODE (op2);
4587 icode = direct_optab_handler (movcc_optab, mode);
4589 if (icode == CODE_FOR_nothing)
4590 return 0;
4592 if (!target)
4593 target = gen_reg_rtx (mode);
4595 code = unsignedp ? unsigned_condition (code) : code;
4596 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4598 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4599 return NULL and let the caller figure out how best to deal with this
4600 situation. */
4601 if (!COMPARISON_P (comparison))
4602 return NULL_RTX;
4604 saved_pending_stack_adjust save;
4605 save_pending_stack_adjust (&save);
4606 last = get_last_insn ();
4607 do_pending_stack_adjust ();
4608 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4609 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4610 &comparison, &cmode);
4611 if (comparison)
4613 struct expand_operand ops[4];
4615 create_output_operand (&ops[0], target, mode);
4616 create_fixed_operand (&ops[1], comparison);
4617 create_input_operand (&ops[2], op2, mode);
4618 create_input_operand (&ops[3], op3, mode);
4619 if (maybe_expand_insn (icode, 4, ops))
4621 if (ops[0].value != target)
4622 convert_move (target, ops[0].value, false);
4623 return target;
4626 delete_insns_since (last);
4627 restore_pending_stack_adjust (&save);
4628 return NULL_RTX;
4631 /* Return nonzero if a conditional move of mode MODE is supported.
4633 This function is for combine so it can tell whether an insn that looks
4634 like a conditional move is actually supported by the hardware. If we
4635 guess wrong we lose a bit on optimization, but that's it. */
4636 /* ??? sparc64 supports conditionally moving integers values based on fp
4637 comparisons, and vice versa. How do we handle them? */
4640 can_conditionally_move_p (machine_mode mode)
4642 if (direct_optab_handler (movcc_optab, mode) != CODE_FOR_nothing)
4643 return 1;
4645 return 0;
4648 #endif /* HAVE_conditional_move */
4650 /* Emit a conditional addition instruction if the machine supports one for that
4651 condition and machine mode.
4653 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4654 the mode to use should they be constants. If it is VOIDmode, they cannot
4655 both be constants.
4657 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4658 should be stored there. MODE is the mode to use should they be constants.
4659 If it is VOIDmode, they cannot both be constants.
4661 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4662 is not supported. */
4665 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4666 machine_mode cmode, rtx op2, rtx op3,
4667 machine_mode mode, int unsignedp)
4669 rtx tem, comparison;
4670 rtx_insn *last;
4671 enum insn_code icode;
4673 /* If one operand is constant, make it the second one. Only do this
4674 if the other operand is not constant as well. */
4676 if (swap_commutative_operands_p (op0, op1))
4678 tem = op0;
4679 op0 = op1;
4680 op1 = tem;
4681 code = swap_condition (code);
4684 /* get_condition will prefer to generate LT and GT even if the old
4685 comparison was against zero, so undo that canonicalization here since
4686 comparisons against zero are cheaper. */
4687 if (code == LT && op1 == const1_rtx)
4688 code = LE, op1 = const0_rtx;
4689 else if (code == GT && op1 == constm1_rtx)
4690 code = GE, op1 = const0_rtx;
4692 if (cmode == VOIDmode)
4693 cmode = GET_MODE (op0);
4695 if (mode == VOIDmode)
4696 mode = GET_MODE (op2);
4698 icode = optab_handler (addcc_optab, mode);
4700 if (icode == CODE_FOR_nothing)
4701 return 0;
4703 if (!target)
4704 target = gen_reg_rtx (mode);
4706 code = unsignedp ? unsigned_condition (code) : code;
4707 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4709 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4710 return NULL and let the caller figure out how best to deal with this
4711 situation. */
4712 if (!COMPARISON_P (comparison))
4713 return NULL_RTX;
4715 do_pending_stack_adjust ();
4716 last = get_last_insn ();
4717 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4718 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4719 &comparison, &cmode);
4720 if (comparison)
4722 struct expand_operand ops[4];
4724 create_output_operand (&ops[0], target, mode);
4725 create_fixed_operand (&ops[1], comparison);
4726 create_input_operand (&ops[2], op2, mode);
4727 create_input_operand (&ops[3], op3, mode);
4728 if (maybe_expand_insn (icode, 4, ops))
4730 if (ops[0].value != target)
4731 convert_move (target, ops[0].value, false);
4732 return target;
4735 delete_insns_since (last);
4736 return NULL_RTX;
4739 /* These functions attempt to generate an insn body, rather than
4740 emitting the insn, but if the gen function already emits them, we
4741 make no attempt to turn them back into naked patterns. */
4743 /* Generate and return an insn body to add Y to X. */
4746 gen_add2_insn (rtx x, rtx y)
4748 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
4750 gcc_assert (insn_operand_matches (icode, 0, x));
4751 gcc_assert (insn_operand_matches (icode, 1, x));
4752 gcc_assert (insn_operand_matches (icode, 2, y));
4754 return GEN_FCN (icode) (x, x, y);
4757 /* Generate and return an insn body to add r1 and c,
4758 storing the result in r0. */
4761 gen_add3_insn (rtx r0, rtx r1, rtx c)
4763 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
4765 if (icode == CODE_FOR_nothing
4766 || !insn_operand_matches (icode, 0, r0)
4767 || !insn_operand_matches (icode, 1, r1)
4768 || !insn_operand_matches (icode, 2, c))
4769 return NULL_RTX;
4771 return GEN_FCN (icode) (r0, r1, c);
4775 have_add2_insn (rtx x, rtx y)
4777 enum insn_code icode;
4779 gcc_assert (GET_MODE (x) != VOIDmode);
4781 icode = optab_handler (add_optab, GET_MODE (x));
4783 if (icode == CODE_FOR_nothing)
4784 return 0;
4786 if (!insn_operand_matches (icode, 0, x)
4787 || !insn_operand_matches (icode, 1, x)
4788 || !insn_operand_matches (icode, 2, y))
4789 return 0;
4791 return 1;
4794 /* Generate and return an insn body to add Y to X. */
4797 gen_addptr3_insn (rtx x, rtx y, rtx z)
4799 enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
4801 gcc_assert (insn_operand_matches (icode, 0, x));
4802 gcc_assert (insn_operand_matches (icode, 1, y));
4803 gcc_assert (insn_operand_matches (icode, 2, z));
4805 return GEN_FCN (icode) (x, y, z);
4808 /* Return true if the target implements an addptr pattern and X, Y,
4809 and Z are valid for the pattern predicates. */
4812 have_addptr3_insn (rtx x, rtx y, rtx z)
4814 enum insn_code icode;
4816 gcc_assert (GET_MODE (x) != VOIDmode);
4818 icode = optab_handler (addptr3_optab, GET_MODE (x));
4820 if (icode == CODE_FOR_nothing)
4821 return 0;
4823 if (!insn_operand_matches (icode, 0, x)
4824 || !insn_operand_matches (icode, 1, y)
4825 || !insn_operand_matches (icode, 2, z))
4826 return 0;
4828 return 1;
4831 /* Generate and return an insn body to subtract Y from X. */
4834 gen_sub2_insn (rtx x, rtx y)
4836 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
4838 gcc_assert (insn_operand_matches (icode, 0, x));
4839 gcc_assert (insn_operand_matches (icode, 1, x));
4840 gcc_assert (insn_operand_matches (icode, 2, y));
4842 return GEN_FCN (icode) (x, x, y);
4845 /* Generate and return an insn body to subtract r1 and c,
4846 storing the result in r0. */
4849 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4851 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
4853 if (icode == CODE_FOR_nothing
4854 || !insn_operand_matches (icode, 0, r0)
4855 || !insn_operand_matches (icode, 1, r1)
4856 || !insn_operand_matches (icode, 2, c))
4857 return NULL_RTX;
4859 return GEN_FCN (icode) (r0, r1, c);
4863 have_sub2_insn (rtx x, rtx y)
4865 enum insn_code icode;
4867 gcc_assert (GET_MODE (x) != VOIDmode);
4869 icode = optab_handler (sub_optab, GET_MODE (x));
4871 if (icode == CODE_FOR_nothing)
4872 return 0;
4874 if (!insn_operand_matches (icode, 0, x)
4875 || !insn_operand_matches (icode, 1, x)
4876 || !insn_operand_matches (icode, 2, y))
4877 return 0;
4879 return 1;
4882 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4883 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4884 no such operation exists, CODE_FOR_nothing will be returned. */
4886 enum insn_code
4887 can_extend_p (machine_mode to_mode, machine_mode from_mode,
4888 int unsignedp)
4890 convert_optab tab;
4891 #ifdef HAVE_ptr_extend
4892 if (unsignedp < 0)
4893 return CODE_FOR_ptr_extend;
4894 #endif
4896 tab = unsignedp ? zext_optab : sext_optab;
4897 return convert_optab_handler (tab, to_mode, from_mode);
4900 /* Generate the body of an insn to extend Y (with mode MFROM)
4901 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4904 gen_extend_insn (rtx x, rtx y, machine_mode mto,
4905 machine_mode mfrom, int unsignedp)
4907 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4908 return GEN_FCN (icode) (x, y);
4911 /* can_fix_p and can_float_p say whether the target machine
4912 can directly convert a given fixed point type to
4913 a given floating point type, or vice versa.
4914 The returned value is the CODE_FOR_... value to use,
4915 or CODE_FOR_nothing if these modes cannot be directly converted.
4917 *TRUNCP_PTR is set to 1 if it is necessary to output
4918 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4920 static enum insn_code
4921 can_fix_p (machine_mode fixmode, machine_mode fltmode,
4922 int unsignedp, int *truncp_ptr)
4924 convert_optab tab;
4925 enum insn_code icode;
4927 tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4928 icode = convert_optab_handler (tab, fixmode, fltmode);
4929 if (icode != CODE_FOR_nothing)
4931 *truncp_ptr = 0;
4932 return icode;
4935 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4936 for this to work. We need to rework the fix* and ftrunc* patterns
4937 and documentation. */
4938 tab = unsignedp ? ufix_optab : sfix_optab;
4939 icode = convert_optab_handler (tab, fixmode, fltmode);
4940 if (icode != CODE_FOR_nothing
4941 && optab_handler (ftrunc_optab, fltmode) != CODE_FOR_nothing)
4943 *truncp_ptr = 1;
4944 return icode;
4947 *truncp_ptr = 0;
4948 return CODE_FOR_nothing;
4951 enum insn_code
4952 can_float_p (machine_mode fltmode, machine_mode fixmode,
4953 int unsignedp)
4955 convert_optab tab;
4957 tab = unsignedp ? ufloat_optab : sfloat_optab;
4958 return convert_optab_handler (tab, fltmode, fixmode);
4961 /* Function supportable_convert_operation
4963 Check whether an operation represented by the code CODE is a
4964 convert operation that is supported by the target platform in
4965 vector form (i.e., when operating on arguments of type VECTYPE_IN
4966 producing a result of type VECTYPE_OUT).
4968 Convert operations we currently support directly are FIX_TRUNC and FLOAT.
4969 This function checks if these operations are supported
4970 by the target platform either directly (via vector tree-codes), or via
4971 target builtins.
4973 Output:
4974 - CODE1 is code of vector operation to be used when
4975 vectorizing the operation, if available.
4976 - DECL is decl of target builtin functions to be used
4977 when vectorizing the operation, if available. In this case,
4978 CODE1 is CALL_EXPR. */
4980 bool
4981 supportable_convert_operation (enum tree_code code,
4982 tree vectype_out, tree vectype_in,
4983 tree *decl, enum tree_code *code1)
4985 machine_mode m1,m2;
4986 int truncp;
4988 m1 = TYPE_MODE (vectype_out);
4989 m2 = TYPE_MODE (vectype_in);
4991 /* First check if we can done conversion directly. */
4992 if ((code == FIX_TRUNC_EXPR
4993 && can_fix_p (m1,m2,TYPE_UNSIGNED (vectype_out), &truncp)
4994 != CODE_FOR_nothing)
4995 || (code == FLOAT_EXPR
4996 && can_float_p (m1,m2,TYPE_UNSIGNED (vectype_in))
4997 != CODE_FOR_nothing))
4999 *code1 = code;
5000 return true;
5003 /* Now check for builtin. */
5004 if (targetm.vectorize.builtin_conversion
5005 && targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in))
5007 *code1 = CALL_EXPR;
5008 *decl = targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in);
5009 return true;
5011 return false;
5015 /* Generate code to convert FROM to floating point
5016 and store in TO. FROM must be fixed point and not VOIDmode.
5017 UNSIGNEDP nonzero means regard FROM as unsigned.
5018 Normally this is done by correcting the final value
5019 if it is negative. */
5021 void
5022 expand_float (rtx to, rtx from, int unsignedp)
5024 enum insn_code icode;
5025 rtx target = to;
5026 machine_mode fmode, imode;
5027 bool can_do_signed = false;
5029 /* Crash now, because we won't be able to decide which mode to use. */
5030 gcc_assert (GET_MODE (from) != VOIDmode);
5032 /* Look for an insn to do the conversion. Do it in the specified
5033 modes if possible; otherwise convert either input, output or both to
5034 wider mode. If the integer mode is wider than the mode of FROM,
5035 we can do the conversion signed even if the input is unsigned. */
5037 for (fmode = GET_MODE (to); fmode != VOIDmode;
5038 fmode = GET_MODE_WIDER_MODE (fmode))
5039 for (imode = GET_MODE (from); imode != VOIDmode;
5040 imode = GET_MODE_WIDER_MODE (imode))
5042 int doing_unsigned = unsignedp;
5044 if (fmode != GET_MODE (to)
5045 && significand_size (fmode) < GET_MODE_PRECISION (GET_MODE (from)))
5046 continue;
5048 icode = can_float_p (fmode, imode, unsignedp);
5049 if (icode == CODE_FOR_nothing && unsignedp)
5051 enum insn_code scode = can_float_p (fmode, imode, 0);
5052 if (scode != CODE_FOR_nothing)
5053 can_do_signed = true;
5054 if (imode != GET_MODE (from))
5055 icode = scode, doing_unsigned = 0;
5058 if (icode != CODE_FOR_nothing)
5060 if (imode != GET_MODE (from))
5061 from = convert_to_mode (imode, from, unsignedp);
5063 if (fmode != GET_MODE (to))
5064 target = gen_reg_rtx (fmode);
5066 emit_unop_insn (icode, target, from,
5067 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
5069 if (target != to)
5070 convert_move (to, target, 0);
5071 return;
5075 /* Unsigned integer, and no way to convert directly. Convert as signed,
5076 then unconditionally adjust the result. */
5077 if (unsignedp && can_do_signed)
5079 rtx_code_label *label = gen_label_rtx ();
5080 rtx temp;
5081 REAL_VALUE_TYPE offset;
5083 /* Look for a usable floating mode FMODE wider than the source and at
5084 least as wide as the target. Using FMODE will avoid rounding woes
5085 with unsigned values greater than the signed maximum value. */
5087 for (fmode = GET_MODE (to); fmode != VOIDmode;
5088 fmode = GET_MODE_WIDER_MODE (fmode))
5089 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
5090 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
5091 break;
5093 if (fmode == VOIDmode)
5095 /* There is no such mode. Pretend the target is wide enough. */
5096 fmode = GET_MODE (to);
5098 /* Avoid double-rounding when TO is narrower than FROM. */
5099 if ((significand_size (fmode) + 1)
5100 < GET_MODE_PRECISION (GET_MODE (from)))
5102 rtx temp1;
5103 rtx_code_label *neglabel = gen_label_rtx ();
5105 /* Don't use TARGET if it isn't a register, is a hard register,
5106 or is the wrong mode. */
5107 if (!REG_P (target)
5108 || REGNO (target) < FIRST_PSEUDO_REGISTER
5109 || GET_MODE (target) != fmode)
5110 target = gen_reg_rtx (fmode);
5112 imode = GET_MODE (from);
5113 do_pending_stack_adjust ();
5115 /* Test whether the sign bit is set. */
5116 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
5117 0, neglabel);
5119 /* The sign bit is not set. Convert as signed. */
5120 expand_float (target, from, 0);
5121 emit_jump_insn (gen_jump (label));
5122 emit_barrier ();
5124 /* The sign bit is set.
5125 Convert to a usable (positive signed) value by shifting right
5126 one bit, while remembering if a nonzero bit was shifted
5127 out; i.e., compute (from & 1) | (from >> 1). */
5129 emit_label (neglabel);
5130 temp = expand_binop (imode, and_optab, from, const1_rtx,
5131 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5132 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
5133 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
5134 OPTAB_LIB_WIDEN);
5135 expand_float (target, temp, 0);
5137 /* Multiply by 2 to undo the shift above. */
5138 temp = expand_binop (fmode, add_optab, target, target,
5139 target, 0, OPTAB_LIB_WIDEN);
5140 if (temp != target)
5141 emit_move_insn (target, temp);
5143 do_pending_stack_adjust ();
5144 emit_label (label);
5145 goto done;
5149 /* If we are about to do some arithmetic to correct for an
5150 unsigned operand, do it in a pseudo-register. */
5152 if (GET_MODE (to) != fmode
5153 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
5154 target = gen_reg_rtx (fmode);
5156 /* Convert as signed integer to floating. */
5157 expand_float (target, from, 0);
5159 /* If FROM is negative (and therefore TO is negative),
5160 correct its value by 2**bitwidth. */
5162 do_pending_stack_adjust ();
5163 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
5164 0, label);
5167 real_2expN (&offset, GET_MODE_PRECISION (GET_MODE (from)), fmode);
5168 temp = expand_binop (fmode, add_optab, target,
5169 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
5170 target, 0, OPTAB_LIB_WIDEN);
5171 if (temp != target)
5172 emit_move_insn (target, temp);
5174 do_pending_stack_adjust ();
5175 emit_label (label);
5176 goto done;
5179 /* No hardware instruction available; call a library routine. */
5181 rtx libfunc;
5182 rtx_insn *insns;
5183 rtx value;
5184 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
5186 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_PRECISION (SImode))
5187 from = convert_to_mode (SImode, from, unsignedp);
5189 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5190 gcc_assert (libfunc);
5192 start_sequence ();
5194 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5195 GET_MODE (to), 1, from,
5196 GET_MODE (from));
5197 insns = get_insns ();
5198 end_sequence ();
5200 emit_libcall_block (insns, target, value,
5201 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
5202 GET_MODE (to), from));
5205 done:
5207 /* Copy result to requested destination
5208 if we have been computing in a temp location. */
5210 if (target != to)
5212 if (GET_MODE (target) == GET_MODE (to))
5213 emit_move_insn (to, target);
5214 else
5215 convert_move (to, target, 0);
5219 /* Generate code to convert FROM to fixed point and store in TO. FROM
5220 must be floating point. */
5222 void
5223 expand_fix (rtx to, rtx from, int unsignedp)
5225 enum insn_code icode;
5226 rtx target = to;
5227 machine_mode fmode, imode;
5228 int must_trunc = 0;
5230 /* We first try to find a pair of modes, one real and one integer, at
5231 least as wide as FROM and TO, respectively, in which we can open-code
5232 this conversion. If the integer mode is wider than the mode of TO,
5233 we can do the conversion either signed or unsigned. */
5235 for (fmode = GET_MODE (from); fmode != VOIDmode;
5236 fmode = GET_MODE_WIDER_MODE (fmode))
5237 for (imode = GET_MODE (to); imode != VOIDmode;
5238 imode = GET_MODE_WIDER_MODE (imode))
5240 int doing_unsigned = unsignedp;
5242 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5243 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5244 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5246 if (icode != CODE_FOR_nothing)
5248 rtx_insn *last = get_last_insn ();
5249 if (fmode != GET_MODE (from))
5250 from = convert_to_mode (fmode, from, 0);
5252 if (must_trunc)
5254 rtx temp = gen_reg_rtx (GET_MODE (from));
5255 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
5256 temp, 0);
5259 if (imode != GET_MODE (to))
5260 target = gen_reg_rtx (imode);
5262 if (maybe_emit_unop_insn (icode, target, from,
5263 doing_unsigned ? UNSIGNED_FIX : FIX))
5265 if (target != to)
5266 convert_move (to, target, unsignedp);
5267 return;
5269 delete_insns_since (last);
5273 /* For an unsigned conversion, there is one more way to do it.
5274 If we have a signed conversion, we generate code that compares
5275 the real value to the largest representable positive number. If if
5276 is smaller, the conversion is done normally. Otherwise, subtract
5277 one plus the highest signed number, convert, and add it back.
5279 We only need to check all real modes, since we know we didn't find
5280 anything with a wider integer mode.
5282 This code used to extend FP value into mode wider than the destination.
5283 This is needed for decimal float modes which cannot accurately
5284 represent one plus the highest signed number of the same size, but
5285 not for binary modes. Consider, for instance conversion from SFmode
5286 into DImode.
5288 The hot path through the code is dealing with inputs smaller than 2^63
5289 and doing just the conversion, so there is no bits to lose.
5291 In the other path we know the value is positive in the range 2^63..2^64-1
5292 inclusive. (as for other input overflow happens and result is undefined)
5293 So we know that the most important bit set in mantissa corresponds to
5294 2^63. The subtraction of 2^63 should not generate any rounding as it
5295 simply clears out that bit. The rest is trivial. */
5297 if (unsignedp && GET_MODE_PRECISION (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
5298 for (fmode = GET_MODE (from); fmode != VOIDmode;
5299 fmode = GET_MODE_WIDER_MODE (fmode))
5300 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
5301 && (!DECIMAL_FLOAT_MODE_P (fmode)
5302 || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (GET_MODE (to))))
5304 int bitsize;
5305 REAL_VALUE_TYPE offset;
5306 rtx limit;
5307 rtx_code_label *lab1, *lab2;
5308 rtx_insn *insn;
5310 bitsize = GET_MODE_PRECISION (GET_MODE (to));
5311 real_2expN (&offset, bitsize - 1, fmode);
5312 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
5313 lab1 = gen_label_rtx ();
5314 lab2 = gen_label_rtx ();
5316 if (fmode != GET_MODE (from))
5317 from = convert_to_mode (fmode, from, 0);
5319 /* See if we need to do the subtraction. */
5320 do_pending_stack_adjust ();
5321 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
5322 0, lab1);
5324 /* If not, do the signed "fix" and branch around fixup code. */
5325 expand_fix (to, from, 0);
5326 emit_jump_insn (gen_jump (lab2));
5327 emit_barrier ();
5329 /* Otherwise, subtract 2**(N-1), convert to signed number,
5330 then add 2**(N-1). Do the addition using XOR since this
5331 will often generate better code. */
5332 emit_label (lab1);
5333 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5334 NULL_RTX, 0, OPTAB_LIB_WIDEN);
5335 expand_fix (to, target, 0);
5336 target = expand_binop (GET_MODE (to), xor_optab, to,
5337 gen_int_mode
5338 ((HOST_WIDE_INT) 1 << (bitsize - 1),
5339 GET_MODE (to)),
5340 to, 1, OPTAB_LIB_WIDEN);
5342 if (target != to)
5343 emit_move_insn (to, target);
5345 emit_label (lab2);
5347 if (optab_handler (mov_optab, GET_MODE (to)) != CODE_FOR_nothing)
5349 /* Make a place for a REG_NOTE and add it. */
5350 insn = emit_move_insn (to, to);
5351 set_dst_reg_note (insn, REG_EQUAL,
5352 gen_rtx_fmt_e (UNSIGNED_FIX, GET_MODE (to),
5353 copy_rtx (from)),
5354 to);
5357 return;
5360 /* We can't do it with an insn, so use a library call. But first ensure
5361 that the mode of TO is at least as wide as SImode, since those are the
5362 only library calls we know about. */
5364 if (GET_MODE_PRECISION (GET_MODE (to)) < GET_MODE_PRECISION (SImode))
5366 target = gen_reg_rtx (SImode);
5368 expand_fix (target, from, unsignedp);
5370 else
5372 rtx_insn *insns;
5373 rtx value;
5374 rtx libfunc;
5376 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5377 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5378 gcc_assert (libfunc);
5380 start_sequence ();
5382 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5383 GET_MODE (to), 1, from,
5384 GET_MODE (from));
5385 insns = get_insns ();
5386 end_sequence ();
5388 emit_libcall_block (insns, target, value,
5389 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5390 GET_MODE (to), from));
5393 if (target != to)
5395 if (GET_MODE (to) == GET_MODE (target))
5396 emit_move_insn (to, target);
5397 else
5398 convert_move (to, target, 0);
5402 /* Generate code to convert FROM or TO a fixed-point.
5403 If UINTP is true, either TO or FROM is an unsigned integer.
5404 If SATP is true, we need to saturate the result. */
5406 void
5407 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5409 machine_mode to_mode = GET_MODE (to);
5410 machine_mode from_mode = GET_MODE (from);
5411 convert_optab tab;
5412 enum rtx_code this_code;
5413 enum insn_code code;
5414 rtx_insn *insns;
5415 rtx value;
5416 rtx libfunc;
5418 if (to_mode == from_mode)
5420 emit_move_insn (to, from);
5421 return;
5424 if (uintp)
5426 tab = satp ? satfractuns_optab : fractuns_optab;
5427 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5429 else
5431 tab = satp ? satfract_optab : fract_optab;
5432 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5434 code = convert_optab_handler (tab, to_mode, from_mode);
5435 if (code != CODE_FOR_nothing)
5437 emit_unop_insn (code, to, from, this_code);
5438 return;
5441 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5442 gcc_assert (libfunc);
5444 start_sequence ();
5445 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5446 1, from, from_mode);
5447 insns = get_insns ();
5448 end_sequence ();
5450 emit_libcall_block (insns, to, value,
5451 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
5454 /* Generate code to convert FROM to fixed point and store in TO. FROM
5455 must be floating point, TO must be signed. Use the conversion optab
5456 TAB to do the conversion. */
5458 bool
5459 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5461 enum insn_code icode;
5462 rtx target = to;
5463 machine_mode fmode, imode;
5465 /* We first try to find a pair of modes, one real and one integer, at
5466 least as wide as FROM and TO, respectively, in which we can open-code
5467 this conversion. If the integer mode is wider than the mode of TO,
5468 we can do the conversion either signed or unsigned. */
5470 for (fmode = GET_MODE (from); fmode != VOIDmode;
5471 fmode = GET_MODE_WIDER_MODE (fmode))
5472 for (imode = GET_MODE (to); imode != VOIDmode;
5473 imode = GET_MODE_WIDER_MODE (imode))
5475 icode = convert_optab_handler (tab, imode, fmode);
5476 if (icode != CODE_FOR_nothing)
5478 rtx_insn *last = get_last_insn ();
5479 if (fmode != GET_MODE (from))
5480 from = convert_to_mode (fmode, from, 0);
5482 if (imode != GET_MODE (to))
5483 target = gen_reg_rtx (imode);
5485 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5487 delete_insns_since (last);
5488 continue;
5490 if (target != to)
5491 convert_move (to, target, 0);
5492 return true;
5496 return false;
5499 /* Report whether we have an instruction to perform the operation
5500 specified by CODE on operands of mode MODE. */
5502 have_insn_for (enum rtx_code code, machine_mode mode)
5504 return (code_to_optab (code)
5505 && (optab_handler (code_to_optab (code), mode)
5506 != CODE_FOR_nothing));
5509 /* Initialize the libfunc fields of an entire group of entries in some
5510 optab. Each entry is set equal to a string consisting of a leading
5511 pair of underscores followed by a generic operation name followed by
5512 a mode name (downshifted to lowercase) followed by a single character
5513 representing the number of operands for the given operation (which is
5514 usually one of the characters '2', '3', or '4').
5516 OPTABLE is the table in which libfunc fields are to be initialized.
5517 OPNAME is the generic (string) name of the operation.
5518 SUFFIX is the character which specifies the number of operands for
5519 the given generic operation.
5520 MODE is the mode to generate for.
5523 static void
5524 gen_libfunc (optab optable, const char *opname, int suffix,
5525 machine_mode mode)
5527 unsigned opname_len = strlen (opname);
5528 const char *mname = GET_MODE_NAME (mode);
5529 unsigned mname_len = strlen (mname);
5530 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5531 int len = prefix_len + opname_len + mname_len + 1 + 1;
5532 char *libfunc_name = XALLOCAVEC (char, len);
5533 char *p;
5534 const char *q;
5536 p = libfunc_name;
5537 *p++ = '_';
5538 *p++ = '_';
5539 if (targetm.libfunc_gnu_prefix)
5541 *p++ = 'g';
5542 *p++ = 'n';
5543 *p++ = 'u';
5544 *p++ = '_';
5546 for (q = opname; *q; )
5547 *p++ = *q++;
5548 for (q = mname; *q; q++)
5549 *p++ = TOLOWER (*q);
5550 *p++ = suffix;
5551 *p = '\0';
5553 set_optab_libfunc (optable, mode,
5554 ggc_alloc_string (libfunc_name, p - libfunc_name));
5557 /* Like gen_libfunc, but verify that integer operation is involved. */
5559 void
5560 gen_int_libfunc (optab optable, const char *opname, char suffix,
5561 machine_mode mode)
5563 int maxsize = 2 * BITS_PER_WORD;
5564 int minsize = BITS_PER_WORD;
5566 if (GET_MODE_CLASS (mode) != MODE_INT)
5567 return;
5568 if (maxsize < LONG_LONG_TYPE_SIZE)
5569 maxsize = LONG_LONG_TYPE_SIZE;
5570 if (minsize > INT_TYPE_SIZE
5571 && (trapv_binoptab_p (optable)
5572 || trapv_unoptab_p (optable)))
5573 minsize = INT_TYPE_SIZE;
5574 if (GET_MODE_BITSIZE (mode) < minsize
5575 || GET_MODE_BITSIZE (mode) > maxsize)
5576 return;
5577 gen_libfunc (optable, opname, suffix, mode);
5580 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */
5582 void
5583 gen_fp_libfunc (optab optable, const char *opname, char suffix,
5584 machine_mode mode)
5586 char *dec_opname;
5588 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
5589 gen_libfunc (optable, opname, suffix, mode);
5590 if (DECIMAL_FLOAT_MODE_P (mode))
5592 dec_opname = XALLOCAVEC (char, sizeof (DECIMAL_PREFIX) + strlen (opname));
5593 /* For BID support, change the name to have either a bid_ or dpd_ prefix
5594 depending on the low level floating format used. */
5595 memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
5596 strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
5597 gen_libfunc (optable, dec_opname, suffix, mode);
5601 /* Like gen_libfunc, but verify that fixed-point operation is involved. */
5603 void
5604 gen_fixed_libfunc (optab optable, const char *opname, char suffix,
5605 machine_mode mode)
5607 if (!ALL_FIXED_POINT_MODE_P (mode))
5608 return;
5609 gen_libfunc (optable, opname, suffix, mode);
5612 /* Like gen_libfunc, but verify that signed fixed-point operation is
5613 involved. */
5615 void
5616 gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
5617 machine_mode mode)
5619 if (!SIGNED_FIXED_POINT_MODE_P (mode))
5620 return;
5621 gen_libfunc (optable, opname, suffix, mode);
5624 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
5625 involved. */
5627 void
5628 gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
5629 machine_mode mode)
5631 if (!UNSIGNED_FIXED_POINT_MODE_P (mode))
5632 return;
5633 gen_libfunc (optable, opname, suffix, mode);
5636 /* Like gen_libfunc, but verify that FP or INT operation is involved. */
5638 void
5639 gen_int_fp_libfunc (optab optable, const char *name, char suffix,
5640 machine_mode mode)
5642 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5643 gen_fp_libfunc (optable, name, suffix, mode);
5644 if (INTEGRAL_MODE_P (mode))
5645 gen_int_libfunc (optable, name, suffix, mode);
5648 /* Like gen_libfunc, but verify that FP or INT operation is involved
5649 and add 'v' suffix for integer operation. */
5651 void
5652 gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
5653 machine_mode mode)
5655 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5656 gen_fp_libfunc (optable, name, suffix, mode);
5657 if (GET_MODE_CLASS (mode) == MODE_INT)
5659 int len = strlen (name);
5660 char *v_name = XALLOCAVEC (char, len + 2);
5661 strcpy (v_name, name);
5662 v_name[len] = 'v';
5663 v_name[len + 1] = 0;
5664 gen_int_libfunc (optable, v_name, suffix, mode);
5668 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
5669 involved. */
5671 void
5672 gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
5673 machine_mode mode)
5675 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5676 gen_fp_libfunc (optable, name, suffix, mode);
5677 if (INTEGRAL_MODE_P (mode))
5678 gen_int_libfunc (optable, name, suffix, mode);
5679 if (ALL_FIXED_POINT_MODE_P (mode))
5680 gen_fixed_libfunc (optable, name, suffix, mode);
5683 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
5684 involved. */
5686 void
5687 gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5688 machine_mode mode)
5690 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5691 gen_fp_libfunc (optable, name, suffix, mode);
5692 if (INTEGRAL_MODE_P (mode))
5693 gen_int_libfunc (optable, name, suffix, mode);
5694 if (SIGNED_FIXED_POINT_MODE_P (mode))
5695 gen_signed_fixed_libfunc (optable, name, suffix, mode);
5698 /* Like gen_libfunc, but verify that INT or FIXED operation is
5699 involved. */
5701 void
5702 gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
5703 machine_mode mode)
5705 if (INTEGRAL_MODE_P (mode))
5706 gen_int_libfunc (optable, name, suffix, mode);
5707 if (ALL_FIXED_POINT_MODE_P (mode))
5708 gen_fixed_libfunc (optable, name, suffix, mode);
5711 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
5712 involved. */
5714 void
5715 gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5716 machine_mode mode)
5718 if (INTEGRAL_MODE_P (mode))
5719 gen_int_libfunc (optable, name, suffix, mode);
5720 if (SIGNED_FIXED_POINT_MODE_P (mode))
5721 gen_signed_fixed_libfunc (optable, name, suffix, mode);
5724 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
5725 involved. */
5727 void
5728 gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
5729 machine_mode mode)
5731 if (INTEGRAL_MODE_P (mode))
5732 gen_int_libfunc (optable, name, suffix, mode);
5733 if (UNSIGNED_FIXED_POINT_MODE_P (mode))
5734 gen_unsigned_fixed_libfunc (optable, name, suffix, mode);
5737 /* Initialize the libfunc fields of an entire group of entries of an
5738 inter-mode-class conversion optab. The string formation rules are
5739 similar to the ones for init_libfuncs, above, but instead of having
5740 a mode name and an operand count these functions have two mode names
5741 and no operand count. */
5743 void
5744 gen_interclass_conv_libfunc (convert_optab tab,
5745 const char *opname,
5746 machine_mode tmode,
5747 machine_mode fmode)
5749 size_t opname_len = strlen (opname);
5750 size_t mname_len = 0;
5752 const char *fname, *tname;
5753 const char *q;
5754 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5755 char *libfunc_name, *suffix;
5756 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5757 char *p;
5759 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5760 depends on which underlying decimal floating point format is used. */
5761 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5763 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5765 nondec_name = XALLOCAVEC (char, prefix_len + opname_len + mname_len + 1 + 1);
5766 nondec_name[0] = '_';
5767 nondec_name[1] = '_';
5768 if (targetm.libfunc_gnu_prefix)
5770 nondec_name[2] = 'g';
5771 nondec_name[3] = 'n';
5772 nondec_name[4] = 'u';
5773 nondec_name[5] = '_';
5776 memcpy (&nondec_name[prefix_len], opname, opname_len);
5777 nondec_suffix = nondec_name + opname_len + prefix_len;
5779 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
5780 dec_name[0] = '_';
5781 dec_name[1] = '_';
5782 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5783 memcpy (&dec_name[2+dec_len], opname, opname_len);
5784 dec_suffix = dec_name + dec_len + opname_len + 2;
5786 fname = GET_MODE_NAME (fmode);
5787 tname = GET_MODE_NAME (tmode);
5789 if (DECIMAL_FLOAT_MODE_P (fmode) || DECIMAL_FLOAT_MODE_P (tmode))
5791 libfunc_name = dec_name;
5792 suffix = dec_suffix;
5794 else
5796 libfunc_name = nondec_name;
5797 suffix = nondec_suffix;
5800 p = suffix;
5801 for (q = fname; *q; p++, q++)
5802 *p = TOLOWER (*q);
5803 for (q = tname; *q; p++, q++)
5804 *p = TOLOWER (*q);
5806 *p = '\0';
5808 set_conv_libfunc (tab, tmode, fmode,
5809 ggc_alloc_string (libfunc_name, p - libfunc_name));
5812 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5813 int->fp conversion. */
5815 void
5816 gen_int_to_fp_conv_libfunc (convert_optab tab,
5817 const char *opname,
5818 machine_mode tmode,
5819 machine_mode fmode)
5821 if (GET_MODE_CLASS (fmode) != MODE_INT)
5822 return;
5823 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5824 return;
5825 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5828 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
5829 naming scheme. */
5831 void
5832 gen_ufloat_conv_libfunc (convert_optab tab,
5833 const char *opname ATTRIBUTE_UNUSED,
5834 machine_mode tmode,
5835 machine_mode fmode)
5837 if (DECIMAL_FLOAT_MODE_P (tmode))
5838 gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode);
5839 else
5840 gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode);
5843 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5844 fp->int conversion. */
5846 void
5847 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
5848 const char *opname,
5849 machine_mode tmode,
5850 machine_mode fmode)
5852 if (GET_MODE_CLASS (fmode) != MODE_INT)
5853 return;
5854 if (GET_MODE_CLASS (tmode) != MODE_FLOAT)
5855 return;
5856 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5859 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5860 fp->int conversion with no decimal floating point involved. */
5862 void
5863 gen_fp_to_int_conv_libfunc (convert_optab tab,
5864 const char *opname,
5865 machine_mode tmode,
5866 machine_mode fmode)
5868 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5869 return;
5870 if (GET_MODE_CLASS (tmode) != MODE_INT)
5871 return;
5872 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5875 /* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
5876 The string formation rules are
5877 similar to the ones for init_libfunc, above. */
5879 void
5880 gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
5881 machine_mode tmode, machine_mode fmode)
5883 size_t opname_len = strlen (opname);
5884 size_t mname_len = 0;
5886 const char *fname, *tname;
5887 const char *q;
5888 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5889 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5890 char *libfunc_name, *suffix;
5891 char *p;
5893 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5894 depends on which underlying decimal floating point format is used. */
5895 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5897 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5899 nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
5900 nondec_name[0] = '_';
5901 nondec_name[1] = '_';
5902 if (targetm.libfunc_gnu_prefix)
5904 nondec_name[2] = 'g';
5905 nondec_name[3] = 'n';
5906 nondec_name[4] = 'u';
5907 nondec_name[5] = '_';
5909 memcpy (&nondec_name[prefix_len], opname, opname_len);
5910 nondec_suffix = nondec_name + opname_len + prefix_len;
5912 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
5913 dec_name[0] = '_';
5914 dec_name[1] = '_';
5915 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5916 memcpy (&dec_name[2 + dec_len], opname, opname_len);
5917 dec_suffix = dec_name + dec_len + opname_len + 2;
5919 fname = GET_MODE_NAME (fmode);
5920 tname = GET_MODE_NAME (tmode);
5922 if (DECIMAL_FLOAT_MODE_P (fmode) || DECIMAL_FLOAT_MODE_P (tmode))
5924 libfunc_name = dec_name;
5925 suffix = dec_suffix;
5927 else
5929 libfunc_name = nondec_name;
5930 suffix = nondec_suffix;
5933 p = suffix;
5934 for (q = fname; *q; p++, q++)
5935 *p = TOLOWER (*q);
5936 for (q = tname; *q; p++, q++)
5937 *p = TOLOWER (*q);
5939 *p++ = '2';
5940 *p = '\0';
5942 set_conv_libfunc (tab, tmode, fmode,
5943 ggc_alloc_string (libfunc_name, p - libfunc_name));
5946 /* Pick proper libcall for trunc_optab. We need to chose if we do
5947 truncation or extension and interclass or intraclass. */
5949 void
5950 gen_trunc_conv_libfunc (convert_optab tab,
5951 const char *opname,
5952 machine_mode tmode,
5953 machine_mode fmode)
5955 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5956 return;
5957 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5958 return;
5959 if (tmode == fmode)
5960 return;
5962 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
5963 || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
5964 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5966 if (GET_MODE_PRECISION (fmode) <= GET_MODE_PRECISION (tmode))
5967 return;
5969 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
5970 && GET_MODE_CLASS (fmode) == MODE_FLOAT)
5971 || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
5972 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5975 /* Pick proper libcall for extend_optab. We need to chose if we do
5976 truncation or extension and interclass or intraclass. */
5978 void
5979 gen_extend_conv_libfunc (convert_optab tab,
5980 const char *opname ATTRIBUTE_UNUSED,
5981 machine_mode tmode,
5982 machine_mode fmode)
5984 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5985 return;
5986 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5987 return;
5988 if (tmode == fmode)
5989 return;
5991 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
5992 || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
5993 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5995 if (GET_MODE_PRECISION (fmode) > GET_MODE_PRECISION (tmode))
5996 return;
5998 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
5999 && GET_MODE_CLASS (fmode) == MODE_FLOAT)
6000 || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
6001 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6004 /* Pick proper libcall for fract_optab. We need to chose if we do
6005 interclass or intraclass. */
6007 void
6008 gen_fract_conv_libfunc (convert_optab tab,
6009 const char *opname,
6010 machine_mode tmode,
6011 machine_mode fmode)
6013 if (tmode == fmode)
6014 return;
6015 if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode)))
6016 return;
6018 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
6019 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6020 else
6021 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6024 /* Pick proper libcall for fractuns_optab. */
6026 void
6027 gen_fractuns_conv_libfunc (convert_optab tab,
6028 const char *opname,
6029 machine_mode tmode,
6030 machine_mode fmode)
6032 if (tmode == fmode)
6033 return;
6034 /* One mode must be a fixed-point mode, and the other must be an integer
6035 mode. */
6036 if (!((ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT)
6037 || (ALL_FIXED_POINT_MODE_P (fmode)
6038 && GET_MODE_CLASS (tmode) == MODE_INT)))
6039 return;
6041 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6044 /* Pick proper libcall for satfract_optab. We need to chose if we do
6045 interclass or intraclass. */
6047 void
6048 gen_satfract_conv_libfunc (convert_optab tab,
6049 const char *opname,
6050 machine_mode tmode,
6051 machine_mode fmode)
6053 if (tmode == fmode)
6054 return;
6055 /* TMODE must be a fixed-point mode. */
6056 if (!ALL_FIXED_POINT_MODE_P (tmode))
6057 return;
6059 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
6060 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6061 else
6062 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6065 /* Pick proper libcall for satfractuns_optab. */
6067 void
6068 gen_satfractuns_conv_libfunc (convert_optab tab,
6069 const char *opname,
6070 machine_mode tmode,
6071 machine_mode fmode)
6073 if (tmode == fmode)
6074 return;
6075 /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
6076 if (!(ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT))
6077 return;
6079 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6082 /* Hashtable callbacks for libfunc_decls. */
6084 struct libfunc_decl_hasher : ggc_hasher<tree>
6086 static hashval_t
6087 hash (tree entry)
6089 return IDENTIFIER_HASH_VALUE (DECL_NAME (entry));
6092 static bool
6093 equal (tree decl, tree name)
6095 return DECL_NAME (decl) == name;
6099 /* A table of previously-created libfuncs, hashed by name. */
6100 static GTY (()) hash_table<libfunc_decl_hasher> *libfunc_decls;
6102 /* Build a decl for a libfunc named NAME. */
6104 tree
6105 build_libfunc_function (const char *name)
6107 tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
6108 get_identifier (name),
6109 build_function_type (integer_type_node, NULL_TREE));
6110 /* ??? We don't have any type information except for this is
6111 a function. Pretend this is "int foo()". */
6112 DECL_ARTIFICIAL (decl) = 1;
6113 DECL_EXTERNAL (decl) = 1;
6114 TREE_PUBLIC (decl) = 1;
6115 gcc_assert (DECL_ASSEMBLER_NAME (decl));
6117 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
6118 are the flags assigned by targetm.encode_section_info. */
6119 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
6121 return decl;
6125 init_one_libfunc (const char *name)
6127 tree id, decl;
6128 hashval_t hash;
6130 if (libfunc_decls == NULL)
6131 libfunc_decls = hash_table<libfunc_decl_hasher>::create_ggc (37);
6133 /* See if we have already created a libfunc decl for this function. */
6134 id = get_identifier (name);
6135 hash = IDENTIFIER_HASH_VALUE (id);
6136 tree *slot = libfunc_decls->find_slot_with_hash (id, hash, INSERT);
6137 decl = *slot;
6138 if (decl == NULL)
6140 /* Create a new decl, so that it can be passed to
6141 targetm.encode_section_info. */
6142 decl = build_libfunc_function (name);
6143 *slot = decl;
6145 return XEXP (DECL_RTL (decl), 0);
6148 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */
6151 set_user_assembler_libfunc (const char *name, const char *asmspec)
6153 tree id, decl;
6154 hashval_t hash;
6156 id = get_identifier (name);
6157 hash = IDENTIFIER_HASH_VALUE (id);
6158 tree *slot = libfunc_decls->find_slot_with_hash (id, hash, NO_INSERT);
6159 gcc_assert (slot);
6160 decl = (tree) *slot;
6161 set_user_assembler_name (decl, asmspec);
6162 return XEXP (DECL_RTL (decl), 0);
6165 /* Call this to reset the function entry for one optab (OPTABLE) in mode
6166 MODE to NAME, which should be either 0 or a string constant. */
6167 void
6168 set_optab_libfunc (optab op, machine_mode mode, const char *name)
6170 rtx val;
6171 struct libfunc_entry e;
6172 struct libfunc_entry **slot;
6174 e.op = op;
6175 e.mode1 = mode;
6176 e.mode2 = VOIDmode;
6178 if (name)
6179 val = init_one_libfunc (name);
6180 else
6181 val = 0;
6182 slot = libfunc_hash->find_slot (&e, INSERT);
6183 if (*slot == NULL)
6184 *slot = ggc_alloc<libfunc_entry> ();
6185 (*slot)->op = op;
6186 (*slot)->mode1 = mode;
6187 (*slot)->mode2 = VOIDmode;
6188 (*slot)->libfunc = val;
6191 /* Call this to reset the function entry for one conversion optab
6192 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
6193 either 0 or a string constant. */
6194 void
6195 set_conv_libfunc (convert_optab optab, machine_mode tmode,
6196 machine_mode fmode, const char *name)
6198 rtx val;
6199 struct libfunc_entry e;
6200 struct libfunc_entry **slot;
6202 e.op = optab;
6203 e.mode1 = tmode;
6204 e.mode2 = fmode;
6206 if (name)
6207 val = init_one_libfunc (name);
6208 else
6209 val = 0;
6210 slot = libfunc_hash->find_slot (&e, INSERT);
6211 if (*slot == NULL)
6212 *slot = ggc_alloc<libfunc_entry> ();
6213 (*slot)->op = optab;
6214 (*slot)->mode1 = tmode;
6215 (*slot)->mode2 = fmode;
6216 (*slot)->libfunc = val;
6219 /* Call this to initialize the contents of the optabs
6220 appropriately for the current target machine. */
6222 void
6223 init_optabs (void)
6225 if (libfunc_hash)
6226 libfunc_hash->empty ();
6227 else
6228 libfunc_hash = hash_table<libfunc_hasher>::create_ggc (10);
6230 /* Fill in the optabs with the insns we support. */
6231 init_all_optabs (this_fn_optabs);
6233 /* The ffs function operates on `int'. Fall back on it if we do not
6234 have a libgcc2 function for that width. */
6235 if (INT_TYPE_SIZE < BITS_PER_WORD)
6236 set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, MODE_INT, 0),
6237 "ffs");
6239 /* Explicitly initialize the bswap libfuncs since we need them to be
6240 valid for things other than word_mode. */
6241 if (targetm.libfunc_gnu_prefix)
6243 set_optab_libfunc (bswap_optab, SImode, "__gnu_bswapsi2");
6244 set_optab_libfunc (bswap_optab, DImode, "__gnu_bswapdi2");
6246 else
6248 set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
6249 set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
6252 /* Use cabs for double complex abs, since systems generally have cabs.
6253 Don't define any libcall for float complex, so that cabs will be used. */
6254 if (complex_double_type_node)
6255 set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node),
6256 "cabs");
6258 abort_libfunc = init_one_libfunc ("abort");
6259 memcpy_libfunc = init_one_libfunc ("memcpy");
6260 memmove_libfunc = init_one_libfunc ("memmove");
6261 memcmp_libfunc = init_one_libfunc ("memcmp");
6262 memset_libfunc = init_one_libfunc ("memset");
6263 setbits_libfunc = init_one_libfunc ("__setbits");
6265 #ifndef DONT_USE_BUILTIN_SETJMP
6266 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
6267 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
6268 #else
6269 setjmp_libfunc = init_one_libfunc ("setjmp");
6270 longjmp_libfunc = init_one_libfunc ("longjmp");
6271 #endif
6272 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
6273 unwind_sjlj_unregister_libfunc
6274 = init_one_libfunc ("_Unwind_SjLj_Unregister");
6276 /* For function entry/exit instrumentation. */
6277 profile_function_entry_libfunc
6278 = init_one_libfunc ("__cyg_profile_func_enter");
6279 profile_function_exit_libfunc
6280 = init_one_libfunc ("__cyg_profile_func_exit");
6282 gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
6284 /* Allow the target to add more libcalls or rename some, etc. */
6285 targetm.init_libfuncs ();
6288 /* Use the current target and options to initialize
6289 TREE_OPTIMIZATION_OPTABS (OPTNODE). */
6291 void
6292 init_tree_optimization_optabs (tree optnode)
6294 /* Quick exit if we have already computed optabs for this target. */
6295 if (TREE_OPTIMIZATION_BASE_OPTABS (optnode) == this_target_optabs)
6296 return;
6298 /* Forget any previous information and set up for the current target. */
6299 TREE_OPTIMIZATION_BASE_OPTABS (optnode) = this_target_optabs;
6300 struct target_optabs *tmp_optabs = (struct target_optabs *)
6301 TREE_OPTIMIZATION_OPTABS (optnode);
6302 if (tmp_optabs)
6303 memset (tmp_optabs, 0, sizeof (struct target_optabs));
6304 else
6305 tmp_optabs = ggc_alloc<target_optabs> ();
6307 /* Generate a new set of optabs into tmp_optabs. */
6308 init_all_optabs (tmp_optabs);
6310 /* If the optabs changed, record it. */
6311 if (memcmp (tmp_optabs, this_target_optabs, sizeof (struct target_optabs)))
6312 TREE_OPTIMIZATION_OPTABS (optnode) = tmp_optabs;
6313 else
6315 TREE_OPTIMIZATION_OPTABS (optnode) = NULL;
6316 ggc_free (tmp_optabs);
6320 /* A helper function for init_sync_libfuncs. Using the basename BASE,
6321 install libfuncs into TAB for BASE_N for 1 <= N <= MAX. */
6323 static void
6324 init_sync_libfuncs_1 (optab tab, const char *base, int max)
6326 machine_mode mode;
6327 char buf[64];
6328 size_t len = strlen (base);
6329 int i;
6331 gcc_assert (max <= 8);
6332 gcc_assert (len + 3 < sizeof (buf));
6334 memcpy (buf, base, len);
6335 buf[len] = '_';
6336 buf[len + 1] = '0';
6337 buf[len + 2] = '\0';
6339 mode = QImode;
6340 for (i = 1; i <= max; i *= 2)
6342 buf[len + 1] = '0' + i;
6343 set_optab_libfunc (tab, mode, buf);
6344 mode = GET_MODE_2XWIDER_MODE (mode);
6348 void
6349 init_sync_libfuncs (int max)
6351 if (!flag_sync_libcalls)
6352 return;
6354 init_sync_libfuncs_1 (sync_compare_and_swap_optab,
6355 "__sync_val_compare_and_swap", max);
6356 init_sync_libfuncs_1 (sync_lock_test_and_set_optab,
6357 "__sync_lock_test_and_set", max);
6359 init_sync_libfuncs_1 (sync_old_add_optab, "__sync_fetch_and_add", max);
6360 init_sync_libfuncs_1 (sync_old_sub_optab, "__sync_fetch_and_sub", max);
6361 init_sync_libfuncs_1 (sync_old_ior_optab, "__sync_fetch_and_or", max);
6362 init_sync_libfuncs_1 (sync_old_and_optab, "__sync_fetch_and_and", max);
6363 init_sync_libfuncs_1 (sync_old_xor_optab, "__sync_fetch_and_xor", max);
6364 init_sync_libfuncs_1 (sync_old_nand_optab, "__sync_fetch_and_nand", max);
6366 init_sync_libfuncs_1 (sync_new_add_optab, "__sync_add_and_fetch", max);
6367 init_sync_libfuncs_1 (sync_new_sub_optab, "__sync_sub_and_fetch", max);
6368 init_sync_libfuncs_1 (sync_new_ior_optab, "__sync_or_and_fetch", max);
6369 init_sync_libfuncs_1 (sync_new_and_optab, "__sync_and_and_fetch", max);
6370 init_sync_libfuncs_1 (sync_new_xor_optab, "__sync_xor_and_fetch", max);
6371 init_sync_libfuncs_1 (sync_new_nand_optab, "__sync_nand_and_fetch", max);
6374 /* Print information about the current contents of the optabs on
6375 STDERR. */
6377 DEBUG_FUNCTION void
6378 debug_optab_libfuncs (void)
6380 int i, j, k;
6382 /* Dump the arithmetic optabs. */
6383 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
6384 for (j = 0; j < NUM_MACHINE_MODES; ++j)
6386 rtx l = optab_libfunc ((optab) i, (machine_mode) j);
6387 if (l)
6389 gcc_assert (GET_CODE (l) == SYMBOL_REF);
6390 fprintf (stderr, "%s\t%s:\t%s\n",
6391 GET_RTX_NAME (optab_to_code ((optab) i)),
6392 GET_MODE_NAME (j),
6393 XSTR (l, 0));
6397 /* Dump the conversion optabs. */
6398 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
6399 for (j = 0; j < NUM_MACHINE_MODES; ++j)
6400 for (k = 0; k < NUM_MACHINE_MODES; ++k)
6402 rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
6403 (machine_mode) k);
6404 if (l)
6406 gcc_assert (GET_CODE (l) == SYMBOL_REF);
6407 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
6408 GET_RTX_NAME (optab_to_code ((optab) i)),
6409 GET_MODE_NAME (j),
6410 GET_MODE_NAME (k),
6411 XSTR (l, 0));
6417 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6418 CODE. Return 0 on failure. */
6421 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
6423 machine_mode mode = GET_MODE (op1);
6424 enum insn_code icode;
6425 rtx insn;
6426 rtx trap_rtx;
6428 if (mode == VOIDmode)
6429 return 0;
6431 icode = optab_handler (ctrap_optab, mode);
6432 if (icode == CODE_FOR_nothing)
6433 return 0;
6435 /* Some targets only accept a zero trap code. */
6436 if (!insn_operand_matches (icode, 3, tcode))
6437 return 0;
6439 do_pending_stack_adjust ();
6440 start_sequence ();
6441 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
6442 &trap_rtx, &mode);
6443 if (!trap_rtx)
6444 insn = NULL_RTX;
6445 else
6446 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
6447 tcode);
6449 /* If that failed, then give up. */
6450 if (insn == 0)
6452 end_sequence ();
6453 return 0;
6456 emit_insn (insn);
6457 insn = get_insns ();
6458 end_sequence ();
6459 return insn;
6462 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6463 or unsigned operation code. */
6465 enum rtx_code
6466 get_rtx_code (enum tree_code tcode, bool unsignedp)
6468 enum rtx_code code;
6469 switch (tcode)
6471 case EQ_EXPR:
6472 code = EQ;
6473 break;
6474 case NE_EXPR:
6475 code = NE;
6476 break;
6477 case LT_EXPR:
6478 code = unsignedp ? LTU : LT;
6479 break;
6480 case LE_EXPR:
6481 code = unsignedp ? LEU : LE;
6482 break;
6483 case GT_EXPR:
6484 code = unsignedp ? GTU : GT;
6485 break;
6486 case GE_EXPR:
6487 code = unsignedp ? GEU : GE;
6488 break;
6490 case UNORDERED_EXPR:
6491 code = UNORDERED;
6492 break;
6493 case ORDERED_EXPR:
6494 code = ORDERED;
6495 break;
6496 case UNLT_EXPR:
6497 code = UNLT;
6498 break;
6499 case UNLE_EXPR:
6500 code = UNLE;
6501 break;
6502 case UNGT_EXPR:
6503 code = UNGT;
6504 break;
6505 case UNGE_EXPR:
6506 code = UNGE;
6507 break;
6508 case UNEQ_EXPR:
6509 code = UNEQ;
6510 break;
6511 case LTGT_EXPR:
6512 code = LTGT;
6513 break;
6515 case BIT_AND_EXPR:
6516 code = AND;
6517 break;
6519 case BIT_IOR_EXPR:
6520 code = IOR;
6521 break;
6523 default:
6524 gcc_unreachable ();
6526 return code;
6529 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6530 unsigned operators. Do not generate compare instruction. */
6532 static rtx
6533 vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
6534 bool unsignedp, enum insn_code icode)
6536 struct expand_operand ops[2];
6537 rtx rtx_op0, rtx_op1;
6538 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
6540 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
6542 /* Expand operands. */
6543 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
6544 EXPAND_STACK_PARM);
6545 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
6546 EXPAND_STACK_PARM);
6548 create_input_operand (&ops[0], rtx_op0, GET_MODE (rtx_op0));
6549 create_input_operand (&ops[1], rtx_op1, GET_MODE (rtx_op1));
6550 if (!maybe_legitimize_operands (icode, 4, 2, ops))
6551 gcc_unreachable ();
6552 return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
6555 /* Return true if VEC_PERM_EXPR of arbitrary input vectors can be expanded using
6556 SIMD extensions of the CPU. SEL may be NULL, which stands for an unknown
6557 constant. Note that additional permutations representing whole-vector shifts
6558 may also be handled via the vec_shr optab, but only where the second input
6559 vector is entirely constant zeroes; this case is not dealt with here. */
6561 bool
6562 can_vec_perm_p (machine_mode mode, bool variable,
6563 const unsigned char *sel)
6565 machine_mode qimode;
6567 /* If the target doesn't implement a vector mode for the vector type,
6568 then no operations are supported. */
6569 if (!VECTOR_MODE_P (mode))
6570 return false;
6572 if (!variable)
6574 if (direct_optab_handler (vec_perm_const_optab, mode) != CODE_FOR_nothing
6575 && (sel == NULL
6576 || targetm.vectorize.vec_perm_const_ok == NULL
6577 || targetm.vectorize.vec_perm_const_ok (mode, sel)))
6578 return true;
6581 if (direct_optab_handler (vec_perm_optab, mode) != CODE_FOR_nothing)
6582 return true;
6584 /* We allow fallback to a QI vector mode, and adjust the mask. */
6585 if (GET_MODE_INNER (mode) == QImode)
6586 return false;
6587 qimode = mode_for_vector (QImode, GET_MODE_SIZE (mode));
6588 if (!VECTOR_MODE_P (qimode))
6589 return false;
6591 /* ??? For completeness, we ought to check the QImode version of
6592 vec_perm_const_optab. But all users of this implicit lowering
6593 feature implement the variable vec_perm_optab. */
6594 if (direct_optab_handler (vec_perm_optab, qimode) == CODE_FOR_nothing)
6595 return false;
6597 /* In order to support the lowering of variable permutations,
6598 we need to support shifts and adds. */
6599 if (variable)
6601 if (GET_MODE_UNIT_SIZE (mode) > 2
6602 && optab_handler (ashl_optab, mode) == CODE_FOR_nothing
6603 && optab_handler (vashl_optab, mode) == CODE_FOR_nothing)
6604 return false;
6605 if (optab_handler (add_optab, qimode) == CODE_FOR_nothing)
6606 return false;
6609 return true;
6612 /* Checks if vec_perm mask SEL is a constant equivalent to a shift of the first
6613 vec_perm operand, assuming the second operand is a constant vector of zeroes.
6614 Return the shift distance in bits if so, or NULL_RTX if the vec_perm is not a
6615 shift. */
6616 static rtx
6617 shift_amt_for_vec_perm_mask (rtx sel)
6619 unsigned int i, first, nelt = GET_MODE_NUNITS (GET_MODE (sel));
6620 unsigned int bitsize = GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (sel)));
6622 if (GET_CODE (sel) != CONST_VECTOR)
6623 return NULL_RTX;
6625 first = INTVAL (CONST_VECTOR_ELT (sel, 0));
6626 if (first >= 2*nelt)
6627 return NULL_RTX;
6628 for (i = 1; i < nelt; i++)
6630 int idx = INTVAL (CONST_VECTOR_ELT (sel, i));
6631 unsigned int expected = (i + first) & (2 * nelt - 1);
6632 /* Indices into the second vector are all equivalent. */
6633 if (idx < 0 || (MIN (nelt, (unsigned) idx) != MIN (nelt, expected)))
6634 return NULL_RTX;
6637 return GEN_INT (first * bitsize);
6640 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
6642 static rtx
6643 expand_vec_perm_1 (enum insn_code icode, rtx target,
6644 rtx v0, rtx v1, rtx sel)
6646 machine_mode tmode = GET_MODE (target);
6647 machine_mode smode = GET_MODE (sel);
6648 struct expand_operand ops[4];
6650 create_output_operand (&ops[0], target, tmode);
6651 create_input_operand (&ops[3], sel, smode);
6653 /* Make an effort to preserve v0 == v1. The target expander is able to
6654 rely on this to determine if we're permuting a single input operand. */
6655 if (rtx_equal_p (v0, v1))
6657 if (!insn_operand_matches (icode, 1, v0))
6658 v0 = force_reg (tmode, v0);
6659 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
6660 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
6662 create_fixed_operand (&ops[1], v0);
6663 create_fixed_operand (&ops[2], v0);
6665 else
6667 create_input_operand (&ops[1], v0, tmode);
6668 /* See if this can be handled with a vec_shr. We only do this if the
6669 second vector is all zeroes. */
6670 enum insn_code shift_code = optab_handler (vec_shr_optab, GET_MODE (v0));
6671 if (v1 == CONST0_RTX (GET_MODE (v1)) && shift_code)
6672 if (rtx shift_amt = shift_amt_for_vec_perm_mask (sel))
6674 create_convert_operand_from_type (&ops[2], shift_amt,
6675 sizetype_tab[(int) stk_sizetype]);
6676 if (maybe_expand_insn (shift_code, 3, ops))
6677 return ops[0].value;
6679 create_input_operand (&ops[2], v1, tmode);
6682 if (maybe_expand_insn (icode, 4, ops))
6683 return ops[0].value;
6684 return NULL_RTX;
6687 /* Generate instructions for vec_perm optab given its mode
6688 and three operands. */
6691 expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
6693 enum insn_code icode;
6694 machine_mode qimode;
6695 unsigned int i, w, e, u;
6696 rtx tmp, sel_qi = NULL;
6697 rtvec vec;
6699 if (!target || GET_MODE (target) != mode)
6700 target = gen_reg_rtx (mode);
6702 w = GET_MODE_SIZE (mode);
6703 e = GET_MODE_NUNITS (mode);
6704 u = GET_MODE_UNIT_SIZE (mode);
6706 /* Set QIMODE to a different vector mode with byte elements.
6707 If no such mode, or if MODE already has byte elements, use VOIDmode. */
6708 qimode = VOIDmode;
6709 if (GET_MODE_INNER (mode) != QImode)
6711 qimode = mode_for_vector (QImode, w);
6712 if (!VECTOR_MODE_P (qimode))
6713 qimode = VOIDmode;
6716 /* If the input is a constant, expand it specially. */
6717 gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT);
6718 if (GET_CODE (sel) == CONST_VECTOR)
6720 icode = direct_optab_handler (vec_perm_const_optab, mode);
6721 if (icode != CODE_FOR_nothing)
6723 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
6724 if (tmp)
6725 return tmp;
6728 /* Fall back to a constant byte-based permutation. */
6729 if (qimode != VOIDmode)
6731 vec = rtvec_alloc (w);
6732 for (i = 0; i < e; ++i)
6734 unsigned int j, this_e;
6736 this_e = INTVAL (CONST_VECTOR_ELT (sel, i));
6737 this_e &= 2 * e - 1;
6738 this_e *= u;
6740 for (j = 0; j < u; ++j)
6741 RTVEC_ELT (vec, i * u + j) = GEN_INT (this_e + j);
6743 sel_qi = gen_rtx_CONST_VECTOR (qimode, vec);
6745 icode = direct_optab_handler (vec_perm_const_optab, qimode);
6746 if (icode != CODE_FOR_nothing)
6748 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
6749 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
6750 gen_lowpart (qimode, v1), sel_qi);
6751 if (tmp)
6752 return gen_lowpart (mode, tmp);
6757 /* Otherwise expand as a fully variable permuation. */
6758 icode = direct_optab_handler (vec_perm_optab, mode);
6759 if (icode != CODE_FOR_nothing)
6761 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
6762 if (tmp)
6763 return tmp;
6766 /* As a special case to aid several targets, lower the element-based
6767 permutation to a byte-based permutation and try again. */
6768 if (qimode == VOIDmode)
6769 return NULL_RTX;
6770 icode = direct_optab_handler (vec_perm_optab, qimode);
6771 if (icode == CODE_FOR_nothing)
6772 return NULL_RTX;
6774 if (sel_qi == NULL)
6776 /* Multiply each element by its byte size. */
6777 machine_mode selmode = GET_MODE (sel);
6778 if (u == 2)
6779 sel = expand_simple_binop (selmode, PLUS, sel, sel,
6780 sel, 0, OPTAB_DIRECT);
6781 else
6782 sel = expand_simple_binop (selmode, ASHIFT, sel,
6783 GEN_INT (exact_log2 (u)),
6784 sel, 0, OPTAB_DIRECT);
6785 gcc_assert (sel != NULL);
6787 /* Broadcast the low byte each element into each of its bytes. */
6788 vec = rtvec_alloc (w);
6789 for (i = 0; i < w; ++i)
6791 int this_e = i / u * u;
6792 if (BYTES_BIG_ENDIAN)
6793 this_e += u - 1;
6794 RTVEC_ELT (vec, i) = GEN_INT (this_e);
6796 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
6797 sel = gen_lowpart (qimode, sel);
6798 sel = expand_vec_perm (qimode, sel, sel, tmp, NULL);
6799 gcc_assert (sel != NULL);
6801 /* Add the byte offset to each byte element. */
6802 /* Note that the definition of the indicies here is memory ordering,
6803 so there should be no difference between big and little endian. */
6804 vec = rtvec_alloc (w);
6805 for (i = 0; i < w; ++i)
6806 RTVEC_ELT (vec, i) = GEN_INT (i % u);
6807 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
6808 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
6809 sel, 0, OPTAB_DIRECT);
6810 gcc_assert (sel_qi != NULL);
6813 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
6814 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
6815 gen_lowpart (qimode, v1), sel_qi);
6816 if (tmp)
6817 tmp = gen_lowpart (mode, tmp);
6818 return tmp;
6821 /* Return insn code for a conditional operator with a comparison in
6822 mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE. */
6824 static inline enum insn_code
6825 get_vcond_icode (machine_mode vmode, machine_mode cmode, bool uns)
6827 enum insn_code icode = CODE_FOR_nothing;
6828 if (uns)
6829 icode = convert_optab_handler (vcondu_optab, vmode, cmode);
6830 else
6831 icode = convert_optab_handler (vcond_optab, vmode, cmode);
6832 return icode;
6835 /* Return TRUE iff, appropriate vector insns are available
6836 for vector cond expr with vector type VALUE_TYPE and a comparison
6837 with operand vector types in CMP_OP_TYPE. */
6839 bool
6840 expand_vec_cond_expr_p (tree value_type, tree cmp_op_type)
6842 machine_mode value_mode = TYPE_MODE (value_type);
6843 machine_mode cmp_op_mode = TYPE_MODE (cmp_op_type);
6844 if (GET_MODE_SIZE (value_mode) != GET_MODE_SIZE (cmp_op_mode)
6845 || GET_MODE_NUNITS (value_mode) != GET_MODE_NUNITS (cmp_op_mode)
6846 || get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type),
6847 TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing)
6848 return false;
6849 return true;
6852 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
6853 three operands. */
6856 expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
6857 rtx target)
6859 struct expand_operand ops[6];
6860 enum insn_code icode;
6861 rtx comparison, rtx_op1, rtx_op2;
6862 machine_mode mode = TYPE_MODE (vec_cond_type);
6863 machine_mode cmp_op_mode;
6864 bool unsignedp;
6865 tree op0a, op0b;
6866 enum tree_code tcode;
6868 if (COMPARISON_CLASS_P (op0))
6870 op0a = TREE_OPERAND (op0, 0);
6871 op0b = TREE_OPERAND (op0, 1);
6872 tcode = TREE_CODE (op0);
6874 else
6876 /* Fake op0 < 0. */
6877 gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (op0)));
6878 op0a = op0;
6879 op0b = build_zero_cst (TREE_TYPE (op0));
6880 tcode = LT_EXPR;
6882 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
6883 cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
6886 gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
6887 && GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
6889 icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
6890 if (icode == CODE_FOR_nothing)
6891 return 0;
6893 comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode);
6894 rtx_op1 = expand_normal (op1);
6895 rtx_op2 = expand_normal (op2);
6897 create_output_operand (&ops[0], target, mode);
6898 create_input_operand (&ops[1], rtx_op1, mode);
6899 create_input_operand (&ops[2], rtx_op2, mode);
6900 create_fixed_operand (&ops[3], comparison);
6901 create_fixed_operand (&ops[4], XEXP (comparison, 0));
6902 create_fixed_operand (&ops[5], XEXP (comparison, 1));
6903 expand_insn (icode, 6, ops);
6904 return ops[0].value;
6907 /* Return non-zero if a highpart multiply is supported of can be synthisized.
6908 For the benefit of expand_mult_highpart, the return value is 1 for direct,
6909 2 for even/odd widening, and 3 for hi/lo widening. */
6912 can_mult_highpart_p (machine_mode mode, bool uns_p)
6914 optab op;
6915 unsigned char *sel;
6916 unsigned i, nunits;
6918 op = uns_p ? umul_highpart_optab : smul_highpart_optab;
6919 if (optab_handler (op, mode) != CODE_FOR_nothing)
6920 return 1;
6922 /* If the mode is an integral vector, synth from widening operations. */
6923 if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
6924 return 0;
6926 nunits = GET_MODE_NUNITS (mode);
6927 sel = XALLOCAVEC (unsigned char, nunits);
6929 op = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
6930 if (optab_handler (op, mode) != CODE_FOR_nothing)
6932 op = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
6933 if (optab_handler (op, mode) != CODE_FOR_nothing)
6935 for (i = 0; i < nunits; ++i)
6936 sel[i] = !BYTES_BIG_ENDIAN + (i & ~1) + ((i & 1) ? nunits : 0);
6937 if (can_vec_perm_p (mode, false, sel))
6938 return 2;
6942 op = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
6943 if (optab_handler (op, mode) != CODE_FOR_nothing)
6945 op = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
6946 if (optab_handler (op, mode) != CODE_FOR_nothing)
6948 for (i = 0; i < nunits; ++i)
6949 sel[i] = 2 * i + (BYTES_BIG_ENDIAN ? 0 : 1);
6950 if (can_vec_perm_p (mode, false, sel))
6951 return 3;
6955 return 0;
6958 /* Expand a highpart multiply. */
6961 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
6962 rtx target, bool uns_p)
6964 struct expand_operand eops[3];
6965 enum insn_code icode;
6966 int method, i, nunits;
6967 machine_mode wmode;
6968 rtx m1, m2, perm;
6969 optab tab1, tab2;
6970 rtvec v;
6972 method = can_mult_highpart_p (mode, uns_p);
6973 switch (method)
6975 case 0:
6976 return NULL_RTX;
6977 case 1:
6978 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
6979 return expand_binop (mode, tab1, op0, op1, target, uns_p,
6980 OPTAB_LIB_WIDEN);
6981 case 2:
6982 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
6983 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
6984 break;
6985 case 3:
6986 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
6987 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
6988 if (BYTES_BIG_ENDIAN)
6990 optab t = tab1;
6991 tab1 = tab2;
6992 tab2 = t;
6994 break;
6995 default:
6996 gcc_unreachable ();
6999 icode = optab_handler (tab1, mode);
7000 nunits = GET_MODE_NUNITS (mode);
7001 wmode = insn_data[icode].operand[0].mode;
7002 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode) == nunits);
7003 gcc_checking_assert (GET_MODE_SIZE (wmode) == GET_MODE_SIZE (mode));
7005 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
7006 create_input_operand (&eops[1], op0, mode);
7007 create_input_operand (&eops[2], op1, mode);
7008 expand_insn (icode, 3, eops);
7009 m1 = gen_lowpart (mode, eops[0].value);
7011 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
7012 create_input_operand (&eops[1], op0, mode);
7013 create_input_operand (&eops[2], op1, mode);
7014 expand_insn (optab_handler (tab2, mode), 3, eops);
7015 m2 = gen_lowpart (mode, eops[0].value);
7017 v = rtvec_alloc (nunits);
7018 if (method == 2)
7020 for (i = 0; i < nunits; ++i)
7021 RTVEC_ELT (v, i) = GEN_INT (!BYTES_BIG_ENDIAN + (i & ~1)
7022 + ((i & 1) ? nunits : 0));
7024 else
7026 for (i = 0; i < nunits; ++i)
7027 RTVEC_ELT (v, i) = GEN_INT (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
7029 perm = gen_rtx_CONST_VECTOR (mode, v);
7031 return expand_vec_perm (mode, m1, m2, perm, target);
7034 /* Return true if target supports vector masked load/store for mode. */
7035 bool
7036 can_vec_mask_load_store_p (machine_mode mode, bool is_load)
7038 optab op = is_load ? maskload_optab : maskstore_optab;
7039 machine_mode vmode;
7040 unsigned int vector_sizes;
7042 /* If mode is vector mode, check it directly. */
7043 if (VECTOR_MODE_P (mode))
7044 return optab_handler (op, mode) != CODE_FOR_nothing;
7046 /* Otherwise, return true if there is some vector mode with
7047 the mask load/store supported. */
7049 /* See if there is any chance the mask load or store might be
7050 vectorized. If not, punt. */
7051 vmode = targetm.vectorize.preferred_simd_mode (mode);
7052 if (!VECTOR_MODE_P (vmode))
7053 return false;
7055 if (optab_handler (op, vmode) != CODE_FOR_nothing)
7056 return true;
7058 vector_sizes = targetm.vectorize.autovectorize_vector_sizes ();
7059 while (vector_sizes != 0)
7061 unsigned int cur = 1 << floor_log2 (vector_sizes);
7062 vector_sizes &= ~cur;
7063 if (cur <= GET_MODE_SIZE (mode))
7064 continue;
7065 vmode = mode_for_vector (mode, cur / GET_MODE_SIZE (mode));
7066 if (VECTOR_MODE_P (vmode)
7067 && optab_handler (op, vmode) != CODE_FOR_nothing)
7068 return true;
7070 return false;
7073 /* Return true if there is a compare_and_swap pattern. */
7075 bool
7076 can_compare_and_swap_p (machine_mode mode, bool allow_libcall)
7078 enum insn_code icode;
7080 /* Check for __atomic_compare_and_swap. */
7081 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
7082 if (icode != CODE_FOR_nothing)
7083 return true;
7085 /* Check for __sync_compare_and_swap. */
7086 icode = optab_handler (sync_compare_and_swap_optab, mode);
7087 if (icode != CODE_FOR_nothing)
7088 return true;
7089 if (allow_libcall && optab_libfunc (sync_compare_and_swap_optab, mode))
7090 return true;
7092 /* No inline compare and swap. */
7093 return false;
7096 /* Return true if an atomic exchange can be performed. */
7098 bool
7099 can_atomic_exchange_p (machine_mode mode, bool allow_libcall)
7101 enum insn_code icode;
7103 /* Check for __atomic_exchange. */
7104 icode = direct_optab_handler (atomic_exchange_optab, mode);
7105 if (icode != CODE_FOR_nothing)
7106 return true;
7108 /* Don't check __sync_test_and_set, as on some platforms that
7109 has reduced functionality. Targets that really do support
7110 a proper exchange should simply be updated to the __atomics. */
7112 return can_compare_and_swap_p (mode, allow_libcall);
7116 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
7117 pattern. */
7119 static void
7120 find_cc_set (rtx x, const_rtx pat, void *data)
7122 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
7123 && GET_CODE (pat) == SET)
7125 rtx *p_cc_reg = (rtx *) data;
7126 gcc_assert (!*p_cc_reg);
7127 *p_cc_reg = x;
7131 /* This is a helper function for the other atomic operations. This function
7132 emits a loop that contains SEQ that iterates until a compare-and-swap
7133 operation at the end succeeds. MEM is the memory to be modified. SEQ is
7134 a set of instructions that takes a value from OLD_REG as an input and
7135 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
7136 set to the current contents of MEM. After SEQ, a compare-and-swap will
7137 attempt to update MEM with NEW_REG. The function returns true when the
7138 loop was generated successfully. */
7140 static bool
7141 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
7143 machine_mode mode = GET_MODE (mem);
7144 rtx_code_label *label;
7145 rtx cmp_reg, success, oldval;
7147 /* The loop we want to generate looks like
7149 cmp_reg = mem;
7150 label:
7151 old_reg = cmp_reg;
7152 seq;
7153 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
7154 if (success)
7155 goto label;
7157 Note that we only do the plain load from memory once. Subsequent
7158 iterations use the value loaded by the compare-and-swap pattern. */
7160 label = gen_label_rtx ();
7161 cmp_reg = gen_reg_rtx (mode);
7163 emit_move_insn (cmp_reg, mem);
7164 emit_label (label);
7165 emit_move_insn (old_reg, cmp_reg);
7166 if (seq)
7167 emit_insn (seq);
7169 success = NULL_RTX;
7170 oldval = cmp_reg;
7171 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
7172 new_reg, false, MEMMODEL_SEQ_CST,
7173 MEMMODEL_RELAXED))
7174 return false;
7176 if (oldval != cmp_reg)
7177 emit_move_insn (cmp_reg, oldval);
7179 /* Mark this jump predicted not taken. */
7180 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
7181 GET_MODE (success), 1, label, 0);
7182 return true;
7186 /* This function tries to emit an atomic_exchange intruction. VAL is written
7187 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
7188 using TARGET if possible. */
7190 static rtx
7191 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
7193 machine_mode mode = GET_MODE (mem);
7194 enum insn_code icode;
7196 /* If the target supports the exchange directly, great. */
7197 icode = direct_optab_handler (atomic_exchange_optab, mode);
7198 if (icode != CODE_FOR_nothing)
7200 struct expand_operand ops[4];
7202 create_output_operand (&ops[0], target, mode);
7203 create_fixed_operand (&ops[1], mem);
7204 create_input_operand (&ops[2], val, mode);
7205 create_integer_operand (&ops[3], model);
7206 if (maybe_expand_insn (icode, 4, ops))
7207 return ops[0].value;
7210 return NULL_RTX;
7213 /* This function tries to implement an atomic exchange operation using
7214 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
7215 The previous contents of *MEM are returned, using TARGET if possible.
7216 Since this instructionn is an acquire barrier only, stronger memory
7217 models may require additional barriers to be emitted. */
7219 static rtx
7220 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
7221 enum memmodel model)
7223 machine_mode mode = GET_MODE (mem);
7224 enum insn_code icode;
7225 rtx_insn *last_insn = get_last_insn ();
7227 icode = optab_handler (sync_lock_test_and_set_optab, mode);
7229 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
7230 exists, and the memory model is stronger than acquire, add a release
7231 barrier before the instruction. */
7233 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST
7234 || (model & MEMMODEL_MASK) == MEMMODEL_RELEASE
7235 || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
7236 expand_mem_thread_fence (model);
7238 if (icode != CODE_FOR_nothing)
7240 struct expand_operand ops[3];
7241 create_output_operand (&ops[0], target, mode);
7242 create_fixed_operand (&ops[1], mem);
7243 create_input_operand (&ops[2], val, mode);
7244 if (maybe_expand_insn (icode, 3, ops))
7245 return ops[0].value;
7248 /* If an external test-and-set libcall is provided, use that instead of
7249 any external compare-and-swap that we might get from the compare-and-
7250 swap-loop expansion later. */
7251 if (!can_compare_and_swap_p (mode, false))
7253 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
7254 if (libfunc != NULL)
7256 rtx addr;
7258 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7259 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
7260 mode, 2, addr, ptr_mode,
7261 val, mode);
7265 /* If the test_and_set can't be emitted, eliminate any barrier that might
7266 have been emitted. */
7267 delete_insns_since (last_insn);
7268 return NULL_RTX;
7271 /* This function tries to implement an atomic exchange operation using a
7272 compare_and_swap loop. VAL is written to *MEM. The previous contents of
7273 *MEM are returned, using TARGET if possible. No memory model is required
7274 since a compare_and_swap loop is seq-cst. */
7276 static rtx
7277 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
7279 machine_mode mode = GET_MODE (mem);
7281 if (can_compare_and_swap_p (mode, true))
7283 if (!target || !register_operand (target, mode))
7284 target = gen_reg_rtx (mode);
7285 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
7286 return target;
7289 return NULL_RTX;
7292 /* This function tries to implement an atomic test-and-set operation
7293 using the atomic_test_and_set instruction pattern. A boolean value
7294 is returned from the operation, using TARGET if possible. */
7296 #ifndef HAVE_atomic_test_and_set
7297 #define HAVE_atomic_test_and_set 0
7298 #define CODE_FOR_atomic_test_and_set CODE_FOR_nothing
7299 #endif
7301 static rtx
7302 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
7304 machine_mode pat_bool_mode;
7305 struct expand_operand ops[3];
7307 if (!HAVE_atomic_test_and_set)
7308 return NULL_RTX;
7310 /* While we always get QImode from __atomic_test_and_set, we get
7311 other memory modes from __sync_lock_test_and_set. Note that we
7312 use no endian adjustment here. This matches the 4.6 behavior
7313 in the Sparc backend. */
7314 gcc_checking_assert
7315 (insn_data[CODE_FOR_atomic_test_and_set].operand[1].mode == QImode);
7316 if (GET_MODE (mem) != QImode)
7317 mem = adjust_address_nv (mem, QImode, 0);
7319 pat_bool_mode = insn_data[CODE_FOR_atomic_test_and_set].operand[0].mode;
7320 create_output_operand (&ops[0], target, pat_bool_mode);
7321 create_fixed_operand (&ops[1], mem);
7322 create_integer_operand (&ops[2], model);
7324 if (maybe_expand_insn (CODE_FOR_atomic_test_and_set, 3, ops))
7325 return ops[0].value;
7326 return NULL_RTX;
7329 /* This function expands the legacy _sync_lock test_and_set operation which is
7330 generally an atomic exchange. Some limited targets only allow the
7331 constant 1 to be stored. This is an ACQUIRE operation.
7333 TARGET is an optional place to stick the return value.
7334 MEM is where VAL is stored. */
7337 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
7339 rtx ret;
7341 /* Try an atomic_exchange first. */
7342 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_ACQUIRE);
7343 if (ret)
7344 return ret;
7346 ret = maybe_emit_sync_lock_test_and_set (target, mem, val, MEMMODEL_ACQUIRE);
7347 if (ret)
7348 return ret;
7350 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
7351 if (ret)
7352 return ret;
7354 /* If there are no other options, try atomic_test_and_set if the value
7355 being stored is 1. */
7356 if (val == const1_rtx)
7357 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_ACQUIRE);
7359 return ret;
7362 /* This function expands the atomic test_and_set operation:
7363 atomically store a boolean TRUE into MEM and return the previous value.
7365 MEMMODEL is the memory model variant to use.
7366 TARGET is an optional place to stick the return value. */
7369 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
7371 machine_mode mode = GET_MODE (mem);
7372 rtx ret, trueval, subtarget;
7374 ret = maybe_emit_atomic_test_and_set (target, mem, model);
7375 if (ret)
7376 return ret;
7378 /* Be binary compatible with non-default settings of trueval, and different
7379 cpu revisions. E.g. one revision may have atomic-test-and-set, but
7380 another only has atomic-exchange. */
7381 if (targetm.atomic_test_and_set_trueval == 1)
7383 trueval = const1_rtx;
7384 subtarget = target ? target : gen_reg_rtx (mode);
7386 else
7388 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
7389 subtarget = gen_reg_rtx (mode);
7392 /* Try the atomic-exchange optab... */
7393 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
7395 /* ... then an atomic-compare-and-swap loop ... */
7396 if (!ret)
7397 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
7399 /* ... before trying the vaguely defined legacy lock_test_and_set. */
7400 if (!ret)
7401 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
7403 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
7404 things with the value 1. Thus we try again without trueval. */
7405 if (!ret && targetm.atomic_test_and_set_trueval != 1)
7406 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
7408 /* Failing all else, assume a single threaded environment and simply
7409 perform the operation. */
7410 if (!ret)
7412 /* If the result is ignored skip the move to target. */
7413 if (subtarget != const0_rtx)
7414 emit_move_insn (subtarget, mem);
7416 emit_move_insn (mem, trueval);
7417 ret = subtarget;
7420 /* Recall that have to return a boolean value; rectify if trueval
7421 is not exactly one. */
7422 if (targetm.atomic_test_and_set_trueval != 1)
7423 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
7425 return ret;
7428 /* This function expands the atomic exchange operation:
7429 atomically store VAL in MEM and return the previous value in MEM.
7431 MEMMODEL is the memory model variant to use.
7432 TARGET is an optional place to stick the return value. */
7435 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
7437 rtx ret;
7439 ret = maybe_emit_atomic_exchange (target, mem, val, model);
7441 /* Next try a compare-and-swap loop for the exchange. */
7442 if (!ret)
7443 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
7445 return ret;
7448 /* This function expands the atomic compare exchange operation:
7450 *PTARGET_BOOL is an optional place to store the boolean success/failure.
7451 *PTARGET_OVAL is an optional place to store the old value from memory.
7452 Both target parameters may be NULL to indicate that we do not care about
7453 that return value. Both target parameters are updated on success to
7454 the actual location of the corresponding result.
7456 MEMMODEL is the memory model variant to use.
7458 The return value of the function is true for success. */
7460 bool
7461 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
7462 rtx mem, rtx expected, rtx desired,
7463 bool is_weak, enum memmodel succ_model,
7464 enum memmodel fail_model)
7466 machine_mode mode = GET_MODE (mem);
7467 struct expand_operand ops[8];
7468 enum insn_code icode;
7469 rtx target_oval, target_bool = NULL_RTX;
7470 rtx libfunc;
7472 /* Load expected into a register for the compare and swap. */
7473 if (MEM_P (expected))
7474 expected = copy_to_reg (expected);
7476 /* Make sure we always have some place to put the return oldval.
7477 Further, make sure that place is distinct from the input expected,
7478 just in case we need that path down below. */
7479 if (ptarget_oval == NULL
7480 || (target_oval = *ptarget_oval) == NULL
7481 || reg_overlap_mentioned_p (expected, target_oval))
7482 target_oval = gen_reg_rtx (mode);
7484 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
7485 if (icode != CODE_FOR_nothing)
7487 machine_mode bool_mode = insn_data[icode].operand[0].mode;
7489 /* Make sure we always have a place for the bool operand. */
7490 if (ptarget_bool == NULL
7491 || (target_bool = *ptarget_bool) == NULL
7492 || GET_MODE (target_bool) != bool_mode)
7493 target_bool = gen_reg_rtx (bool_mode);
7495 /* Emit the compare_and_swap. */
7496 create_output_operand (&ops[0], target_bool, bool_mode);
7497 create_output_operand (&ops[1], target_oval, mode);
7498 create_fixed_operand (&ops[2], mem);
7499 create_input_operand (&ops[3], expected, mode);
7500 create_input_operand (&ops[4], desired, mode);
7501 create_integer_operand (&ops[5], is_weak);
7502 create_integer_operand (&ops[6], succ_model);
7503 create_integer_operand (&ops[7], fail_model);
7504 if (maybe_expand_insn (icode, 8, ops))
7506 /* Return success/failure. */
7507 target_bool = ops[0].value;
7508 target_oval = ops[1].value;
7509 goto success;
7513 /* Otherwise fall back to the original __sync_val_compare_and_swap
7514 which is always seq-cst. */
7515 icode = optab_handler (sync_compare_and_swap_optab, mode);
7516 if (icode != CODE_FOR_nothing)
7518 rtx cc_reg;
7520 create_output_operand (&ops[0], target_oval, mode);
7521 create_fixed_operand (&ops[1], mem);
7522 create_input_operand (&ops[2], expected, mode);
7523 create_input_operand (&ops[3], desired, mode);
7524 if (!maybe_expand_insn (icode, 4, ops))
7525 return false;
7527 target_oval = ops[0].value;
7529 /* If the caller isn't interested in the boolean return value,
7530 skip the computation of it. */
7531 if (ptarget_bool == NULL)
7532 goto success;
7534 /* Otherwise, work out if the compare-and-swap succeeded. */
7535 cc_reg = NULL_RTX;
7536 if (have_insn_for (COMPARE, CCmode))
7537 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
7538 if (cc_reg)
7540 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
7541 const0_rtx, VOIDmode, 0, 1);
7542 goto success;
7544 goto success_bool_from_val;
7547 /* Also check for library support for __sync_val_compare_and_swap. */
7548 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
7549 if (libfunc != NULL)
7551 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7552 target_oval = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
7553 mode, 3, addr, ptr_mode,
7554 expected, mode, desired, mode);
7556 /* Compute the boolean return value only if requested. */
7557 if (ptarget_bool)
7558 goto success_bool_from_val;
7559 else
7560 goto success;
7563 /* Failure. */
7564 return false;
7566 success_bool_from_val:
7567 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
7568 expected, VOIDmode, 1, 1);
7569 success:
7570 /* Make sure that the oval output winds up where the caller asked. */
7571 if (ptarget_oval)
7572 *ptarget_oval = target_oval;
7573 if (ptarget_bool)
7574 *ptarget_bool = target_bool;
7575 return true;
7578 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
7580 static void
7581 expand_asm_memory_barrier (void)
7583 rtx asm_op, clob;
7585 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, empty_string, empty_string, 0,
7586 rtvec_alloc (0), rtvec_alloc (0),
7587 rtvec_alloc (0), UNKNOWN_LOCATION);
7588 MEM_VOLATILE_P (asm_op) = 1;
7590 clob = gen_rtx_SCRATCH (VOIDmode);
7591 clob = gen_rtx_MEM (BLKmode, clob);
7592 clob = gen_rtx_CLOBBER (VOIDmode, clob);
7594 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
7597 /* This routine will either emit the mem_thread_fence pattern or issue a
7598 sync_synchronize to generate a fence for memory model MEMMODEL. */
7600 #ifndef HAVE_mem_thread_fence
7601 # define HAVE_mem_thread_fence 0
7602 # define gen_mem_thread_fence(x) (gcc_unreachable (), NULL_RTX)
7603 #endif
7604 #ifndef HAVE_memory_barrier
7605 # define HAVE_memory_barrier 0
7606 # define gen_memory_barrier() (gcc_unreachable (), NULL_RTX)
7607 #endif
7609 void
7610 expand_mem_thread_fence (enum memmodel model)
7612 if (HAVE_mem_thread_fence)
7613 emit_insn (gen_mem_thread_fence (GEN_INT (model)));
7614 else if ((model & MEMMODEL_MASK) != MEMMODEL_RELAXED)
7616 if (HAVE_memory_barrier)
7617 emit_insn (gen_memory_barrier ());
7618 else if (synchronize_libfunc != NULL_RTX)
7619 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
7620 else
7621 expand_asm_memory_barrier ();
7625 /* This routine will either emit the mem_signal_fence pattern or issue a
7626 sync_synchronize to generate a fence for memory model MEMMODEL. */
7628 #ifndef HAVE_mem_signal_fence
7629 # define HAVE_mem_signal_fence 0
7630 # define gen_mem_signal_fence(x) (gcc_unreachable (), NULL_RTX)
7631 #endif
7633 void
7634 expand_mem_signal_fence (enum memmodel model)
7636 if (HAVE_mem_signal_fence)
7637 emit_insn (gen_mem_signal_fence (GEN_INT (model)));
7638 else if ((model & MEMMODEL_MASK) != MEMMODEL_RELAXED)
7640 /* By default targets are coherent between a thread and the signal
7641 handler running on the same thread. Thus this really becomes a
7642 compiler barrier, in that stores must not be sunk past
7643 (or raised above) a given point. */
7644 expand_asm_memory_barrier ();
7648 /* This function expands the atomic load operation:
7649 return the atomically loaded value in MEM.
7651 MEMMODEL is the memory model variant to use.
7652 TARGET is an option place to stick the return value. */
7655 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
7657 machine_mode mode = GET_MODE (mem);
7658 enum insn_code icode;
7660 /* If the target supports the load directly, great. */
7661 icode = direct_optab_handler (atomic_load_optab, mode);
7662 if (icode != CODE_FOR_nothing)
7664 struct expand_operand ops[3];
7666 create_output_operand (&ops[0], target, mode);
7667 create_fixed_operand (&ops[1], mem);
7668 create_integer_operand (&ops[2], model);
7669 if (maybe_expand_insn (icode, 3, ops))
7670 return ops[0].value;
7673 /* If the size of the object is greater than word size on this target,
7674 then we assume that a load will not be atomic. */
7675 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
7677 /* Issue val = compare_and_swap (mem, 0, 0).
7678 This may cause the occasional harmless store of 0 when the value is
7679 already 0, but it seems to be OK according to the standards guys. */
7680 if (expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
7681 const0_rtx, false, model, model))
7682 return target;
7683 else
7684 /* Otherwise there is no atomic load, leave the library call. */
7685 return NULL_RTX;
7688 /* Otherwise assume loads are atomic, and emit the proper barriers. */
7689 if (!target || target == const0_rtx)
7690 target = gen_reg_rtx (mode);
7692 /* For SEQ_CST, emit a barrier before the load. */
7693 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST)
7694 expand_mem_thread_fence (model);
7696 emit_move_insn (target, mem);
7698 /* Emit the appropriate barrier after the load. */
7699 expand_mem_thread_fence (model);
7701 return target;
7704 /* This function expands the atomic store operation:
7705 Atomically store VAL in MEM.
7706 MEMMODEL is the memory model variant to use.
7707 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
7708 function returns const0_rtx if a pattern was emitted. */
7711 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
7713 machine_mode mode = GET_MODE (mem);
7714 enum insn_code icode;
7715 struct expand_operand ops[3];
7717 /* If the target supports the store directly, great. */
7718 icode = direct_optab_handler (atomic_store_optab, mode);
7719 if (icode != CODE_FOR_nothing)
7721 create_fixed_operand (&ops[0], mem);
7722 create_input_operand (&ops[1], val, mode);
7723 create_integer_operand (&ops[2], model);
7724 if (maybe_expand_insn (icode, 3, ops))
7725 return const0_rtx;
7728 /* If using __sync_lock_release is a viable alternative, try it. */
7729 if (use_release)
7731 icode = direct_optab_handler (sync_lock_release_optab, mode);
7732 if (icode != CODE_FOR_nothing)
7734 create_fixed_operand (&ops[0], mem);
7735 create_input_operand (&ops[1], const0_rtx, mode);
7736 if (maybe_expand_insn (icode, 2, ops))
7738 /* lock_release is only a release barrier. */
7739 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST)
7740 expand_mem_thread_fence (model);
7741 return const0_rtx;
7746 /* If the size of the object is greater than word size on this target,
7747 a default store will not be atomic, Try a mem_exchange and throw away
7748 the result. If that doesn't work, don't do anything. */
7749 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
7751 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
7752 if (!target)
7753 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val);
7754 if (target)
7755 return const0_rtx;
7756 else
7757 return NULL_RTX;
7760 /* Otherwise assume stores are atomic, and emit the proper barriers. */
7761 expand_mem_thread_fence (model);
7763 emit_move_insn (mem, val);
7765 /* For SEQ_CST, also emit a barrier after the store. */
7766 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST)
7767 expand_mem_thread_fence (model);
7769 return const0_rtx;
7773 /* Structure containing the pointers and values required to process the
7774 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
7776 struct atomic_op_functions
7778 direct_optab mem_fetch_before;
7779 direct_optab mem_fetch_after;
7780 direct_optab mem_no_result;
7781 optab fetch_before;
7782 optab fetch_after;
7783 direct_optab no_result;
7784 enum rtx_code reverse_code;
7788 /* Fill in structure pointed to by OP with the various optab entries for an
7789 operation of type CODE. */
7791 static void
7792 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
7794 gcc_assert (op!= NULL);
7796 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
7797 in the source code during compilation, and the optab entries are not
7798 computable until runtime. Fill in the values at runtime. */
7799 switch (code)
7801 case PLUS:
7802 op->mem_fetch_before = atomic_fetch_add_optab;
7803 op->mem_fetch_after = atomic_add_fetch_optab;
7804 op->mem_no_result = atomic_add_optab;
7805 op->fetch_before = sync_old_add_optab;
7806 op->fetch_after = sync_new_add_optab;
7807 op->no_result = sync_add_optab;
7808 op->reverse_code = MINUS;
7809 break;
7810 case MINUS:
7811 op->mem_fetch_before = atomic_fetch_sub_optab;
7812 op->mem_fetch_after = atomic_sub_fetch_optab;
7813 op->mem_no_result = atomic_sub_optab;
7814 op->fetch_before = sync_old_sub_optab;
7815 op->fetch_after = sync_new_sub_optab;
7816 op->no_result = sync_sub_optab;
7817 op->reverse_code = PLUS;
7818 break;
7819 case XOR:
7820 op->mem_fetch_before = atomic_fetch_xor_optab;
7821 op->mem_fetch_after = atomic_xor_fetch_optab;
7822 op->mem_no_result = atomic_xor_optab;
7823 op->fetch_before = sync_old_xor_optab;
7824 op->fetch_after = sync_new_xor_optab;
7825 op->no_result = sync_xor_optab;
7826 op->reverse_code = XOR;
7827 break;
7828 case AND:
7829 op->mem_fetch_before = atomic_fetch_and_optab;
7830 op->mem_fetch_after = atomic_and_fetch_optab;
7831 op->mem_no_result = atomic_and_optab;
7832 op->fetch_before = sync_old_and_optab;
7833 op->fetch_after = sync_new_and_optab;
7834 op->no_result = sync_and_optab;
7835 op->reverse_code = UNKNOWN;
7836 break;
7837 case IOR:
7838 op->mem_fetch_before = atomic_fetch_or_optab;
7839 op->mem_fetch_after = atomic_or_fetch_optab;
7840 op->mem_no_result = atomic_or_optab;
7841 op->fetch_before = sync_old_ior_optab;
7842 op->fetch_after = sync_new_ior_optab;
7843 op->no_result = sync_ior_optab;
7844 op->reverse_code = UNKNOWN;
7845 break;
7846 case NOT:
7847 op->mem_fetch_before = atomic_fetch_nand_optab;
7848 op->mem_fetch_after = atomic_nand_fetch_optab;
7849 op->mem_no_result = atomic_nand_optab;
7850 op->fetch_before = sync_old_nand_optab;
7851 op->fetch_after = sync_new_nand_optab;
7852 op->no_result = sync_nand_optab;
7853 op->reverse_code = UNKNOWN;
7854 break;
7855 default:
7856 gcc_unreachable ();
7860 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
7861 using memory order MODEL. If AFTER is true the operation needs to return
7862 the value of *MEM after the operation, otherwise the previous value.
7863 TARGET is an optional place to place the result. The result is unused if
7864 it is const0_rtx.
7865 Return the result if there is a better sequence, otherwise NULL_RTX. */
7867 static rtx
7868 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
7869 enum memmodel model, bool after)
7871 /* If the value is prefetched, or not used, it may be possible to replace
7872 the sequence with a native exchange operation. */
7873 if (!after || target == const0_rtx)
7875 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
7876 if (code == AND && val == const0_rtx)
7878 if (target == const0_rtx)
7879 target = gen_reg_rtx (GET_MODE (mem));
7880 return maybe_emit_atomic_exchange (target, mem, val, model);
7883 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
7884 if (code == IOR && val == constm1_rtx)
7886 if (target == const0_rtx)
7887 target = gen_reg_rtx (GET_MODE (mem));
7888 return maybe_emit_atomic_exchange (target, mem, val, model);
7892 return NULL_RTX;
7895 /* Try to emit an instruction for a specific operation varaition.
7896 OPTAB contains the OP functions.
7897 TARGET is an optional place to return the result. const0_rtx means unused.
7898 MEM is the memory location to operate on.
7899 VAL is the value to use in the operation.
7900 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
7901 MODEL is the memory model, if used.
7902 AFTER is true if the returned result is the value after the operation. */
7904 static rtx
7905 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
7906 rtx val, bool use_memmodel, enum memmodel model, bool after)
7908 machine_mode mode = GET_MODE (mem);
7909 struct expand_operand ops[4];
7910 enum insn_code icode;
7911 int op_counter = 0;
7912 int num_ops;
7914 /* Check to see if there is a result returned. */
7915 if (target == const0_rtx)
7917 if (use_memmodel)
7919 icode = direct_optab_handler (optab->mem_no_result, mode);
7920 create_integer_operand (&ops[2], model);
7921 num_ops = 3;
7923 else
7925 icode = direct_optab_handler (optab->no_result, mode);
7926 num_ops = 2;
7929 /* Otherwise, we need to generate a result. */
7930 else
7932 if (use_memmodel)
7934 icode = direct_optab_handler (after ? optab->mem_fetch_after
7935 : optab->mem_fetch_before, mode);
7936 create_integer_operand (&ops[3], model);
7937 num_ops = 4;
7939 else
7941 icode = optab_handler (after ? optab->fetch_after
7942 : optab->fetch_before, mode);
7943 num_ops = 3;
7945 create_output_operand (&ops[op_counter++], target, mode);
7947 if (icode == CODE_FOR_nothing)
7948 return NULL_RTX;
7950 create_fixed_operand (&ops[op_counter++], mem);
7951 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7952 create_convert_operand_to (&ops[op_counter++], val, mode, true);
7954 if (maybe_expand_insn (icode, num_ops, ops))
7955 return (target == const0_rtx ? const0_rtx : ops[0].value);
7957 return NULL_RTX;
7961 /* This function expands an atomic fetch_OP or OP_fetch operation:
7962 TARGET is an option place to stick the return value. const0_rtx indicates
7963 the result is unused.
7964 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7965 CODE is the operation being performed (OP)
7966 MEMMODEL is the memory model variant to use.
7967 AFTER is true to return the result of the operation (OP_fetch).
7968 AFTER is false to return the value before the operation (fetch_OP).
7970 This function will *only* generate instructions if there is a direct
7971 optab. No compare and swap loops or libcalls will be generated. */
7973 static rtx
7974 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
7975 enum rtx_code code, enum memmodel model,
7976 bool after)
7978 machine_mode mode = GET_MODE (mem);
7979 struct atomic_op_functions optab;
7980 rtx result;
7981 bool unused_result = (target == const0_rtx);
7983 get_atomic_op_for_code (&optab, code);
7985 /* Check to see if there are any better instructions. */
7986 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
7987 if (result)
7988 return result;
7990 /* Check for the case where the result isn't used and try those patterns. */
7991 if (unused_result)
7993 /* Try the memory model variant first. */
7994 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
7995 if (result)
7996 return result;
7998 /* Next try the old style withuot a memory model. */
7999 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
8000 if (result)
8001 return result;
8003 /* There is no no-result pattern, so try patterns with a result. */
8004 target = NULL_RTX;
8007 /* Try the __atomic version. */
8008 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
8009 if (result)
8010 return result;
8012 /* Try the older __sync version. */
8013 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
8014 if (result)
8015 return result;
8017 /* If the fetch value can be calculated from the other variation of fetch,
8018 try that operation. */
8019 if (after || unused_result || optab.reverse_code != UNKNOWN)
8021 /* Try the __atomic version, then the older __sync version. */
8022 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
8023 if (!result)
8024 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
8026 if (result)
8028 /* If the result isn't used, no need to do compensation code. */
8029 if (unused_result)
8030 return result;
8032 /* Issue compensation code. Fetch_after == fetch_before OP val.
8033 Fetch_before == after REVERSE_OP val. */
8034 if (!after)
8035 code = optab.reverse_code;
8036 if (code == NOT)
8038 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
8039 true, OPTAB_LIB_WIDEN);
8040 result = expand_simple_unop (mode, NOT, result, target, true);
8042 else
8043 result = expand_simple_binop (mode, code, result, val, target,
8044 true, OPTAB_LIB_WIDEN);
8045 return result;
8049 /* No direct opcode can be generated. */
8050 return NULL_RTX;
8055 /* This function expands an atomic fetch_OP or OP_fetch operation:
8056 TARGET is an option place to stick the return value. const0_rtx indicates
8057 the result is unused.
8058 atomically fetch MEM, perform the operation with VAL and return it to MEM.
8059 CODE is the operation being performed (OP)
8060 MEMMODEL is the memory model variant to use.
8061 AFTER is true to return the result of the operation (OP_fetch).
8062 AFTER is false to return the value before the operation (fetch_OP). */
8064 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
8065 enum memmodel model, bool after)
8067 machine_mode mode = GET_MODE (mem);
8068 rtx result;
8069 bool unused_result = (target == const0_rtx);
8071 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
8072 after);
8074 if (result)
8075 return result;
8077 /* Add/sub can be implemented by doing the reverse operation with -(val). */
8078 if (code == PLUS || code == MINUS)
8080 rtx tmp;
8081 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
8083 start_sequence ();
8084 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
8085 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
8086 model, after);
8087 if (result)
8089 /* PLUS worked so emit the insns and return. */
8090 tmp = get_insns ();
8091 end_sequence ();
8092 emit_insn (tmp);
8093 return result;
8096 /* PLUS did not work, so throw away the negation code and continue. */
8097 end_sequence ();
8100 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
8101 if (!can_compare_and_swap_p (mode, false))
8103 rtx libfunc;
8104 bool fixup = false;
8105 enum rtx_code orig_code = code;
8106 struct atomic_op_functions optab;
8108 get_atomic_op_for_code (&optab, code);
8109 libfunc = optab_libfunc (after ? optab.fetch_after
8110 : optab.fetch_before, mode);
8111 if (libfunc == NULL
8112 && (after || unused_result || optab.reverse_code != UNKNOWN))
8114 fixup = true;
8115 if (!after)
8116 code = optab.reverse_code;
8117 libfunc = optab_libfunc (after ? optab.fetch_before
8118 : optab.fetch_after, mode);
8120 if (libfunc != NULL)
8122 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
8123 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
8124 2, addr, ptr_mode, val, mode);
8126 if (!unused_result && fixup)
8127 result = expand_simple_binop (mode, code, result, val, target,
8128 true, OPTAB_LIB_WIDEN);
8129 return result;
8132 /* We need the original code for any further attempts. */
8133 code = orig_code;
8136 /* If nothing else has succeeded, default to a compare and swap loop. */
8137 if (can_compare_and_swap_p (mode, true))
8139 rtx_insn *insn;
8140 rtx t0 = gen_reg_rtx (mode), t1;
8142 start_sequence ();
8144 /* If the result is used, get a register for it. */
8145 if (!unused_result)
8147 if (!target || !register_operand (target, mode))
8148 target = gen_reg_rtx (mode);
8149 /* If fetch_before, copy the value now. */
8150 if (!after)
8151 emit_move_insn (target, t0);
8153 else
8154 target = const0_rtx;
8156 t1 = t0;
8157 if (code == NOT)
8159 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
8160 true, OPTAB_LIB_WIDEN);
8161 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
8163 else
8164 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
8165 OPTAB_LIB_WIDEN);
8167 /* For after, copy the value now. */
8168 if (!unused_result && after)
8169 emit_move_insn (target, t1);
8170 insn = get_insns ();
8171 end_sequence ();
8173 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
8174 return target;
8177 return NULL_RTX;
8180 /* Return true if OPERAND is suitable for operand number OPNO of
8181 instruction ICODE. */
8183 bool
8184 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
8186 return (!insn_data[(int) icode].operand[opno].predicate
8187 || (insn_data[(int) icode].operand[opno].predicate
8188 (operand, insn_data[(int) icode].operand[opno].mode)));
8191 /* TARGET is a target of a multiword operation that we are going to
8192 implement as a series of word-mode operations. Return true if
8193 TARGET is suitable for this purpose. */
8195 bool
8196 valid_multiword_target_p (rtx target)
8198 machine_mode mode;
8199 int i;
8201 mode = GET_MODE (target);
8202 for (i = 0; i < GET_MODE_SIZE (mode); i += UNITS_PER_WORD)
8203 if (!validate_subreg (word_mode, mode, target, i))
8204 return false;
8205 return true;
8208 /* Like maybe_legitimize_operand, but do not change the code of the
8209 current rtx value. */
8211 static bool
8212 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
8213 struct expand_operand *op)
8215 /* See if the operand matches in its current form. */
8216 if (insn_operand_matches (icode, opno, op->value))
8217 return true;
8219 /* If the operand is a memory whose address has no side effects,
8220 try forcing the address into a non-virtual pseudo register.
8221 The check for side effects is important because copy_to_mode_reg
8222 cannot handle things like auto-modified addresses. */
8223 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
8225 rtx addr, mem;
8227 mem = op->value;
8228 addr = XEXP (mem, 0);
8229 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
8230 && !side_effects_p (addr))
8232 rtx_insn *last;
8233 machine_mode mode;
8235 last = get_last_insn ();
8236 mode = get_address_mode (mem);
8237 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
8238 if (insn_operand_matches (icode, opno, mem))
8240 op->value = mem;
8241 return true;
8243 delete_insns_since (last);
8247 return false;
8250 /* Try to make OP match operand OPNO of instruction ICODE. Return true
8251 on success, storing the new operand value back in OP. */
8253 static bool
8254 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
8255 struct expand_operand *op)
8257 machine_mode mode, imode;
8258 bool old_volatile_ok, result;
8260 mode = op->mode;
8261 switch (op->type)
8263 case EXPAND_FIXED:
8264 old_volatile_ok = volatile_ok;
8265 volatile_ok = true;
8266 result = maybe_legitimize_operand_same_code (icode, opno, op);
8267 volatile_ok = old_volatile_ok;
8268 return result;
8270 case EXPAND_OUTPUT:
8271 gcc_assert (mode != VOIDmode);
8272 if (op->value
8273 && op->value != const0_rtx
8274 && GET_MODE (op->value) == mode
8275 && maybe_legitimize_operand_same_code (icode, opno, op))
8276 return true;
8278 op->value = gen_reg_rtx (mode);
8279 break;
8281 case EXPAND_INPUT:
8282 input:
8283 gcc_assert (mode != VOIDmode);
8284 gcc_assert (GET_MODE (op->value) == VOIDmode
8285 || GET_MODE (op->value) == mode);
8286 if (maybe_legitimize_operand_same_code (icode, opno, op))
8287 return true;
8289 op->value = copy_to_mode_reg (mode, op->value);
8290 break;
8292 case EXPAND_CONVERT_TO:
8293 gcc_assert (mode != VOIDmode);
8294 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
8295 goto input;
8297 case EXPAND_CONVERT_FROM:
8298 if (GET_MODE (op->value) != VOIDmode)
8299 mode = GET_MODE (op->value);
8300 else
8301 /* The caller must tell us what mode this value has. */
8302 gcc_assert (mode != VOIDmode);
8304 imode = insn_data[(int) icode].operand[opno].mode;
8305 if (imode != VOIDmode && imode != mode)
8307 op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
8308 mode = imode;
8310 goto input;
8312 case EXPAND_ADDRESS:
8313 gcc_assert (mode != VOIDmode);
8314 op->value = convert_memory_address (mode, op->value);
8315 goto input;
8317 case EXPAND_INTEGER:
8318 mode = insn_data[(int) icode].operand[opno].mode;
8319 if (mode != VOIDmode && const_int_operand (op->value, mode))
8320 goto input;
8321 break;
8323 return insn_operand_matches (icode, opno, op->value);
8326 /* Make OP describe an input operand that should have the same value
8327 as VALUE, after any mode conversion that the target might request.
8328 TYPE is the type of VALUE. */
8330 void
8331 create_convert_operand_from_type (struct expand_operand *op,
8332 rtx value, tree type)
8334 create_convert_operand_from (op, value, TYPE_MODE (type),
8335 TYPE_UNSIGNED (type));
8338 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
8339 of instruction ICODE. Return true on success, leaving the new operand
8340 values in the OPS themselves. Emit no code on failure. */
8342 bool
8343 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
8344 unsigned int nops, struct expand_operand *ops)
8346 rtx_insn *last;
8347 unsigned int i;
8349 last = get_last_insn ();
8350 for (i = 0; i < nops; i++)
8351 if (!maybe_legitimize_operand (icode, opno + i, &ops[i]))
8353 delete_insns_since (last);
8354 return false;
8356 return true;
8359 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
8360 as its operands. Return the instruction pattern on success,
8361 and emit any necessary set-up code. Return null and emit no
8362 code on failure. */
8365 maybe_gen_insn (enum insn_code icode, unsigned int nops,
8366 struct expand_operand *ops)
8368 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
8369 if (!maybe_legitimize_operands (icode, 0, nops, ops))
8370 return NULL_RTX;
8372 switch (nops)
8374 case 1:
8375 return GEN_FCN (icode) (ops[0].value);
8376 case 2:
8377 return GEN_FCN (icode) (ops[0].value, ops[1].value);
8378 case 3:
8379 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
8380 case 4:
8381 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8382 ops[3].value);
8383 case 5:
8384 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8385 ops[3].value, ops[4].value);
8386 case 6:
8387 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8388 ops[3].value, ops[4].value, ops[5].value);
8389 case 7:
8390 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8391 ops[3].value, ops[4].value, ops[5].value,
8392 ops[6].value);
8393 case 8:
8394 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8395 ops[3].value, ops[4].value, ops[5].value,
8396 ops[6].value, ops[7].value);
8397 case 9:
8398 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8399 ops[3].value, ops[4].value, ops[5].value,
8400 ops[6].value, ops[7].value, ops[8].value);
8402 gcc_unreachable ();
8405 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
8406 as its operands. Return true on success and emit no code on failure. */
8408 bool
8409 maybe_expand_insn (enum insn_code icode, unsigned int nops,
8410 struct expand_operand *ops)
8412 rtx pat = maybe_gen_insn (icode, nops, ops);
8413 if (pat)
8415 emit_insn (pat);
8416 return true;
8418 return false;
8421 /* Like maybe_expand_insn, but for jumps. */
8423 bool
8424 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
8425 struct expand_operand *ops)
8427 rtx pat = maybe_gen_insn (icode, nops, ops);
8428 if (pat)
8430 emit_jump_insn (pat);
8431 return true;
8433 return false;
8436 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
8437 as its operands. */
8439 void
8440 expand_insn (enum insn_code icode, unsigned int nops,
8441 struct expand_operand *ops)
8443 if (!maybe_expand_insn (icode, nops, ops))
8444 gcc_unreachable ();
8447 /* Like expand_insn, but for jumps. */
8449 void
8450 expand_jump_insn (enum insn_code icode, unsigned int nops,
8451 struct expand_operand *ops)
8453 if (!maybe_expand_jump_insn (icode, nops, ops))
8454 gcc_unreachable ();
8457 /* Reduce conditional compilation elsewhere. */
8458 #ifndef HAVE_insv
8459 #define HAVE_insv 0
8460 #define CODE_FOR_insv CODE_FOR_nothing
8461 #endif
8462 #ifndef HAVE_extv
8463 #define HAVE_extv 0
8464 #define CODE_FOR_extv CODE_FOR_nothing
8465 #endif
8466 #ifndef HAVE_extzv
8467 #define HAVE_extzv 0
8468 #define CODE_FOR_extzv CODE_FOR_nothing
8469 #endif
8471 /* Enumerates the possible types of structure operand to an
8472 extraction_insn. */
8473 enum extraction_type { ET_unaligned_mem, ET_reg };
8475 /* Check whether insv, extv or extzv pattern ICODE can be used for an
8476 insertion or extraction of type TYPE on a structure of mode MODE.
8477 Return true if so and fill in *INSN accordingly. STRUCT_OP is the
8478 operand number of the structure (the first sign_extract or zero_extract
8479 operand) and FIELD_OP is the operand number of the field (the other
8480 side of the set from the sign_extract or zero_extract). */
8482 static bool
8483 get_traditional_extraction_insn (extraction_insn *insn,
8484 enum extraction_type type,
8485 machine_mode mode,
8486 enum insn_code icode,
8487 int struct_op, int field_op)
8489 const struct insn_data_d *data = &insn_data[icode];
8491 machine_mode struct_mode = data->operand[struct_op].mode;
8492 if (struct_mode == VOIDmode)
8493 struct_mode = word_mode;
8494 if (mode != struct_mode)
8495 return false;
8497 machine_mode field_mode = data->operand[field_op].mode;
8498 if (field_mode == VOIDmode)
8499 field_mode = word_mode;
8501 machine_mode pos_mode = data->operand[struct_op + 2].mode;
8502 if (pos_mode == VOIDmode)
8503 pos_mode = word_mode;
8505 insn->icode = icode;
8506 insn->field_mode = field_mode;
8507 insn->struct_mode = (type == ET_unaligned_mem ? byte_mode : struct_mode);
8508 insn->pos_mode = pos_mode;
8509 return true;
8512 /* Return true if an optab exists to perform an insertion or extraction
8513 of type TYPE in mode MODE. Describe the instruction in *INSN if so.
8515 REG_OPTAB is the optab to use for register structures and
8516 MISALIGN_OPTAB is the optab to use for misaligned memory structures.
8517 POS_OP is the operand number of the bit position. */
8519 static bool
8520 get_optab_extraction_insn (struct extraction_insn *insn,
8521 enum extraction_type type,
8522 machine_mode mode, direct_optab reg_optab,
8523 direct_optab misalign_optab, int pos_op)
8525 direct_optab optab = (type == ET_unaligned_mem ? misalign_optab : reg_optab);
8526 enum insn_code icode = direct_optab_handler (optab, mode);
8527 if (icode == CODE_FOR_nothing)
8528 return false;
8530 const struct insn_data_d *data = &insn_data[icode];
8532 insn->icode = icode;
8533 insn->field_mode = mode;
8534 insn->struct_mode = (type == ET_unaligned_mem ? BLKmode : mode);
8535 insn->pos_mode = data->operand[pos_op].mode;
8536 if (insn->pos_mode == VOIDmode)
8537 insn->pos_mode = word_mode;
8538 return true;
8541 /* Return true if an instruction exists to perform an insertion or
8542 extraction (PATTERN says which) of type TYPE in mode MODE.
8543 Describe the instruction in *INSN if so. */
8545 static bool
8546 get_extraction_insn (extraction_insn *insn,
8547 enum extraction_pattern pattern,
8548 enum extraction_type type,
8549 machine_mode mode)
8551 switch (pattern)
8553 case EP_insv:
8554 if (HAVE_insv
8555 && get_traditional_extraction_insn (insn, type, mode,
8556 CODE_FOR_insv, 0, 3))
8557 return true;
8558 return get_optab_extraction_insn (insn, type, mode, insv_optab,
8559 insvmisalign_optab, 2);
8561 case EP_extv:
8562 if (HAVE_extv
8563 && get_traditional_extraction_insn (insn, type, mode,
8564 CODE_FOR_extv, 1, 0))
8565 return true;
8566 return get_optab_extraction_insn (insn, type, mode, extv_optab,
8567 extvmisalign_optab, 3);
8569 case EP_extzv:
8570 if (HAVE_extzv
8571 && get_traditional_extraction_insn (insn, type, mode,
8572 CODE_FOR_extzv, 1, 0))
8573 return true;
8574 return get_optab_extraction_insn (insn, type, mode, extzv_optab,
8575 extzvmisalign_optab, 3);
8577 default:
8578 gcc_unreachable ();
8582 /* Return true if an instruction exists to access a field of mode
8583 FIELDMODE in a structure that has STRUCT_BITS significant bits.
8584 Describe the "best" such instruction in *INSN if so. PATTERN and
8585 TYPE describe the type of insertion or extraction we want to perform.
8587 For an insertion, the number of significant structure bits includes
8588 all bits of the target. For an extraction, it need only include the
8589 most significant bit of the field. Larger widths are acceptable
8590 in both cases. */
8592 static bool
8593 get_best_extraction_insn (extraction_insn *insn,
8594 enum extraction_pattern pattern,
8595 enum extraction_type type,
8596 unsigned HOST_WIDE_INT struct_bits,
8597 machine_mode field_mode)
8599 machine_mode mode = smallest_mode_for_size (struct_bits, MODE_INT);
8600 while (mode != VOIDmode)
8602 if (get_extraction_insn (insn, pattern, type, mode))
8604 while (mode != VOIDmode
8605 && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (field_mode)
8606 && !TRULY_NOOP_TRUNCATION_MODES_P (insn->field_mode,
8607 field_mode))
8609 get_extraction_insn (insn, pattern, type, mode);
8610 mode = GET_MODE_WIDER_MODE (mode);
8612 return true;
8614 mode = GET_MODE_WIDER_MODE (mode);
8616 return false;
8619 /* Return true if an instruction exists to access a field of mode
8620 FIELDMODE in a register structure that has STRUCT_BITS significant bits.
8621 Describe the "best" such instruction in *INSN if so. PATTERN describes
8622 the type of insertion or extraction we want to perform.
8624 For an insertion, the number of significant structure bits includes
8625 all bits of the target. For an extraction, it need only include the
8626 most significant bit of the field. Larger widths are acceptable
8627 in both cases. */
8629 bool
8630 get_best_reg_extraction_insn (extraction_insn *insn,
8631 enum extraction_pattern pattern,
8632 unsigned HOST_WIDE_INT struct_bits,
8633 machine_mode field_mode)
8635 return get_best_extraction_insn (insn, pattern, ET_reg, struct_bits,
8636 field_mode);
8639 /* Return true if an instruction exists to access a field of BITSIZE
8640 bits starting BITNUM bits into a memory structure. Describe the
8641 "best" such instruction in *INSN if so. PATTERN describes the type
8642 of insertion or extraction we want to perform and FIELDMODE is the
8643 natural mode of the extracted field.
8645 The instructions considered here only access bytes that overlap
8646 the bitfield; they do not touch any surrounding bytes. */
8648 bool
8649 get_best_mem_extraction_insn (extraction_insn *insn,
8650 enum extraction_pattern pattern,
8651 HOST_WIDE_INT bitsize, HOST_WIDE_INT bitnum,
8652 machine_mode field_mode)
8654 unsigned HOST_WIDE_INT struct_bits = (bitnum % BITS_PER_UNIT
8655 + bitsize
8656 + BITS_PER_UNIT - 1);
8657 struct_bits -= struct_bits % BITS_PER_UNIT;
8658 return get_best_extraction_insn (insn, pattern, ET_unaligned_mem,
8659 struct_bits, field_mode);
8662 /* Determine whether "1 << x" is relatively cheap in word_mode. */
8664 bool
8665 lshift_cheap_p (bool speed_p)
8667 /* FIXME: This should be made target dependent via this "this_target"
8668 mechanism, similar to e.g. can_copy_init_p in gcse.c. */
8669 static bool init[2] = { false, false };
8670 static bool cheap[2] = { true, true };
8672 /* If the targer has no lshift in word_mode, the operation will most
8673 probably not be cheap. ??? Does GCC even work for such targets? */
8674 if (optab_handler (ashl_optab, word_mode) == CODE_FOR_nothing)
8675 return false;
8677 if (!init[speed_p])
8679 rtx reg = gen_raw_REG (word_mode, 10000);
8680 int cost = set_src_cost (gen_rtx_ASHIFT (word_mode, const1_rtx, reg),
8681 speed_p);
8682 cheap[speed_p] = cost < COSTS_N_INSNS (3);
8683 init[speed_p] = true;
8686 return cheap[speed_p];
8689 #include "gt-optabs.h"