Mark ChangeLog
[official-gcc.git] / gcc / optabs.c
blobdbf83076f2ba04815dfaa154c9324c6de1fccca1
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2013 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 "tree.h"
32 #include "tm_p.h"
33 #include "flags.h"
34 #include "function.h"
35 #include "except.h"
36 #include "expr.h"
37 #include "optabs.h"
38 #include "libfuncs.h"
39 #include "recog.h"
40 #include "reload.h"
41 #include "ggc.h"
42 #include "basic-block.h"
43 #include "target.h"
45 struct target_optabs default_target_optabs;
46 struct target_libfuncs default_target_libfuncs;
47 struct target_optabs *this_fn_optabs = &default_target_optabs;
48 #if SWITCHABLE_TARGET
49 struct target_optabs *this_target_optabs = &default_target_optabs;
50 struct target_libfuncs *this_target_libfuncs = &default_target_libfuncs;
51 #endif
53 #define libfunc_hash \
54 (this_target_libfuncs->x_libfunc_hash)
56 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
57 enum machine_mode *);
58 static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
59 static void emit_libcall_block_1 (rtx, rtx, rtx, rtx, bool);
61 /* Debug facility for use in GDB. */
62 void debug_optab_libfuncs (void);
64 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
65 #if ENABLE_DECIMAL_BID_FORMAT
66 #define DECIMAL_PREFIX "bid_"
67 #else
68 #define DECIMAL_PREFIX "dpd_"
69 #endif
71 /* Used for libfunc_hash. */
73 static hashval_t
74 hash_libfunc (const void *p)
76 const struct libfunc_entry *const e = (const struct libfunc_entry *) p;
77 return ((e->mode1 + e->mode2 * NUM_MACHINE_MODES) ^ e->op);
80 /* Used for libfunc_hash. */
82 static int
83 eq_libfunc (const void *p, const void *q)
85 const struct libfunc_entry *const e1 = (const struct libfunc_entry *) p;
86 const struct libfunc_entry *const e2 = (const struct libfunc_entry *) q;
87 return e1->op == e2->op && e1->mode1 == e2->mode1 && e1->mode2 == e2->mode2;
90 /* Return libfunc corresponding operation defined by OPTAB converting
91 from MODE2 to MODE1. Trigger lazy initialization if needed, return NULL
92 if no libfunc is available. */
93 rtx
94 convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
95 enum machine_mode mode2)
97 struct libfunc_entry e;
98 struct libfunc_entry **slot;
100 /* ??? This ought to be an assert, but not all of the places
101 that we expand optabs know about the optabs that got moved
102 to being direct. */
103 if (!(optab >= FIRST_CONV_OPTAB && optab <= LAST_CONVLIB_OPTAB))
104 return NULL_RTX;
106 e.op = optab;
107 e.mode1 = mode1;
108 e.mode2 = mode2;
109 slot = (struct libfunc_entry **)
110 htab_find_slot (libfunc_hash, &e, NO_INSERT);
111 if (!slot)
113 const struct convert_optab_libcall_d *d
114 = &convlib_def[optab - FIRST_CONV_OPTAB];
116 if (d->libcall_gen == NULL)
117 return NULL;
119 d->libcall_gen (optab, d->libcall_basename, mode1, mode2);
120 slot = (struct libfunc_entry **)
121 htab_find_slot (libfunc_hash, &e, NO_INSERT);
122 if (!slot)
123 return NULL;
125 return (*slot)->libfunc;
128 /* Return libfunc corresponding operation defined by OPTAB in MODE.
129 Trigger lazy initialization if needed, return NULL if no libfunc is
130 available. */
132 optab_libfunc (optab optab, enum machine_mode mode)
134 struct libfunc_entry e;
135 struct libfunc_entry **slot;
137 /* ??? This ought to be an assert, but not all of the places
138 that we expand optabs know about the optabs that got moved
139 to being direct. */
140 if (!(optab >= FIRST_NORM_OPTAB && optab <= LAST_NORMLIB_OPTAB))
141 return NULL_RTX;
143 e.op = optab;
144 e.mode1 = mode;
145 e.mode2 = VOIDmode;
146 slot = (struct libfunc_entry **)
147 htab_find_slot (libfunc_hash, &e, NO_INSERT);
148 if (!slot)
150 const struct optab_libcall_d *d
151 = &normlib_def[optab - FIRST_NORM_OPTAB];
153 if (d->libcall_gen == NULL)
154 return NULL;
156 d->libcall_gen (optab, d->libcall_basename, d->libcall_suffix, mode);
157 slot = (struct libfunc_entry **)
158 htab_find_slot (libfunc_hash, &e, NO_INSERT);
159 if (!slot)
160 return NULL;
162 return (*slot)->libfunc;
166 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
167 the result of operation CODE applied to OP0 (and OP1 if it is a binary
168 operation).
170 If the last insn does not set TARGET, don't do anything, but return 1.
172 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
173 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
174 try again, ensuring that TARGET is not one of the operands. */
176 static int
177 add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
179 rtx last_insn, set;
180 rtx note;
182 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
184 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
185 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
186 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
187 && GET_RTX_CLASS (code) != RTX_COMPARE
188 && GET_RTX_CLASS (code) != RTX_UNARY)
189 return 1;
191 if (GET_CODE (target) == ZERO_EXTRACT)
192 return 1;
194 for (last_insn = insns;
195 NEXT_INSN (last_insn) != NULL_RTX;
196 last_insn = NEXT_INSN (last_insn))
199 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
200 a value changing in the insn, so the note would be invalid for CSE. */
201 if (reg_overlap_mentioned_p (target, op0)
202 || (op1 && reg_overlap_mentioned_p (target, op1)))
204 if (MEM_P (target)
205 && (rtx_equal_p (target, op0)
206 || (op1 && rtx_equal_p (target, op1))))
208 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
209 over expanding it as temp = MEM op X, MEM = temp. If the target
210 supports MEM = MEM op X instructions, it is sometimes too hard
211 to reconstruct that form later, especially if X is also a memory,
212 and due to multiple occurrences of addresses the address might
213 be forced into register unnecessarily.
214 Note that not emitting the REG_EQUIV note might inhibit
215 CSE in some cases. */
216 set = single_set (last_insn);
217 if (set
218 && GET_CODE (SET_SRC (set)) == code
219 && MEM_P (SET_DEST (set))
220 && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
221 || (op1 && rtx_equal_p (SET_DEST (set),
222 XEXP (SET_SRC (set), 1)))))
223 return 1;
225 return 0;
228 set = single_set (last_insn);
229 if (set == NULL_RTX)
230 return 1;
232 if (! rtx_equal_p (SET_DEST (set), target)
233 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
234 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
235 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
236 return 1;
238 if (GET_RTX_CLASS (code) == RTX_UNARY)
239 switch (code)
241 case FFS:
242 case CLZ:
243 case CTZ:
244 case CLRSB:
245 case POPCOUNT:
246 case PARITY:
247 case BSWAP:
248 if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
250 note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
251 if (GET_MODE_SIZE (GET_MODE (op0))
252 > GET_MODE_SIZE (GET_MODE (target)))
253 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
254 note, GET_MODE (op0));
255 else
256 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
257 note, GET_MODE (op0));
258 break;
260 /* FALLTHRU */
261 default:
262 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
263 break;
265 else
266 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
268 set_unique_reg_note (last_insn, REG_EQUAL, note);
270 return 1;
273 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
274 for a widening operation would be. In most cases this would be OP0, but if
275 that's a constant it'll be VOIDmode, which isn't useful. */
277 static enum machine_mode
278 widened_mode (enum machine_mode to_mode, rtx op0, rtx op1)
280 enum machine_mode m0 = GET_MODE (op0);
281 enum machine_mode m1 = GET_MODE (op1);
282 enum machine_mode result;
284 if (m0 == VOIDmode && m1 == VOIDmode)
285 return to_mode;
286 else if (m0 == VOIDmode || GET_MODE_SIZE (m0) < GET_MODE_SIZE (m1))
287 result = m1;
288 else
289 result = m0;
291 if (GET_MODE_SIZE (result) > GET_MODE_SIZE (to_mode))
292 return to_mode;
294 return result;
297 /* Find a widening optab even if it doesn't widen as much as we want.
298 E.g. if from_mode is HImode, and to_mode is DImode, and there is no
299 direct HI->SI insn, then return SI->DI, if that exists.
300 If PERMIT_NON_WIDENING is non-zero then this can be used with
301 non-widening optabs also. */
303 enum insn_code
304 find_widening_optab_handler_and_mode (optab op, enum machine_mode to_mode,
305 enum machine_mode from_mode,
306 int permit_non_widening,
307 enum machine_mode *found_mode)
309 for (; (permit_non_widening || from_mode != to_mode)
310 && GET_MODE_SIZE (from_mode) <= GET_MODE_SIZE (to_mode)
311 && from_mode != VOIDmode;
312 from_mode = GET_MODE_WIDER_MODE (from_mode))
314 enum insn_code handler = widening_optab_handler (op, to_mode,
315 from_mode);
317 if (handler != CODE_FOR_nothing)
319 if (found_mode)
320 *found_mode = from_mode;
321 return handler;
325 return CODE_FOR_nothing;
328 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
329 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
330 not actually do a sign-extend or zero-extend, but can leave the
331 higher-order bits of the result rtx undefined, for example, in the case
332 of logical operations, but not right shifts. */
334 static rtx
335 widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
336 int unsignedp, int no_extend)
338 rtx result;
340 /* If we don't have to extend and this is a constant, return it. */
341 if (no_extend && GET_MODE (op) == VOIDmode)
342 return op;
344 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
345 extend since it will be more efficient to do so unless the signedness of
346 a promoted object differs from our extension. */
347 if (! no_extend
348 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
349 && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
350 return convert_modes (mode, oldmode, op, unsignedp);
352 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
353 SUBREG. */
354 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
355 return gen_lowpart (mode, force_reg (GET_MODE (op), op));
357 /* Otherwise, get an object of MODE, clobber it, and set the low-order
358 part to OP. */
360 result = gen_reg_rtx (mode);
361 emit_clobber (result);
362 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
363 return result;
366 /* Return the optab used for computing the operation given by the tree code,
367 CODE and the tree EXP. This function is not always usable (for example, it
368 cannot give complete results for multiplication or division) but probably
369 ought to be relied on more widely throughout the expander. */
370 optab
371 optab_for_tree_code (enum tree_code code, const_tree type,
372 enum optab_subtype subtype)
374 bool trapv;
375 switch (code)
377 case BIT_AND_EXPR:
378 return and_optab;
380 case BIT_IOR_EXPR:
381 return ior_optab;
383 case BIT_NOT_EXPR:
384 return one_cmpl_optab;
386 case BIT_XOR_EXPR:
387 return xor_optab;
389 case MULT_HIGHPART_EXPR:
390 return TYPE_UNSIGNED (type) ? umul_highpart_optab : smul_highpart_optab;
392 case TRUNC_MOD_EXPR:
393 case CEIL_MOD_EXPR:
394 case FLOOR_MOD_EXPR:
395 case ROUND_MOD_EXPR:
396 return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
398 case RDIV_EXPR:
399 case TRUNC_DIV_EXPR:
400 case CEIL_DIV_EXPR:
401 case FLOOR_DIV_EXPR:
402 case ROUND_DIV_EXPR:
403 case EXACT_DIV_EXPR:
404 if (TYPE_SATURATING(type))
405 return TYPE_UNSIGNED(type) ? usdiv_optab : ssdiv_optab;
406 return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
408 case LSHIFT_EXPR:
409 if (TREE_CODE (type) == VECTOR_TYPE)
411 if (subtype == optab_vector)
412 return TYPE_SATURATING (type) ? unknown_optab : vashl_optab;
414 gcc_assert (subtype == optab_scalar);
416 if (TYPE_SATURATING(type))
417 return TYPE_UNSIGNED(type) ? usashl_optab : ssashl_optab;
418 return ashl_optab;
420 case RSHIFT_EXPR:
421 if (TREE_CODE (type) == VECTOR_TYPE)
423 if (subtype == optab_vector)
424 return TYPE_UNSIGNED (type) ? vlshr_optab : vashr_optab;
426 gcc_assert (subtype == optab_scalar);
428 return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
430 case LROTATE_EXPR:
431 if (TREE_CODE (type) == VECTOR_TYPE)
433 if (subtype == optab_vector)
434 return vrotl_optab;
436 gcc_assert (subtype == optab_scalar);
438 return rotl_optab;
440 case RROTATE_EXPR:
441 if (TREE_CODE (type) == VECTOR_TYPE)
443 if (subtype == optab_vector)
444 return vrotr_optab;
446 gcc_assert (subtype == optab_scalar);
448 return rotr_optab;
450 case MAX_EXPR:
451 return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
453 case MIN_EXPR:
454 return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
456 case REALIGN_LOAD_EXPR:
457 return vec_realign_load_optab;
459 case WIDEN_SUM_EXPR:
460 return TYPE_UNSIGNED (type) ? usum_widen_optab : ssum_widen_optab;
462 case DOT_PROD_EXPR:
463 return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
465 case WIDEN_MULT_PLUS_EXPR:
466 return (TYPE_UNSIGNED (type)
467 ? (TYPE_SATURATING (type)
468 ? usmadd_widen_optab : umadd_widen_optab)
469 : (TYPE_SATURATING (type)
470 ? ssmadd_widen_optab : smadd_widen_optab));
472 case WIDEN_MULT_MINUS_EXPR:
473 return (TYPE_UNSIGNED (type)
474 ? (TYPE_SATURATING (type)
475 ? usmsub_widen_optab : umsub_widen_optab)
476 : (TYPE_SATURATING (type)
477 ? ssmsub_widen_optab : smsub_widen_optab));
479 case FMA_EXPR:
480 return fma_optab;
482 case REDUC_MAX_EXPR:
483 return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab;
485 case REDUC_MIN_EXPR:
486 return TYPE_UNSIGNED (type) ? reduc_umin_optab : reduc_smin_optab;
488 case REDUC_PLUS_EXPR:
489 return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
491 case VEC_LSHIFT_EXPR:
492 return vec_shl_optab;
494 case VEC_RSHIFT_EXPR:
495 return vec_shr_optab;
497 case VEC_WIDEN_MULT_HI_EXPR:
498 return TYPE_UNSIGNED (type) ?
499 vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
501 case VEC_WIDEN_MULT_LO_EXPR:
502 return TYPE_UNSIGNED (type) ?
503 vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
505 case VEC_WIDEN_MULT_EVEN_EXPR:
506 return TYPE_UNSIGNED (type) ?
507 vec_widen_umult_even_optab : vec_widen_smult_even_optab;
509 case VEC_WIDEN_MULT_ODD_EXPR:
510 return TYPE_UNSIGNED (type) ?
511 vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
513 case VEC_WIDEN_LSHIFT_HI_EXPR:
514 return TYPE_UNSIGNED (type) ?
515 vec_widen_ushiftl_hi_optab : vec_widen_sshiftl_hi_optab;
517 case VEC_WIDEN_LSHIFT_LO_EXPR:
518 return TYPE_UNSIGNED (type) ?
519 vec_widen_ushiftl_lo_optab : vec_widen_sshiftl_lo_optab;
521 case VEC_UNPACK_HI_EXPR:
522 return TYPE_UNSIGNED (type) ?
523 vec_unpacku_hi_optab : vec_unpacks_hi_optab;
525 case VEC_UNPACK_LO_EXPR:
526 return TYPE_UNSIGNED (type) ?
527 vec_unpacku_lo_optab : vec_unpacks_lo_optab;
529 case VEC_UNPACK_FLOAT_HI_EXPR:
530 /* The signedness is determined from input operand. */
531 return TYPE_UNSIGNED (type) ?
532 vec_unpacku_float_hi_optab : vec_unpacks_float_hi_optab;
534 case VEC_UNPACK_FLOAT_LO_EXPR:
535 /* The signedness is determined from input operand. */
536 return TYPE_UNSIGNED (type) ?
537 vec_unpacku_float_lo_optab : vec_unpacks_float_lo_optab;
539 case VEC_PACK_TRUNC_EXPR:
540 return vec_pack_trunc_optab;
542 case VEC_PACK_SAT_EXPR:
543 return TYPE_UNSIGNED (type) ? vec_pack_usat_optab : vec_pack_ssat_optab;
545 case VEC_PACK_FIX_TRUNC_EXPR:
546 /* The signedness is determined from output operand. */
547 return TYPE_UNSIGNED (type) ?
548 vec_pack_ufix_trunc_optab : vec_pack_sfix_trunc_optab;
550 default:
551 break;
554 trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
555 switch (code)
557 case POINTER_PLUS_EXPR:
558 case PLUS_EXPR:
559 if (TYPE_SATURATING(type))
560 return TYPE_UNSIGNED(type) ? usadd_optab : ssadd_optab;
561 return trapv ? addv_optab : add_optab;
563 case MINUS_EXPR:
564 if (TYPE_SATURATING(type))
565 return TYPE_UNSIGNED(type) ? ussub_optab : sssub_optab;
566 return trapv ? subv_optab : sub_optab;
568 case MULT_EXPR:
569 if (TYPE_SATURATING(type))
570 return TYPE_UNSIGNED(type) ? usmul_optab : ssmul_optab;
571 return trapv ? smulv_optab : smul_optab;
573 case NEGATE_EXPR:
574 if (TYPE_SATURATING(type))
575 return TYPE_UNSIGNED(type) ? usneg_optab : ssneg_optab;
576 return trapv ? negv_optab : neg_optab;
578 case ABS_EXPR:
579 return trapv ? absv_optab : abs_optab;
581 default:
582 return unknown_optab;
587 /* Expand vector widening operations.
589 There are two different classes of operations handled here:
590 1) Operations whose result is wider than all the arguments to the operation.
591 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
592 In this case OP0 and optionally OP1 would be initialized,
593 but WIDE_OP wouldn't (not relevant for this case).
594 2) Operations whose result is of the same size as the last argument to the
595 operation, but wider than all the other arguments to the operation.
596 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
597 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
599 E.g, when called to expand the following operations, this is how
600 the arguments will be initialized:
601 nops OP0 OP1 WIDE_OP
602 widening-sum 2 oprnd0 - oprnd1
603 widening-dot-product 3 oprnd0 oprnd1 oprnd2
604 widening-mult 2 oprnd0 oprnd1 -
605 type-promotion (vec-unpack) 1 oprnd0 - - */
608 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
609 rtx target, int unsignedp)
611 struct expand_operand eops[4];
612 tree oprnd0, oprnd1, oprnd2;
613 enum machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
614 optab widen_pattern_optab;
615 enum insn_code icode;
616 int nops = TREE_CODE_LENGTH (ops->code);
617 int op;
619 oprnd0 = ops->op0;
620 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
621 widen_pattern_optab =
622 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
623 if (ops->code == WIDEN_MULT_PLUS_EXPR
624 || ops->code == WIDEN_MULT_MINUS_EXPR)
625 icode = find_widening_optab_handler (widen_pattern_optab,
626 TYPE_MODE (TREE_TYPE (ops->op2)),
627 tmode0, 0);
628 else
629 icode = optab_handler (widen_pattern_optab, tmode0);
630 gcc_assert (icode != CODE_FOR_nothing);
632 if (nops >= 2)
634 oprnd1 = ops->op1;
635 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
638 /* The last operand is of a wider mode than the rest of the operands. */
639 if (nops == 2)
640 wmode = tmode1;
641 else if (nops == 3)
643 gcc_assert (tmode1 == tmode0);
644 gcc_assert (op1);
645 oprnd2 = ops->op2;
646 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
649 op = 0;
650 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
651 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
652 if (op1)
653 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
654 if (wide_op)
655 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
656 expand_insn (icode, op, eops);
657 return eops[0].value;
660 /* Generate code to perform an operation specified by TERNARY_OPTAB
661 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
663 UNSIGNEDP is for the case where we have to widen the operands
664 to perform the operation. It says to use zero-extension.
666 If TARGET is nonzero, the value
667 is generated there, if it is convenient to do so.
668 In all cases an rtx is returned for the locus of the value;
669 this may or may not be TARGET. */
672 expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
673 rtx op1, rtx op2, rtx target, int unsignedp)
675 struct expand_operand ops[4];
676 enum insn_code icode = optab_handler (ternary_optab, mode);
678 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
680 create_output_operand (&ops[0], target, mode);
681 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
682 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
683 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
684 expand_insn (icode, 4, ops);
685 return ops[0].value;
689 /* Like expand_binop, but return a constant rtx if the result can be
690 calculated at compile time. The arguments and return value are
691 otherwise the same as for expand_binop. */
694 simplify_expand_binop (enum machine_mode mode, optab binoptab,
695 rtx op0, rtx op1, rtx target, int unsignedp,
696 enum optab_methods methods)
698 if (CONSTANT_P (op0) && CONSTANT_P (op1))
700 rtx x = simplify_binary_operation (optab_to_code (binoptab),
701 mode, op0, op1);
702 if (x)
703 return x;
706 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
709 /* Like simplify_expand_binop, but always put the result in TARGET.
710 Return true if the expansion succeeded. */
712 bool
713 force_expand_binop (enum machine_mode mode, optab binoptab,
714 rtx op0, rtx op1, rtx target, int unsignedp,
715 enum optab_methods methods)
717 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
718 target, unsignedp, methods);
719 if (x == 0)
720 return false;
721 if (x != target)
722 emit_move_insn (target, x);
723 return true;
726 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */
729 expand_vec_shift_expr (sepops ops, rtx target)
731 struct expand_operand eops[3];
732 enum insn_code icode;
733 rtx rtx_op1, rtx_op2;
734 enum machine_mode mode = TYPE_MODE (ops->type);
735 tree vec_oprnd = ops->op0;
736 tree shift_oprnd = ops->op1;
737 optab shift_optab;
739 switch (ops->code)
741 case VEC_RSHIFT_EXPR:
742 shift_optab = vec_shr_optab;
743 break;
744 case VEC_LSHIFT_EXPR:
745 shift_optab = vec_shl_optab;
746 break;
747 default:
748 gcc_unreachable ();
751 icode = optab_handler (shift_optab, mode);
752 gcc_assert (icode != CODE_FOR_nothing);
754 rtx_op1 = expand_normal (vec_oprnd);
755 rtx_op2 = expand_normal (shift_oprnd);
757 create_output_operand (&eops[0], target, mode);
758 create_input_operand (&eops[1], rtx_op1, GET_MODE (rtx_op1));
759 create_convert_operand_from_type (&eops[2], rtx_op2, TREE_TYPE (shift_oprnd));
760 expand_insn (icode, 3, eops);
762 return eops[0].value;
765 /* Create a new vector value in VMODE with all elements set to OP. The
766 mode of OP must be the element mode of VMODE. If OP is a constant,
767 then the return value will be a constant. */
769 static rtx
770 expand_vector_broadcast (enum machine_mode vmode, rtx op)
772 enum insn_code icode;
773 rtvec vec;
774 rtx ret;
775 int i, n;
777 gcc_checking_assert (VECTOR_MODE_P (vmode));
779 n = GET_MODE_NUNITS (vmode);
780 vec = rtvec_alloc (n);
781 for (i = 0; i < n; ++i)
782 RTVEC_ELT (vec, i) = op;
784 if (CONSTANT_P (op))
785 return gen_rtx_CONST_VECTOR (vmode, vec);
787 /* ??? If the target doesn't have a vec_init, then we have no easy way
788 of performing this operation. Most of this sort of generic support
789 is hidden away in the vector lowering support in gimple. */
790 icode = optab_handler (vec_init_optab, vmode);
791 if (icode == CODE_FOR_nothing)
792 return NULL;
794 ret = gen_reg_rtx (vmode);
795 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
797 return ret;
800 /* This subroutine of expand_doubleword_shift handles the cases in which
801 the effective shift value is >= BITS_PER_WORD. The arguments and return
802 value are the same as for the parent routine, except that SUPERWORD_OP1
803 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
804 INTO_TARGET may be null if the caller has decided to calculate it. */
806 static bool
807 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
808 rtx outof_target, rtx into_target,
809 int unsignedp, enum optab_methods methods)
811 if (into_target != 0)
812 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
813 into_target, unsignedp, methods))
814 return false;
816 if (outof_target != 0)
818 /* For a signed right shift, we must fill OUTOF_TARGET with copies
819 of the sign bit, otherwise we must fill it with zeros. */
820 if (binoptab != ashr_optab)
821 emit_move_insn (outof_target, CONST0_RTX (word_mode));
822 else
823 if (!force_expand_binop (word_mode, binoptab,
824 outof_input, GEN_INT (BITS_PER_WORD - 1),
825 outof_target, unsignedp, methods))
826 return false;
828 return true;
831 /* This subroutine of expand_doubleword_shift handles the cases in which
832 the effective shift value is < BITS_PER_WORD. The arguments and return
833 value are the same as for the parent routine. */
835 static bool
836 expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
837 rtx outof_input, rtx into_input, rtx op1,
838 rtx outof_target, rtx into_target,
839 int unsignedp, enum optab_methods methods,
840 unsigned HOST_WIDE_INT shift_mask)
842 optab reverse_unsigned_shift, unsigned_shift;
843 rtx tmp, carries;
845 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
846 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
848 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
849 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
850 the opposite direction to BINOPTAB. */
851 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
853 carries = outof_input;
854 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
855 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
856 0, true, methods);
858 else
860 /* We must avoid shifting by BITS_PER_WORD bits since that is either
861 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
862 has unknown behavior. Do a single shift first, then shift by the
863 remainder. It's OK to use ~OP1 as the remainder if shift counts
864 are truncated to the mode size. */
865 carries = expand_binop (word_mode, reverse_unsigned_shift,
866 outof_input, const1_rtx, 0, unsignedp, methods);
867 if (shift_mask == BITS_PER_WORD - 1)
869 tmp = immed_double_const (-1, -1, op1_mode);
870 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
871 0, true, methods);
873 else
875 tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
876 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
877 0, true, methods);
880 if (tmp == 0 || carries == 0)
881 return false;
882 carries = expand_binop (word_mode, reverse_unsigned_shift,
883 carries, tmp, 0, unsignedp, methods);
884 if (carries == 0)
885 return false;
887 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
888 so the result can go directly into INTO_TARGET if convenient. */
889 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
890 into_target, unsignedp, methods);
891 if (tmp == 0)
892 return false;
894 /* Now OR in the bits carried over from OUTOF_INPUT. */
895 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
896 into_target, unsignedp, methods))
897 return false;
899 /* Use a standard word_mode shift for the out-of half. */
900 if (outof_target != 0)
901 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
902 outof_target, unsignedp, methods))
903 return false;
905 return true;
909 #ifdef HAVE_conditional_move
910 /* Try implementing expand_doubleword_shift using conditional moves.
911 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
912 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
913 are the shift counts to use in the former and latter case. All other
914 arguments are the same as the parent routine. */
916 static bool
917 expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
918 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
919 rtx outof_input, rtx into_input,
920 rtx subword_op1, rtx superword_op1,
921 rtx outof_target, rtx into_target,
922 int unsignedp, enum optab_methods methods,
923 unsigned HOST_WIDE_INT shift_mask)
925 rtx outof_superword, into_superword;
927 /* Put the superword version of the output into OUTOF_SUPERWORD and
928 INTO_SUPERWORD. */
929 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
930 if (outof_target != 0 && subword_op1 == superword_op1)
932 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
933 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
934 into_superword = outof_target;
935 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
936 outof_superword, 0, unsignedp, methods))
937 return false;
939 else
941 into_superword = gen_reg_rtx (word_mode);
942 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
943 outof_superword, into_superword,
944 unsignedp, methods))
945 return false;
948 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
949 if (!expand_subword_shift (op1_mode, binoptab,
950 outof_input, into_input, subword_op1,
951 outof_target, into_target,
952 unsignedp, methods, shift_mask))
953 return false;
955 /* Select between them. Do the INTO half first because INTO_SUPERWORD
956 might be the current value of OUTOF_TARGET. */
957 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
958 into_target, into_superword, word_mode, false))
959 return false;
961 if (outof_target != 0)
962 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
963 outof_target, outof_superword,
964 word_mode, false))
965 return false;
967 return true;
969 #endif
971 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
972 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
973 input operand; the shift moves bits in the direction OUTOF_INPUT->
974 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
975 of the target. OP1 is the shift count and OP1_MODE is its mode.
976 If OP1 is constant, it will have been truncated as appropriate
977 and is known to be nonzero.
979 If SHIFT_MASK is zero, the result of word shifts is undefined when the
980 shift count is outside the range [0, BITS_PER_WORD). This routine must
981 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
983 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
984 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
985 fill with zeros or sign bits as appropriate.
987 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
988 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
989 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
990 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
991 are undefined.
993 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
994 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
995 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
996 function wants to calculate it itself.
998 Return true if the shift could be successfully synthesized. */
1000 static bool
1001 expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
1002 rtx outof_input, rtx into_input, rtx op1,
1003 rtx outof_target, rtx into_target,
1004 int unsignedp, enum optab_methods methods,
1005 unsigned HOST_WIDE_INT shift_mask)
1007 rtx superword_op1, tmp, cmp1, cmp2;
1008 rtx subword_label, done_label;
1009 enum rtx_code cmp_code;
1011 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
1012 fill the result with sign or zero bits as appropriate. If so, the value
1013 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
1014 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
1015 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
1017 This isn't worthwhile for constant shifts since the optimizers will
1018 cope better with in-range shift counts. */
1019 if (shift_mask >= BITS_PER_WORD
1020 && outof_target != 0
1021 && !CONSTANT_P (op1))
1023 if (!expand_doubleword_shift (op1_mode, binoptab,
1024 outof_input, into_input, op1,
1025 0, into_target,
1026 unsignedp, methods, shift_mask))
1027 return false;
1028 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
1029 outof_target, unsignedp, methods))
1030 return false;
1031 return true;
1034 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
1035 is true when the effective shift value is less than BITS_PER_WORD.
1036 Set SUPERWORD_OP1 to the shift count that should be used to shift
1037 OUTOF_INPUT into INTO_TARGET when the condition is false. */
1038 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
1039 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
1041 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
1042 is a subword shift count. */
1043 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
1044 0, true, methods);
1045 cmp2 = CONST0_RTX (op1_mode);
1046 cmp_code = EQ;
1047 superword_op1 = op1;
1049 else
1051 /* Set CMP1 to OP1 - BITS_PER_WORD. */
1052 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
1053 0, true, methods);
1054 cmp2 = CONST0_RTX (op1_mode);
1055 cmp_code = LT;
1056 superword_op1 = cmp1;
1058 if (cmp1 == 0)
1059 return false;
1061 /* If we can compute the condition at compile time, pick the
1062 appropriate subroutine. */
1063 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
1064 if (tmp != 0 && CONST_INT_P (tmp))
1066 if (tmp == const0_rtx)
1067 return expand_superword_shift (binoptab, outof_input, superword_op1,
1068 outof_target, into_target,
1069 unsignedp, methods);
1070 else
1071 return expand_subword_shift (op1_mode, binoptab,
1072 outof_input, into_input, op1,
1073 outof_target, into_target,
1074 unsignedp, methods, shift_mask);
1077 #ifdef HAVE_conditional_move
1078 /* Try using conditional moves to generate straight-line code. */
1080 rtx start = get_last_insn ();
1081 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
1082 cmp_code, cmp1, cmp2,
1083 outof_input, into_input,
1084 op1, superword_op1,
1085 outof_target, into_target,
1086 unsignedp, methods, shift_mask))
1087 return true;
1088 delete_insns_since (start);
1090 #endif
1092 /* As a last resort, use branches to select the correct alternative. */
1093 subword_label = gen_label_rtx ();
1094 done_label = gen_label_rtx ();
1096 NO_DEFER_POP;
1097 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
1098 0, 0, subword_label, -1);
1099 OK_DEFER_POP;
1101 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
1102 outof_target, into_target,
1103 unsignedp, methods))
1104 return false;
1106 emit_jump_insn (gen_jump (done_label));
1107 emit_barrier ();
1108 emit_label (subword_label);
1110 if (!expand_subword_shift (op1_mode, binoptab,
1111 outof_input, into_input, op1,
1112 outof_target, into_target,
1113 unsignedp, methods, shift_mask))
1114 return false;
1116 emit_label (done_label);
1117 return true;
1120 /* Subroutine of expand_binop. Perform a double word multiplication of
1121 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1122 as the target's word_mode. This function return NULL_RTX if anything
1123 goes wrong, in which case it may have already emitted instructions
1124 which need to be deleted.
1126 If we want to multiply two two-word values and have normal and widening
1127 multiplies of single-word values, we can do this with three smaller
1128 multiplications.
1130 The multiplication proceeds as follows:
1131 _______________________
1132 [__op0_high_|__op0_low__]
1133 _______________________
1134 * [__op1_high_|__op1_low__]
1135 _______________________________________________
1136 _______________________
1137 (1) [__op0_low__*__op1_low__]
1138 _______________________
1139 (2a) [__op0_low__*__op1_high_]
1140 _______________________
1141 (2b) [__op0_high_*__op1_low__]
1142 _______________________
1143 (3) [__op0_high_*__op1_high_]
1146 This gives a 4-word result. Since we are only interested in the
1147 lower 2 words, partial result (3) and the upper words of (2a) and
1148 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1149 calculated using non-widening multiplication.
1151 (1), however, needs to be calculated with an unsigned widening
1152 multiplication. If this operation is not directly supported we
1153 try using a signed widening multiplication and adjust the result.
1154 This adjustment works as follows:
1156 If both operands are positive then no adjustment is needed.
1158 If the operands have different signs, for example op0_low < 0 and
1159 op1_low >= 0, the instruction treats the most significant bit of
1160 op0_low as a sign bit instead of a bit with significance
1161 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1162 with 2**BITS_PER_WORD - op0_low, and two's complements the
1163 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1164 the result.
1166 Similarly, if both operands are negative, we need to add
1167 (op0_low + op1_low) * 2**BITS_PER_WORD.
1169 We use a trick to adjust quickly. We logically shift op0_low right
1170 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1171 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1172 logical shift exists, we do an arithmetic right shift and subtract
1173 the 0 or -1. */
1175 static rtx
1176 expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
1177 bool umulp, enum optab_methods methods)
1179 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1180 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1181 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
1182 rtx product, adjust, product_high, temp;
1184 rtx op0_high = operand_subword_force (op0, high, mode);
1185 rtx op0_low = operand_subword_force (op0, low, mode);
1186 rtx op1_high = operand_subword_force (op1, high, mode);
1187 rtx op1_low = operand_subword_force (op1, low, mode);
1189 /* If we're using an unsigned multiply to directly compute the product
1190 of the low-order words of the operands and perform any required
1191 adjustments of the operands, we begin by trying two more multiplications
1192 and then computing the appropriate sum.
1194 We have checked above that the required addition is provided.
1195 Full-word addition will normally always succeed, especially if
1196 it is provided at all, so we don't worry about its failure. The
1197 multiplication may well fail, however, so we do handle that. */
1199 if (!umulp)
1201 /* ??? This could be done with emit_store_flag where available. */
1202 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1203 NULL_RTX, 1, methods);
1204 if (temp)
1205 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
1206 NULL_RTX, 0, OPTAB_DIRECT);
1207 else
1209 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1210 NULL_RTX, 0, methods);
1211 if (!temp)
1212 return NULL_RTX;
1213 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
1214 NULL_RTX, 0, OPTAB_DIRECT);
1217 if (!op0_high)
1218 return NULL_RTX;
1221 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
1222 NULL_RTX, 0, OPTAB_DIRECT);
1223 if (!adjust)
1224 return NULL_RTX;
1226 /* OP0_HIGH should now be dead. */
1228 if (!umulp)
1230 /* ??? This could be done with emit_store_flag where available. */
1231 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1232 NULL_RTX, 1, methods);
1233 if (temp)
1234 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
1235 NULL_RTX, 0, OPTAB_DIRECT);
1236 else
1238 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1239 NULL_RTX, 0, methods);
1240 if (!temp)
1241 return NULL_RTX;
1242 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
1243 NULL_RTX, 0, OPTAB_DIRECT);
1246 if (!op1_high)
1247 return NULL_RTX;
1250 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
1251 NULL_RTX, 0, OPTAB_DIRECT);
1252 if (!temp)
1253 return NULL_RTX;
1255 /* OP1_HIGH should now be dead. */
1257 adjust = expand_binop (word_mode, add_optab, adjust, temp,
1258 NULL_RTX, 0, OPTAB_DIRECT);
1260 if (target && !REG_P (target))
1261 target = NULL_RTX;
1263 if (umulp)
1264 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1265 target, 1, OPTAB_DIRECT);
1266 else
1267 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1268 target, 1, OPTAB_DIRECT);
1270 if (!product)
1271 return NULL_RTX;
1273 product_high = operand_subword (product, high, 1, mode);
1274 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
1275 NULL_RTX, 0, OPTAB_DIRECT);
1276 emit_move_insn (product_high, adjust);
1277 return product;
1280 /* Wrapper around expand_binop which takes an rtx code to specify
1281 the operation to perform, not an optab pointer. All other
1282 arguments are the same. */
1284 expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
1285 rtx op1, rtx target, int unsignedp,
1286 enum optab_methods methods)
1288 optab binop = code_to_optab (code);
1289 gcc_assert (binop);
1291 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1294 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1295 binop. Order them according to commutative_operand_precedence and, if
1296 possible, try to put TARGET or a pseudo first. */
1297 static bool
1298 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1300 int op0_prec = commutative_operand_precedence (op0);
1301 int op1_prec = commutative_operand_precedence (op1);
1303 if (op0_prec < op1_prec)
1304 return true;
1306 if (op0_prec > op1_prec)
1307 return false;
1309 /* With equal precedence, both orders are ok, but it is better if the
1310 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1311 if (target == 0 || REG_P (target))
1312 return (REG_P (op1) && !REG_P (op0)) || target == op1;
1313 else
1314 return rtx_equal_p (op1, target);
1317 /* Return true if BINOPTAB implements a shift operation. */
1319 static bool
1320 shift_optab_p (optab binoptab)
1322 switch (optab_to_code (binoptab))
1324 case ASHIFT:
1325 case SS_ASHIFT:
1326 case US_ASHIFT:
1327 case ASHIFTRT:
1328 case LSHIFTRT:
1329 case ROTATE:
1330 case ROTATERT:
1331 return true;
1333 default:
1334 return false;
1338 /* Return true if BINOPTAB implements a commutative binary operation. */
1340 static bool
1341 commutative_optab_p (optab binoptab)
1343 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
1344 || binoptab == smul_widen_optab
1345 || binoptab == umul_widen_optab
1346 || binoptab == smul_highpart_optab
1347 || binoptab == umul_highpart_optab);
1350 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
1351 optimizing, and if the operand is a constant that costs more than
1352 1 instruction, force the constant into a register and return that
1353 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1355 static rtx
1356 avoid_expensive_constant (enum machine_mode mode, optab binoptab,
1357 int opn, rtx x, bool unsignedp)
1359 bool speed = optimize_insn_for_speed_p ();
1361 if (mode != VOIDmode
1362 && optimize
1363 && CONSTANT_P (x)
1364 && (rtx_cost (x, optab_to_code (binoptab), opn, speed)
1365 > set_src_cost (x, speed)))
1367 if (CONST_INT_P (x))
1369 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
1370 if (intval != INTVAL (x))
1371 x = GEN_INT (intval);
1373 else
1374 x = convert_modes (mode, VOIDmode, x, unsignedp);
1375 x = force_reg (mode, x);
1377 return x;
1380 /* Helper function for expand_binop: handle the case where there
1381 is an insn that directly implements the indicated operation.
1382 Returns null if this is not possible. */
1383 static rtx
1384 expand_binop_directly (enum machine_mode mode, optab binoptab,
1385 rtx op0, rtx op1,
1386 rtx target, int unsignedp, enum optab_methods methods,
1387 rtx last)
1389 enum machine_mode from_mode = widened_mode (mode, op0, op1);
1390 enum insn_code icode = find_widening_optab_handler (binoptab, mode,
1391 from_mode, 1);
1392 enum machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
1393 enum machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
1394 enum machine_mode mode0, mode1, tmp_mode;
1395 struct expand_operand ops[3];
1396 bool commutative_p;
1397 rtx pat;
1398 rtx xop0 = op0, xop1 = op1;
1399 rtx swap;
1401 /* If it is a commutative operator and the modes would match
1402 if we would swap the operands, we can save the conversions. */
1403 commutative_p = commutative_optab_p (binoptab);
1404 if (commutative_p
1405 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1406 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode1)
1408 swap = xop0;
1409 xop0 = xop1;
1410 xop1 = swap;
1413 /* If we are optimizing, force expensive constants into a register. */
1414 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1415 if (!shift_optab_p (binoptab))
1416 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1418 /* In case the insn wants input operands in modes different from
1419 those of the actual operands, convert the operands. It would
1420 seem that we don't need to convert CONST_INTs, but we do, so
1421 that they're properly zero-extended, sign-extended or truncated
1422 for their mode. */
1424 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1425 if (xmode0 != VOIDmode && xmode0 != mode0)
1427 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1428 mode0 = xmode0;
1431 mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
1432 if (xmode1 != VOIDmode && xmode1 != mode1)
1434 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1435 mode1 = xmode1;
1438 /* If operation is commutative,
1439 try to make the first operand a register.
1440 Even better, try to make it the same as the target.
1441 Also try to make the last operand a constant. */
1442 if (commutative_p
1443 && swap_commutative_operands_with_target (target, xop0, xop1))
1445 swap = xop1;
1446 xop1 = xop0;
1447 xop0 = swap;
1450 /* Now, if insn's predicates don't allow our operands, put them into
1451 pseudo regs. */
1453 if (binoptab == vec_pack_trunc_optab
1454 || binoptab == vec_pack_usat_optab
1455 || binoptab == vec_pack_ssat_optab
1456 || binoptab == vec_pack_ufix_trunc_optab
1457 || binoptab == vec_pack_sfix_trunc_optab)
1459 /* The mode of the result is different then the mode of the
1460 arguments. */
1461 tmp_mode = insn_data[(int) icode].operand[0].mode;
1462 if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1464 delete_insns_since (last);
1465 return NULL_RTX;
1468 else
1469 tmp_mode = mode;
1471 create_output_operand (&ops[0], target, tmp_mode);
1472 create_input_operand (&ops[1], xop0, mode0);
1473 create_input_operand (&ops[2], xop1, mode1);
1474 pat = maybe_gen_insn (icode, 3, ops);
1475 if (pat)
1477 /* If PAT is composed of more than one insn, try to add an appropriate
1478 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1479 operand, call expand_binop again, this time without a target. */
1480 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1481 && ! add_equal_note (pat, ops[0].value, optab_to_code (binoptab),
1482 ops[1].value, ops[2].value))
1484 delete_insns_since (last);
1485 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1486 unsignedp, methods);
1489 emit_insn (pat);
1490 return ops[0].value;
1492 delete_insns_since (last);
1493 return NULL_RTX;
1496 /* Generate code to perform an operation specified by BINOPTAB
1497 on operands OP0 and OP1, with result having machine-mode MODE.
1499 UNSIGNEDP is for the case where we have to widen the operands
1500 to perform the operation. It says to use zero-extension.
1502 If TARGET is nonzero, the value
1503 is generated there, if it is convenient to do so.
1504 In all cases an rtx is returned for the locus of the value;
1505 this may or may not be TARGET. */
1508 expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
1509 rtx target, int unsignedp, enum optab_methods methods)
1511 enum optab_methods next_methods
1512 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1513 ? OPTAB_WIDEN : methods);
1514 enum mode_class mclass;
1515 enum machine_mode wider_mode;
1516 rtx libfunc;
1517 rtx temp;
1518 rtx entry_last = get_last_insn ();
1519 rtx last;
1521 mclass = GET_MODE_CLASS (mode);
1523 /* If subtracting an integer constant, convert this into an addition of
1524 the negated constant. */
1526 if (binoptab == sub_optab && CONST_INT_P (op1))
1528 op1 = negate_rtx (mode, op1);
1529 binoptab = add_optab;
1532 /* Record where to delete back to if we backtrack. */
1533 last = get_last_insn ();
1535 /* If we can do it with a three-operand insn, do so. */
1537 if (methods != OPTAB_MUST_WIDEN
1538 && find_widening_optab_handler (binoptab, mode,
1539 widened_mode (mode, op0, op1), 1)
1540 != CODE_FOR_nothing)
1542 temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1543 unsignedp, methods, last);
1544 if (temp)
1545 return temp;
1548 /* If we were trying to rotate, and that didn't work, try rotating
1549 the other direction before falling back to shifts and bitwise-or. */
1550 if (((binoptab == rotl_optab
1551 && optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
1552 || (binoptab == rotr_optab
1553 && optab_handler (rotl_optab, mode) != CODE_FOR_nothing))
1554 && mclass == MODE_INT)
1556 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1557 rtx newop1;
1558 unsigned int bits = GET_MODE_PRECISION (mode);
1560 if (CONST_INT_P (op1))
1561 newop1 = GEN_INT (bits - INTVAL (op1));
1562 else if (targetm.shift_truncation_mask (mode) == bits - 1)
1563 newop1 = negate_rtx (GET_MODE (op1), op1);
1564 else
1565 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1566 GEN_INT (bits), op1,
1567 NULL_RTX, unsignedp, OPTAB_DIRECT);
1569 temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1570 target, unsignedp, methods, last);
1571 if (temp)
1572 return temp;
1575 /* If this is a multiply, see if we can do a widening operation that
1576 takes operands of this mode and makes a wider mode. */
1578 if (binoptab == smul_optab
1579 && GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1580 && (widening_optab_handler ((unsignedp ? umul_widen_optab
1581 : smul_widen_optab),
1582 GET_MODE_2XWIDER_MODE (mode), mode)
1583 != CODE_FOR_nothing))
1585 temp = expand_binop (GET_MODE_2XWIDER_MODE (mode),
1586 unsignedp ? umul_widen_optab : smul_widen_optab,
1587 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1589 if (temp != 0)
1591 if (GET_MODE_CLASS (mode) == MODE_INT
1592 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1593 return gen_lowpart (mode, temp);
1594 else
1595 return convert_to_mode (mode, temp, unsignedp);
1599 /* If this is a vector shift by a scalar, see if we can do a vector
1600 shift by a vector. If so, broadcast the scalar into a vector. */
1601 if (mclass == MODE_VECTOR_INT)
1603 optab otheroptab = unknown_optab;
1605 if (binoptab == ashl_optab)
1606 otheroptab = vashl_optab;
1607 else if (binoptab == ashr_optab)
1608 otheroptab = vashr_optab;
1609 else if (binoptab == lshr_optab)
1610 otheroptab = vlshr_optab;
1611 else if (binoptab == rotl_optab)
1612 otheroptab = vrotl_optab;
1613 else if (binoptab == rotr_optab)
1614 otheroptab = vrotr_optab;
1616 if (otheroptab && optab_handler (otheroptab, mode) != CODE_FOR_nothing)
1618 rtx vop1 = expand_vector_broadcast (mode, op1);
1619 if (vop1)
1621 temp = expand_binop_directly (mode, otheroptab, op0, vop1,
1622 target, unsignedp, methods, last);
1623 if (temp)
1624 return temp;
1629 /* Look for a wider mode of the same class for which we think we
1630 can open-code the operation. Check for a widening multiply at the
1631 wider mode as well. */
1633 if (CLASS_HAS_WIDER_MODES_P (mclass)
1634 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1635 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1636 wider_mode != VOIDmode;
1637 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1639 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1640 || (binoptab == smul_optab
1641 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1642 && (find_widening_optab_handler ((unsignedp
1643 ? umul_widen_optab
1644 : smul_widen_optab),
1645 GET_MODE_WIDER_MODE (wider_mode),
1646 mode, 0)
1647 != CODE_FOR_nothing)))
1649 rtx xop0 = op0, xop1 = op1;
1650 int no_extend = 0;
1652 /* For certain integer operations, we need not actually extend
1653 the narrow operands, as long as we will truncate
1654 the results to the same narrowness. */
1656 if ((binoptab == ior_optab || binoptab == and_optab
1657 || binoptab == xor_optab
1658 || binoptab == add_optab || binoptab == sub_optab
1659 || binoptab == smul_optab || binoptab == ashl_optab)
1660 && mclass == MODE_INT)
1662 no_extend = 1;
1663 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1664 xop0, unsignedp);
1665 if (binoptab != ashl_optab)
1666 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1667 xop1, unsignedp);
1670 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1672 /* The second operand of a shift must always be extended. */
1673 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1674 no_extend && binoptab != ashl_optab);
1676 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1677 unsignedp, OPTAB_DIRECT);
1678 if (temp)
1680 if (mclass != MODE_INT
1681 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1683 if (target == 0)
1684 target = gen_reg_rtx (mode);
1685 convert_move (target, temp, 0);
1686 return target;
1688 else
1689 return gen_lowpart (mode, temp);
1691 else
1692 delete_insns_since (last);
1696 /* If operation is commutative,
1697 try to make the first operand a register.
1698 Even better, try to make it the same as the target.
1699 Also try to make the last operand a constant. */
1700 if (commutative_optab_p (binoptab)
1701 && swap_commutative_operands_with_target (target, op0, op1))
1703 temp = op1;
1704 op1 = op0;
1705 op0 = temp;
1708 /* These can be done a word at a time. */
1709 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1710 && mclass == MODE_INT
1711 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1712 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1714 int i;
1715 rtx insns;
1717 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1718 won't be accurate, so use a new target. */
1719 if (target == 0
1720 || target == op0
1721 || target == op1
1722 || !valid_multiword_target_p (target))
1723 target = gen_reg_rtx (mode);
1725 start_sequence ();
1727 /* Do the actual arithmetic. */
1728 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1730 rtx target_piece = operand_subword (target, i, 1, mode);
1731 rtx x = expand_binop (word_mode, binoptab,
1732 operand_subword_force (op0, i, mode),
1733 operand_subword_force (op1, i, mode),
1734 target_piece, unsignedp, next_methods);
1736 if (x == 0)
1737 break;
1739 if (target_piece != x)
1740 emit_move_insn (target_piece, x);
1743 insns = get_insns ();
1744 end_sequence ();
1746 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1748 emit_insn (insns);
1749 return target;
1753 /* Synthesize double word shifts from single word shifts. */
1754 if ((binoptab == lshr_optab || binoptab == ashl_optab
1755 || binoptab == ashr_optab)
1756 && mclass == MODE_INT
1757 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1758 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1759 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode)
1760 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1761 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1762 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1764 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1765 enum machine_mode op1_mode;
1767 double_shift_mask = targetm.shift_truncation_mask (mode);
1768 shift_mask = targetm.shift_truncation_mask (word_mode);
1769 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1771 /* Apply the truncation to constant shifts. */
1772 if (double_shift_mask > 0 && CONST_INT_P (op1))
1773 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1775 if (op1 == CONST0_RTX (op1_mode))
1776 return op0;
1778 /* Make sure that this is a combination that expand_doubleword_shift
1779 can handle. See the comments there for details. */
1780 if (double_shift_mask == 0
1781 || (shift_mask == BITS_PER_WORD - 1
1782 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1784 rtx insns;
1785 rtx into_target, outof_target;
1786 rtx into_input, outof_input;
1787 int left_shift, outof_word;
1789 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1790 won't be accurate, so use a new target. */
1791 if (target == 0
1792 || target == op0
1793 || target == op1
1794 || !valid_multiword_target_p (target))
1795 target = gen_reg_rtx (mode);
1797 start_sequence ();
1799 /* OUTOF_* is the word we are shifting bits away from, and
1800 INTO_* is the word that we are shifting bits towards, thus
1801 they differ depending on the direction of the shift and
1802 WORDS_BIG_ENDIAN. */
1804 left_shift = binoptab == ashl_optab;
1805 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1807 outof_target = operand_subword (target, outof_word, 1, mode);
1808 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1810 outof_input = operand_subword_force (op0, outof_word, mode);
1811 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1813 if (expand_doubleword_shift (op1_mode, binoptab,
1814 outof_input, into_input, op1,
1815 outof_target, into_target,
1816 unsignedp, next_methods, shift_mask))
1818 insns = get_insns ();
1819 end_sequence ();
1821 emit_insn (insns);
1822 return target;
1824 end_sequence ();
1828 /* Synthesize double word rotates from single word shifts. */
1829 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1830 && mclass == MODE_INT
1831 && CONST_INT_P (op1)
1832 && GET_MODE_PRECISION (mode) == 2 * BITS_PER_WORD
1833 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1834 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1836 rtx insns;
1837 rtx into_target, outof_target;
1838 rtx into_input, outof_input;
1839 rtx inter;
1840 int shift_count, left_shift, outof_word;
1842 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1843 won't be accurate, so use a new target. Do this also if target is not
1844 a REG, first because having a register instead may open optimization
1845 opportunities, and second because if target and op0 happen to be MEMs
1846 designating the same location, we would risk clobbering it too early
1847 in the code sequence we generate below. */
1848 if (target == 0
1849 || target == op0
1850 || target == op1
1851 || !REG_P (target)
1852 || !valid_multiword_target_p (target))
1853 target = gen_reg_rtx (mode);
1855 start_sequence ();
1857 shift_count = INTVAL (op1);
1859 /* OUTOF_* is the word we are shifting bits away from, and
1860 INTO_* is the word that we are shifting bits towards, thus
1861 they differ depending on the direction of the shift and
1862 WORDS_BIG_ENDIAN. */
1864 left_shift = (binoptab == rotl_optab);
1865 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1867 outof_target = operand_subword (target, outof_word, 1, mode);
1868 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1870 outof_input = operand_subword_force (op0, outof_word, mode);
1871 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1873 if (shift_count == BITS_PER_WORD)
1875 /* This is just a word swap. */
1876 emit_move_insn (outof_target, into_input);
1877 emit_move_insn (into_target, outof_input);
1878 inter = const0_rtx;
1880 else
1882 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1883 rtx first_shift_count, second_shift_count;
1884 optab reverse_unsigned_shift, unsigned_shift;
1886 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1887 ? lshr_optab : ashl_optab);
1889 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1890 ? ashl_optab : lshr_optab);
1892 if (shift_count > BITS_PER_WORD)
1894 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1895 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1897 else
1899 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1900 second_shift_count = GEN_INT (shift_count);
1903 into_temp1 = expand_binop (word_mode, unsigned_shift,
1904 outof_input, first_shift_count,
1905 NULL_RTX, unsignedp, next_methods);
1906 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1907 into_input, second_shift_count,
1908 NULL_RTX, unsignedp, next_methods);
1910 if (into_temp1 != 0 && into_temp2 != 0)
1911 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1912 into_target, unsignedp, next_methods);
1913 else
1914 inter = 0;
1916 if (inter != 0 && inter != into_target)
1917 emit_move_insn (into_target, inter);
1919 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1920 into_input, first_shift_count,
1921 NULL_RTX, unsignedp, next_methods);
1922 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1923 outof_input, second_shift_count,
1924 NULL_RTX, unsignedp, next_methods);
1926 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1927 inter = expand_binop (word_mode, ior_optab,
1928 outof_temp1, outof_temp2,
1929 outof_target, unsignedp, next_methods);
1931 if (inter != 0 && inter != outof_target)
1932 emit_move_insn (outof_target, inter);
1935 insns = get_insns ();
1936 end_sequence ();
1938 if (inter != 0)
1940 emit_insn (insns);
1941 return target;
1945 /* These can be done a word at a time by propagating carries. */
1946 if ((binoptab == add_optab || binoptab == sub_optab)
1947 && mclass == MODE_INT
1948 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1949 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1951 unsigned int i;
1952 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1953 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1954 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1955 rtx xop0, xop1, xtarget;
1957 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1958 value is one of those, use it. Otherwise, use 1 since it is the
1959 one easiest to get. */
1960 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1961 int normalizep = STORE_FLAG_VALUE;
1962 #else
1963 int normalizep = 1;
1964 #endif
1966 /* Prepare the operands. */
1967 xop0 = force_reg (mode, op0);
1968 xop1 = force_reg (mode, op1);
1970 xtarget = gen_reg_rtx (mode);
1972 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1973 target = xtarget;
1975 /* Indicate for flow that the entire target reg is being set. */
1976 if (REG_P (target))
1977 emit_clobber (xtarget);
1979 /* Do the actual arithmetic. */
1980 for (i = 0; i < nwords; i++)
1982 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1983 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1984 rtx op0_piece = operand_subword_force (xop0, index, mode);
1985 rtx op1_piece = operand_subword_force (xop1, index, mode);
1986 rtx x;
1988 /* Main add/subtract of the input operands. */
1989 x = expand_binop (word_mode, binoptab,
1990 op0_piece, op1_piece,
1991 target_piece, unsignedp, next_methods);
1992 if (x == 0)
1993 break;
1995 if (i + 1 < nwords)
1997 /* Store carry from main add/subtract. */
1998 carry_out = gen_reg_rtx (word_mode);
1999 carry_out = emit_store_flag_force (carry_out,
2000 (binoptab == add_optab
2001 ? LT : GT),
2002 x, op0_piece,
2003 word_mode, 1, normalizep);
2006 if (i > 0)
2008 rtx newx;
2010 /* Add/subtract previous carry to main result. */
2011 newx = expand_binop (word_mode,
2012 normalizep == 1 ? binoptab : otheroptab,
2013 x, carry_in,
2014 NULL_RTX, 1, next_methods);
2016 if (i + 1 < nwords)
2018 /* Get out carry from adding/subtracting carry in. */
2019 rtx carry_tmp = gen_reg_rtx (word_mode);
2020 carry_tmp = emit_store_flag_force (carry_tmp,
2021 (binoptab == add_optab
2022 ? LT : GT),
2023 newx, x,
2024 word_mode, 1, normalizep);
2026 /* Logical-ior the two poss. carry together. */
2027 carry_out = expand_binop (word_mode, ior_optab,
2028 carry_out, carry_tmp,
2029 carry_out, 0, next_methods);
2030 if (carry_out == 0)
2031 break;
2033 emit_move_insn (target_piece, newx);
2035 else
2037 if (x != target_piece)
2038 emit_move_insn (target_piece, x);
2041 carry_in = carry_out;
2044 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
2046 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing
2047 || ! rtx_equal_p (target, xtarget))
2049 rtx temp = emit_move_insn (target, xtarget);
2051 set_dst_reg_note (temp, REG_EQUAL,
2052 gen_rtx_fmt_ee (optab_to_code (binoptab),
2053 mode, copy_rtx (xop0),
2054 copy_rtx (xop1)),
2055 target);
2057 else
2058 target = xtarget;
2060 return target;
2063 else
2064 delete_insns_since (last);
2067 /* Attempt to synthesize double word multiplies using a sequence of word
2068 mode multiplications. We first attempt to generate a sequence using a
2069 more efficient unsigned widening multiply, and if that fails we then
2070 try using a signed widening multiply. */
2072 if (binoptab == smul_optab
2073 && mclass == MODE_INT
2074 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2075 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
2076 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
2078 rtx product = NULL_RTX;
2079 if (widening_optab_handler (umul_widen_optab, mode, word_mode)
2080 != CODE_FOR_nothing)
2082 product = expand_doubleword_mult (mode, op0, op1, target,
2083 true, methods);
2084 if (!product)
2085 delete_insns_since (last);
2088 if (product == NULL_RTX
2089 && widening_optab_handler (smul_widen_optab, mode, word_mode)
2090 != CODE_FOR_nothing)
2092 product = expand_doubleword_mult (mode, op0, op1, target,
2093 false, methods);
2094 if (!product)
2095 delete_insns_since (last);
2098 if (product != NULL_RTX)
2100 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing)
2102 temp = emit_move_insn (target ? target : product, product);
2103 set_dst_reg_note (temp,
2104 REG_EQUAL,
2105 gen_rtx_fmt_ee (MULT, mode,
2106 copy_rtx (op0),
2107 copy_rtx (op1)),
2108 target ? target : product);
2110 return product;
2114 /* It can't be open-coded in this mode.
2115 Use a library call if one is available and caller says that's ok. */
2117 libfunc = optab_libfunc (binoptab, mode);
2118 if (libfunc
2119 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
2121 rtx insns;
2122 rtx op1x = op1;
2123 enum machine_mode op1_mode = mode;
2124 rtx value;
2126 start_sequence ();
2128 if (shift_optab_p (binoptab))
2130 op1_mode = targetm.libgcc_shift_count_mode ();
2131 /* Specify unsigned here,
2132 since negative shift counts are meaningless. */
2133 op1x = convert_to_mode (op1_mode, op1, 1);
2136 if (GET_MODE (op0) != VOIDmode
2137 && GET_MODE (op0) != mode)
2138 op0 = convert_to_mode (mode, op0, unsignedp);
2140 /* Pass 1 for NO_QUEUE so we don't lose any increments
2141 if the libcall is cse'd or moved. */
2142 value = emit_library_call_value (libfunc,
2143 NULL_RTX, LCT_CONST, mode, 2,
2144 op0, mode, op1x, op1_mode);
2146 insns = get_insns ();
2147 end_sequence ();
2149 target = gen_reg_rtx (mode);
2150 emit_libcall_block_1 (insns, target, value,
2151 gen_rtx_fmt_ee (optab_to_code (binoptab),
2152 mode, op0, op1),
2153 trapv_binoptab_p (binoptab));
2155 return target;
2158 delete_insns_since (last);
2160 /* It can't be done in this mode. Can we do it in a wider mode? */
2162 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
2163 || methods == OPTAB_MUST_WIDEN))
2165 /* Caller says, don't even try. */
2166 delete_insns_since (entry_last);
2167 return 0;
2170 /* Compute the value of METHODS to pass to recursive calls.
2171 Don't allow widening to be tried recursively. */
2173 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
2175 /* Look for a wider mode of the same class for which it appears we can do
2176 the operation. */
2178 if (CLASS_HAS_WIDER_MODES_P (mclass))
2180 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2181 wider_mode != VOIDmode;
2182 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2184 if (find_widening_optab_handler (binoptab, wider_mode, mode, 1)
2185 != CODE_FOR_nothing
2186 || (methods == OPTAB_LIB
2187 && optab_libfunc (binoptab, wider_mode)))
2189 rtx xop0 = op0, xop1 = op1;
2190 int no_extend = 0;
2192 /* For certain integer operations, we need not actually extend
2193 the narrow operands, as long as we will truncate
2194 the results to the same narrowness. */
2196 if ((binoptab == ior_optab || binoptab == and_optab
2197 || binoptab == xor_optab
2198 || binoptab == add_optab || binoptab == sub_optab
2199 || binoptab == smul_optab || binoptab == ashl_optab)
2200 && mclass == MODE_INT)
2201 no_extend = 1;
2203 xop0 = widen_operand (xop0, wider_mode, mode,
2204 unsignedp, no_extend);
2206 /* The second operand of a shift must always be extended. */
2207 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
2208 no_extend && binoptab != ashl_optab);
2210 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
2211 unsignedp, methods);
2212 if (temp)
2214 if (mclass != MODE_INT
2215 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2217 if (target == 0)
2218 target = gen_reg_rtx (mode);
2219 convert_move (target, temp, 0);
2220 return target;
2222 else
2223 return gen_lowpart (mode, temp);
2225 else
2226 delete_insns_since (last);
2231 delete_insns_since (entry_last);
2232 return 0;
2235 /* Expand a binary operator which has both signed and unsigned forms.
2236 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2237 signed operations.
2239 If we widen unsigned operands, we may use a signed wider operation instead
2240 of an unsigned wider operation, since the result would be the same. */
2243 sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
2244 rtx op0, rtx op1, rtx target, int unsignedp,
2245 enum optab_methods methods)
2247 rtx temp;
2248 optab direct_optab = unsignedp ? uoptab : soptab;
2249 bool save_enable;
2251 /* Do it without widening, if possible. */
2252 temp = expand_binop (mode, direct_optab, op0, op1, target,
2253 unsignedp, OPTAB_DIRECT);
2254 if (temp || methods == OPTAB_DIRECT)
2255 return temp;
2257 /* Try widening to a signed int. Disable any direct use of any
2258 signed insn in the current mode. */
2259 save_enable = swap_optab_enable (soptab, mode, false);
2261 temp = expand_binop (mode, soptab, op0, op1, target,
2262 unsignedp, OPTAB_WIDEN);
2264 /* For unsigned operands, try widening to an unsigned int. */
2265 if (!temp && unsignedp)
2266 temp = expand_binop (mode, uoptab, op0, op1, target,
2267 unsignedp, OPTAB_WIDEN);
2268 if (temp || methods == OPTAB_WIDEN)
2269 goto egress;
2271 /* Use the right width libcall if that exists. */
2272 temp = expand_binop (mode, direct_optab, op0, op1, target,
2273 unsignedp, OPTAB_LIB);
2274 if (temp || methods == OPTAB_LIB)
2275 goto egress;
2277 /* Must widen and use a libcall, use either signed or unsigned. */
2278 temp = expand_binop (mode, soptab, op0, op1, target,
2279 unsignedp, methods);
2280 if (!temp && unsignedp)
2281 temp = expand_binop (mode, uoptab, op0, op1, target,
2282 unsignedp, methods);
2284 egress:
2285 /* Undo the fiddling above. */
2286 if (save_enable)
2287 swap_optab_enable (soptab, mode, true);
2288 return temp;
2291 /* Generate code to perform an operation specified by UNOPPTAB
2292 on operand OP0, with two results to TARG0 and TARG1.
2293 We assume that the order of the operands for the instruction
2294 is TARG0, TARG1, OP0.
2296 Either TARG0 or TARG1 may be zero, but what that means is that
2297 the result is not actually wanted. We will generate it into
2298 a dummy pseudo-reg and discard it. They may not both be zero.
2300 Returns 1 if this operation can be performed; 0 if not. */
2303 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2304 int unsignedp)
2306 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2307 enum mode_class mclass;
2308 enum machine_mode wider_mode;
2309 rtx entry_last = get_last_insn ();
2310 rtx last;
2312 mclass = GET_MODE_CLASS (mode);
2314 if (!targ0)
2315 targ0 = gen_reg_rtx (mode);
2316 if (!targ1)
2317 targ1 = gen_reg_rtx (mode);
2319 /* Record where to go back to if we fail. */
2320 last = get_last_insn ();
2322 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2324 struct expand_operand ops[3];
2325 enum insn_code icode = optab_handler (unoptab, mode);
2327 create_fixed_operand (&ops[0], targ0);
2328 create_fixed_operand (&ops[1], targ1);
2329 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
2330 if (maybe_expand_insn (icode, 3, ops))
2331 return 1;
2334 /* It can't be done in this mode. Can we do it in a wider mode? */
2336 if (CLASS_HAS_WIDER_MODES_P (mclass))
2338 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2339 wider_mode != VOIDmode;
2340 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2342 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2344 rtx t0 = gen_reg_rtx (wider_mode);
2345 rtx t1 = gen_reg_rtx (wider_mode);
2346 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2348 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2350 convert_move (targ0, t0, unsignedp);
2351 convert_move (targ1, t1, unsignedp);
2352 return 1;
2354 else
2355 delete_insns_since (last);
2360 delete_insns_since (entry_last);
2361 return 0;
2364 /* Generate code to perform an operation specified by BINOPTAB
2365 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2366 We assume that the order of the operands for the instruction
2367 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2368 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2370 Either TARG0 or TARG1 may be zero, but what that means is that
2371 the result is not actually wanted. We will generate it into
2372 a dummy pseudo-reg and discard it. They may not both be zero.
2374 Returns 1 if this operation can be performed; 0 if not. */
2377 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2378 int unsignedp)
2380 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2381 enum mode_class mclass;
2382 enum machine_mode wider_mode;
2383 rtx entry_last = get_last_insn ();
2384 rtx last;
2386 mclass = GET_MODE_CLASS (mode);
2388 if (!targ0)
2389 targ0 = gen_reg_rtx (mode);
2390 if (!targ1)
2391 targ1 = gen_reg_rtx (mode);
2393 /* Record where to go back to if we fail. */
2394 last = get_last_insn ();
2396 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2398 struct expand_operand ops[4];
2399 enum insn_code icode = optab_handler (binoptab, mode);
2400 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2401 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2402 rtx xop0 = op0, xop1 = op1;
2404 /* If we are optimizing, force expensive constants into a register. */
2405 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2406 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2408 create_fixed_operand (&ops[0], targ0);
2409 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2410 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
2411 create_fixed_operand (&ops[3], targ1);
2412 if (maybe_expand_insn (icode, 4, ops))
2413 return 1;
2414 delete_insns_since (last);
2417 /* It can't be done in this mode. Can we do it in a wider mode? */
2419 if (CLASS_HAS_WIDER_MODES_P (mclass))
2421 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2422 wider_mode != VOIDmode;
2423 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2425 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2427 rtx t0 = gen_reg_rtx (wider_mode);
2428 rtx t1 = gen_reg_rtx (wider_mode);
2429 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2430 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2432 if (expand_twoval_binop (binoptab, cop0, cop1,
2433 t0, t1, unsignedp))
2435 convert_move (targ0, t0, unsignedp);
2436 convert_move (targ1, t1, unsignedp);
2437 return 1;
2439 else
2440 delete_insns_since (last);
2445 delete_insns_since (entry_last);
2446 return 0;
2449 /* Expand the two-valued library call indicated by BINOPTAB, but
2450 preserve only one of the values. If TARG0 is non-NULL, the first
2451 value is placed into TARG0; otherwise the second value is placed
2452 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2453 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2454 This routine assumes that the value returned by the library call is
2455 as if the return value was of an integral mode twice as wide as the
2456 mode of OP0. Returns 1 if the call was successful. */
2458 bool
2459 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2460 rtx targ0, rtx targ1, enum rtx_code code)
2462 enum machine_mode mode;
2463 enum machine_mode libval_mode;
2464 rtx libval;
2465 rtx insns;
2466 rtx libfunc;
2468 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2469 gcc_assert (!targ0 != !targ1);
2471 mode = GET_MODE (op0);
2472 libfunc = optab_libfunc (binoptab, mode);
2473 if (!libfunc)
2474 return false;
2476 /* The value returned by the library function will have twice as
2477 many bits as the nominal MODE. */
2478 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2479 MODE_INT);
2480 start_sequence ();
2481 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2482 libval_mode, 2,
2483 op0, mode,
2484 op1, mode);
2485 /* Get the part of VAL containing the value that we want. */
2486 libval = simplify_gen_subreg (mode, libval, libval_mode,
2487 targ0 ? 0 : GET_MODE_SIZE (mode));
2488 insns = get_insns ();
2489 end_sequence ();
2490 /* Move the into the desired location. */
2491 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2492 gen_rtx_fmt_ee (code, mode, op0, op1));
2494 return true;
2498 /* Wrapper around expand_unop which takes an rtx code to specify
2499 the operation to perform, not an optab pointer. All other
2500 arguments are the same. */
2502 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2503 rtx target, int unsignedp)
2505 optab unop = code_to_optab (code);
2506 gcc_assert (unop);
2508 return expand_unop (mode, unop, op0, target, unsignedp);
2511 /* Try calculating
2512 (clz:narrow x)
2514 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2516 A similar operation can be used for clrsb. UNOPTAB says which operation
2517 we are trying to expand. */
2518 static rtx
2519 widen_leading (enum machine_mode mode, rtx op0, rtx target, optab unoptab)
2521 enum mode_class mclass = GET_MODE_CLASS (mode);
2522 if (CLASS_HAS_WIDER_MODES_P (mclass))
2524 enum machine_mode wider_mode;
2525 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2526 wider_mode != VOIDmode;
2527 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2529 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2531 rtx xop0, temp, last;
2533 last = get_last_insn ();
2535 if (target == 0)
2536 target = gen_reg_rtx (mode);
2537 xop0 = widen_operand (op0, wider_mode, mode,
2538 unoptab != clrsb_optab, false);
2539 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2540 unoptab != clrsb_optab);
2541 if (temp != 0)
2542 temp = expand_binop (wider_mode, sub_optab, temp,
2543 GEN_INT (GET_MODE_PRECISION (wider_mode)
2544 - GET_MODE_PRECISION (mode)),
2545 target, true, OPTAB_DIRECT);
2546 if (temp == 0)
2547 delete_insns_since (last);
2549 return temp;
2553 return 0;
2556 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2557 quantities, choosing which based on whether the high word is nonzero. */
2558 static rtx
2559 expand_doubleword_clz (enum machine_mode mode, rtx op0, rtx target)
2561 rtx xop0 = force_reg (mode, op0);
2562 rtx subhi = gen_highpart (word_mode, xop0);
2563 rtx sublo = gen_lowpart (word_mode, xop0);
2564 rtx hi0_label = gen_label_rtx ();
2565 rtx after_label = gen_label_rtx ();
2566 rtx seq, temp, result;
2568 /* If we were not given a target, use a word_mode register, not a
2569 'mode' register. The result will fit, and nobody is expecting
2570 anything bigger (the return type of __builtin_clz* is int). */
2571 if (!target)
2572 target = gen_reg_rtx (word_mode);
2574 /* In any case, write to a word_mode scratch in both branches of the
2575 conditional, so we can ensure there is a single move insn setting
2576 'target' to tag a REG_EQUAL note on. */
2577 result = gen_reg_rtx (word_mode);
2579 start_sequence ();
2581 /* If the high word is not equal to zero,
2582 then clz of the full value is clz of the high word. */
2583 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2584 word_mode, true, hi0_label);
2586 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2587 if (!temp)
2588 goto fail;
2590 if (temp != result)
2591 convert_move (result, temp, true);
2593 emit_jump_insn (gen_jump (after_label));
2594 emit_barrier ();
2596 /* Else clz of the full value is clz of the low word plus the number
2597 of bits in the high word. */
2598 emit_label (hi0_label);
2600 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2601 if (!temp)
2602 goto fail;
2603 temp = expand_binop (word_mode, add_optab, temp,
2604 GEN_INT (GET_MODE_BITSIZE (word_mode)),
2605 result, true, OPTAB_DIRECT);
2606 if (!temp)
2607 goto fail;
2608 if (temp != result)
2609 convert_move (result, temp, true);
2611 emit_label (after_label);
2612 convert_move (target, result, true);
2614 seq = get_insns ();
2615 end_sequence ();
2617 add_equal_note (seq, target, CLZ, xop0, 0);
2618 emit_insn (seq);
2619 return target;
2621 fail:
2622 end_sequence ();
2623 return 0;
2626 /* Try calculating
2627 (bswap:narrow x)
2629 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2630 static rtx
2631 widen_bswap (enum machine_mode mode, rtx op0, rtx target)
2633 enum mode_class mclass = GET_MODE_CLASS (mode);
2634 enum machine_mode wider_mode;
2635 rtx x, last;
2637 if (!CLASS_HAS_WIDER_MODES_P (mclass))
2638 return NULL_RTX;
2640 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2641 wider_mode != VOIDmode;
2642 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2643 if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing)
2644 goto found;
2645 return NULL_RTX;
2647 found:
2648 last = get_last_insn ();
2650 x = widen_operand (op0, wider_mode, mode, true, true);
2651 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2653 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2654 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2655 if (x != 0)
2656 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2657 GET_MODE_BITSIZE (wider_mode)
2658 - GET_MODE_BITSIZE (mode),
2659 NULL_RTX, true);
2661 if (x != 0)
2663 if (target == 0)
2664 target = gen_reg_rtx (mode);
2665 emit_move_insn (target, gen_lowpart (mode, x));
2667 else
2668 delete_insns_since (last);
2670 return target;
2673 /* Try calculating bswap as two bswaps of two word-sized operands. */
2675 static rtx
2676 expand_doubleword_bswap (enum machine_mode mode, rtx op, rtx target)
2678 rtx t0, t1;
2680 t1 = expand_unop (word_mode, bswap_optab,
2681 operand_subword_force (op, 0, mode), NULL_RTX, true);
2682 t0 = expand_unop (word_mode, bswap_optab,
2683 operand_subword_force (op, 1, mode), NULL_RTX, true);
2685 if (target == 0 || !valid_multiword_target_p (target))
2686 target = gen_reg_rtx (mode);
2687 if (REG_P (target))
2688 emit_clobber (target);
2689 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2690 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2692 return target;
2695 /* Try calculating (parity x) as (and (popcount x) 1), where
2696 popcount can also be done in a wider mode. */
2697 static rtx
2698 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2700 enum mode_class mclass = GET_MODE_CLASS (mode);
2701 if (CLASS_HAS_WIDER_MODES_P (mclass))
2703 enum machine_mode wider_mode;
2704 for (wider_mode = mode; wider_mode != VOIDmode;
2705 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2707 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2709 rtx xop0, temp, last;
2711 last = get_last_insn ();
2713 if (target == 0)
2714 target = gen_reg_rtx (mode);
2715 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2716 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2717 true);
2718 if (temp != 0)
2719 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2720 target, true, OPTAB_DIRECT);
2721 if (temp == 0)
2722 delete_insns_since (last);
2724 return temp;
2728 return 0;
2731 /* Try calculating ctz(x) as K - clz(x & -x) ,
2732 where K is GET_MODE_PRECISION(mode) - 1.
2734 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2735 don't have to worry about what the hardware does in that case. (If
2736 the clz instruction produces the usual value at 0, which is K, the
2737 result of this code sequence will be -1; expand_ffs, below, relies
2738 on this. It might be nice to have it be K instead, for consistency
2739 with the (very few) processors that provide a ctz with a defined
2740 value, but that would take one more instruction, and it would be
2741 less convenient for expand_ffs anyway. */
2743 static rtx
2744 expand_ctz (enum machine_mode mode, rtx op0, rtx target)
2746 rtx seq, temp;
2748 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2749 return 0;
2751 start_sequence ();
2753 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2754 if (temp)
2755 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2756 true, OPTAB_DIRECT);
2757 if (temp)
2758 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2759 if (temp)
2760 temp = expand_binop (mode, sub_optab, GEN_INT (GET_MODE_PRECISION (mode) - 1),
2761 temp, target,
2762 true, OPTAB_DIRECT);
2763 if (temp == 0)
2765 end_sequence ();
2766 return 0;
2769 seq = get_insns ();
2770 end_sequence ();
2772 add_equal_note (seq, temp, CTZ, op0, 0);
2773 emit_insn (seq);
2774 return temp;
2778 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2779 else with the sequence used by expand_clz.
2781 The ffs builtin promises to return zero for a zero value and ctz/clz
2782 may have an undefined value in that case. If they do not give us a
2783 convenient value, we have to generate a test and branch. */
2784 static rtx
2785 expand_ffs (enum machine_mode mode, rtx op0, rtx target)
2787 HOST_WIDE_INT val = 0;
2788 bool defined_at_zero = false;
2789 rtx temp, seq;
2791 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2793 start_sequence ();
2795 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2796 if (!temp)
2797 goto fail;
2799 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2801 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2803 start_sequence ();
2804 temp = expand_ctz (mode, op0, 0);
2805 if (!temp)
2806 goto fail;
2808 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2810 defined_at_zero = true;
2811 val = (GET_MODE_PRECISION (mode) - 1) - val;
2814 else
2815 return 0;
2817 if (defined_at_zero && val == -1)
2818 /* No correction needed at zero. */;
2819 else
2821 /* We don't try to do anything clever with the situation found
2822 on some processors (eg Alpha) where ctz(0:mode) ==
2823 bitsize(mode). If someone can think of a way to send N to -1
2824 and leave alone all values in the range 0..N-1 (where N is a
2825 power of two), cheaper than this test-and-branch, please add it.
2827 The test-and-branch is done after the operation itself, in case
2828 the operation sets condition codes that can be recycled for this.
2829 (This is true on i386, for instance.) */
2831 rtx nonzero_label = gen_label_rtx ();
2832 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2833 mode, true, nonzero_label);
2835 convert_move (temp, GEN_INT (-1), false);
2836 emit_label (nonzero_label);
2839 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2840 to produce a value in the range 0..bitsize. */
2841 temp = expand_binop (mode, add_optab, temp, GEN_INT (1),
2842 target, false, OPTAB_DIRECT);
2843 if (!temp)
2844 goto fail;
2846 seq = get_insns ();
2847 end_sequence ();
2849 add_equal_note (seq, temp, FFS, op0, 0);
2850 emit_insn (seq);
2851 return temp;
2853 fail:
2854 end_sequence ();
2855 return 0;
2858 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2859 conditions, VAL may already be a SUBREG against which we cannot generate
2860 a further SUBREG. In this case, we expect forcing the value into a
2861 register will work around the situation. */
2863 static rtx
2864 lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2865 enum machine_mode imode)
2867 rtx ret;
2868 ret = lowpart_subreg (omode, val, imode);
2869 if (ret == NULL)
2871 val = force_reg (imode, val);
2872 ret = lowpart_subreg (omode, val, imode);
2873 gcc_assert (ret != NULL);
2875 return ret;
2878 /* Expand a floating point absolute value or negation operation via a
2879 logical operation on the sign bit. */
2881 static rtx
2882 expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2883 rtx op0, rtx target)
2885 const struct real_format *fmt;
2886 int bitpos, word, nwords, i;
2887 enum machine_mode imode;
2888 double_int mask;
2889 rtx temp, insns;
2891 /* The format has to have a simple sign bit. */
2892 fmt = REAL_MODE_FORMAT (mode);
2893 if (fmt == NULL)
2894 return NULL_RTX;
2896 bitpos = fmt->signbit_rw;
2897 if (bitpos < 0)
2898 return NULL_RTX;
2900 /* Don't create negative zeros if the format doesn't support them. */
2901 if (code == NEG && !fmt->has_signed_zero)
2902 return NULL_RTX;
2904 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2906 imode = int_mode_for_mode (mode);
2907 if (imode == BLKmode)
2908 return NULL_RTX;
2909 word = 0;
2910 nwords = 1;
2912 else
2914 imode = word_mode;
2916 if (FLOAT_WORDS_BIG_ENDIAN)
2917 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2918 else
2919 word = bitpos / BITS_PER_WORD;
2920 bitpos = bitpos % BITS_PER_WORD;
2921 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2924 mask = double_int_zero.set_bit (bitpos);
2925 if (code == ABS)
2926 mask = ~mask;
2928 if (target == 0
2929 || target == op0
2930 || (nwords > 1 && !valid_multiword_target_p (target)))
2931 target = gen_reg_rtx (mode);
2933 if (nwords > 1)
2935 start_sequence ();
2937 for (i = 0; i < nwords; ++i)
2939 rtx targ_piece = operand_subword (target, i, 1, mode);
2940 rtx op0_piece = operand_subword_force (op0, i, mode);
2942 if (i == word)
2944 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2945 op0_piece,
2946 immed_double_int_const (mask, imode),
2947 targ_piece, 1, OPTAB_LIB_WIDEN);
2948 if (temp != targ_piece)
2949 emit_move_insn (targ_piece, temp);
2951 else
2952 emit_move_insn (targ_piece, op0_piece);
2955 insns = get_insns ();
2956 end_sequence ();
2958 emit_insn (insns);
2960 else
2962 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2963 gen_lowpart (imode, op0),
2964 immed_double_int_const (mask, imode),
2965 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2966 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2968 set_dst_reg_note (get_last_insn (), REG_EQUAL,
2969 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
2970 target);
2973 return target;
2976 /* As expand_unop, but will fail rather than attempt the operation in a
2977 different mode or with a libcall. */
2978 static rtx
2979 expand_unop_direct (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2980 int unsignedp)
2982 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2984 struct expand_operand ops[2];
2985 enum insn_code icode = optab_handler (unoptab, mode);
2986 rtx last = get_last_insn ();
2987 rtx pat;
2989 create_output_operand (&ops[0], target, mode);
2990 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2991 pat = maybe_gen_insn (icode, 2, ops);
2992 if (pat)
2994 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2995 && ! add_equal_note (pat, ops[0].value, optab_to_code (unoptab),
2996 ops[1].value, NULL_RTX))
2998 delete_insns_since (last);
2999 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
3002 emit_insn (pat);
3004 return ops[0].value;
3007 return 0;
3010 /* Generate code to perform an operation specified by UNOPTAB
3011 on operand OP0, with result having machine-mode MODE.
3013 UNSIGNEDP is for the case where we have to widen the operands
3014 to perform the operation. It says to use zero-extension.
3016 If TARGET is nonzero, the value
3017 is generated there, if it is convenient to do so.
3018 In all cases an rtx is returned for the locus of the value;
3019 this may or may not be TARGET. */
3022 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
3023 int unsignedp)
3025 enum mode_class mclass = GET_MODE_CLASS (mode);
3026 enum machine_mode wider_mode;
3027 rtx temp;
3028 rtx libfunc;
3030 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
3031 if (temp)
3032 return temp;
3034 /* It can't be done in this mode. Can we open-code it in a wider mode? */
3036 /* Widening (or narrowing) clz needs special treatment. */
3037 if (unoptab == clz_optab)
3039 temp = widen_leading (mode, op0, target, unoptab);
3040 if (temp)
3041 return temp;
3043 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
3044 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3046 temp = expand_doubleword_clz (mode, op0, target);
3047 if (temp)
3048 return temp;
3051 goto try_libcall;
3054 if (unoptab == clrsb_optab)
3056 temp = widen_leading (mode, op0, target, unoptab);
3057 if (temp)
3058 return temp;
3059 goto try_libcall;
3062 /* Widening (or narrowing) bswap needs special treatment. */
3063 if (unoptab == bswap_optab)
3065 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
3066 or ROTATERT. First try these directly; if this fails, then try the
3067 obvious pair of shifts with allowed widening, as this will probably
3068 be always more efficient than the other fallback methods. */
3069 if (mode == HImode)
3071 rtx last, temp1, temp2;
3073 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
3075 temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target,
3076 unsignedp, OPTAB_DIRECT);
3077 if (temp)
3078 return temp;
3081 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
3083 temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target,
3084 unsignedp, OPTAB_DIRECT);
3085 if (temp)
3086 return temp;
3089 last = get_last_insn ();
3091 temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX,
3092 unsignedp, OPTAB_WIDEN);
3093 temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX,
3094 unsignedp, OPTAB_WIDEN);
3095 if (temp1 && temp2)
3097 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
3098 unsignedp, OPTAB_WIDEN);
3099 if (temp)
3100 return temp;
3103 delete_insns_since (last);
3106 temp = widen_bswap (mode, op0, target);
3107 if (temp)
3108 return temp;
3110 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
3111 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3113 temp = expand_doubleword_bswap (mode, op0, target);
3114 if (temp)
3115 return temp;
3118 goto try_libcall;
3121 if (CLASS_HAS_WIDER_MODES_P (mclass))
3122 for (wider_mode = GET_MODE_WIDER_MODE (mode);
3123 wider_mode != VOIDmode;
3124 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3126 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
3128 rtx xop0 = op0;
3129 rtx last = get_last_insn ();
3131 /* For certain operations, we need not actually extend
3132 the narrow operand, as long as we will truncate the
3133 results to the same narrowness. */
3135 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3136 (unoptab == neg_optab
3137 || unoptab == one_cmpl_optab)
3138 && mclass == MODE_INT);
3140 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3141 unsignedp);
3143 if (temp)
3145 if (mclass != MODE_INT
3146 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
3148 if (target == 0)
3149 target = gen_reg_rtx (mode);
3150 convert_move (target, temp, 0);
3151 return target;
3153 else
3154 return gen_lowpart (mode, temp);
3156 else
3157 delete_insns_since (last);
3161 /* These can be done a word at a time. */
3162 if (unoptab == one_cmpl_optab
3163 && mclass == MODE_INT
3164 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
3165 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3167 int i;
3168 rtx insns;
3170 if (target == 0 || target == op0 || !valid_multiword_target_p (target))
3171 target = gen_reg_rtx (mode);
3173 start_sequence ();
3175 /* Do the actual arithmetic. */
3176 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
3178 rtx target_piece = operand_subword (target, i, 1, mode);
3179 rtx x = expand_unop (word_mode, unoptab,
3180 operand_subword_force (op0, i, mode),
3181 target_piece, unsignedp);
3183 if (target_piece != x)
3184 emit_move_insn (target_piece, x);
3187 insns = get_insns ();
3188 end_sequence ();
3190 emit_insn (insns);
3191 return target;
3194 if (optab_to_code (unoptab) == NEG)
3196 /* Try negating floating point values by flipping the sign bit. */
3197 if (SCALAR_FLOAT_MODE_P (mode))
3199 temp = expand_absneg_bit (NEG, mode, op0, target);
3200 if (temp)
3201 return temp;
3204 /* If there is no negation pattern, and we have no negative zero,
3205 try subtracting from zero. */
3206 if (!HONOR_SIGNED_ZEROS (mode))
3208 temp = expand_binop (mode, (unoptab == negv_optab
3209 ? subv_optab : sub_optab),
3210 CONST0_RTX (mode), op0, target,
3211 unsignedp, OPTAB_DIRECT);
3212 if (temp)
3213 return temp;
3217 /* Try calculating parity (x) as popcount (x) % 2. */
3218 if (unoptab == parity_optab)
3220 temp = expand_parity (mode, op0, target);
3221 if (temp)
3222 return temp;
3225 /* Try implementing ffs (x) in terms of clz (x). */
3226 if (unoptab == ffs_optab)
3228 temp = expand_ffs (mode, op0, target);
3229 if (temp)
3230 return temp;
3233 /* Try implementing ctz (x) in terms of clz (x). */
3234 if (unoptab == ctz_optab)
3236 temp = expand_ctz (mode, op0, target);
3237 if (temp)
3238 return temp;
3241 try_libcall:
3242 /* Now try a library call in this mode. */
3243 libfunc = optab_libfunc (unoptab, mode);
3244 if (libfunc)
3246 rtx insns;
3247 rtx value;
3248 rtx eq_value;
3249 enum machine_mode outmode = mode;
3251 /* All of these functions return small values. Thus we choose to
3252 have them return something that isn't a double-word. */
3253 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3254 || unoptab == clrsb_optab || unoptab == popcount_optab
3255 || unoptab == parity_optab)
3256 outmode
3257 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
3258 optab_libfunc (unoptab, mode)));
3260 start_sequence ();
3262 /* Pass 1 for NO_QUEUE so we don't lose any increments
3263 if the libcall is cse'd or moved. */
3264 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
3265 1, op0, mode);
3266 insns = get_insns ();
3267 end_sequence ();
3269 target = gen_reg_rtx (outmode);
3270 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
3271 if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode))
3272 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
3273 else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
3274 eq_value = simplify_gen_unary (ZERO_EXTEND, outmode, eq_value, mode);
3275 emit_libcall_block_1 (insns, target, value, eq_value,
3276 trapv_unoptab_p (unoptab));
3278 return target;
3281 /* It can't be done in this mode. Can we do it in a wider mode? */
3283 if (CLASS_HAS_WIDER_MODES_P (mclass))
3285 for (wider_mode = GET_MODE_WIDER_MODE (mode);
3286 wider_mode != VOIDmode;
3287 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3289 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
3290 || optab_libfunc (unoptab, wider_mode))
3292 rtx xop0 = op0;
3293 rtx last = get_last_insn ();
3295 /* For certain operations, we need not actually extend
3296 the narrow operand, as long as we will truncate the
3297 results to the same narrowness. */
3298 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3299 (unoptab == neg_optab
3300 || unoptab == one_cmpl_optab
3301 || unoptab == bswap_optab)
3302 && mclass == MODE_INT);
3304 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3305 unsignedp);
3307 /* If we are generating clz using wider mode, adjust the
3308 result. Similarly for clrsb. */
3309 if ((unoptab == clz_optab || unoptab == clrsb_optab)
3310 && temp != 0)
3311 temp = expand_binop (wider_mode, sub_optab, temp,
3312 GEN_INT (GET_MODE_PRECISION (wider_mode)
3313 - GET_MODE_PRECISION (mode)),
3314 target, true, OPTAB_DIRECT);
3316 /* Likewise for bswap. */
3317 if (unoptab == bswap_optab && temp != 0)
3319 gcc_assert (GET_MODE_PRECISION (wider_mode)
3320 == GET_MODE_BITSIZE (wider_mode)
3321 && GET_MODE_PRECISION (mode)
3322 == GET_MODE_BITSIZE (mode));
3324 temp = expand_shift (RSHIFT_EXPR, wider_mode, temp,
3325 GET_MODE_BITSIZE (wider_mode)
3326 - GET_MODE_BITSIZE (mode),
3327 NULL_RTX, true);
3330 if (temp)
3332 if (mclass != MODE_INT)
3334 if (target == 0)
3335 target = gen_reg_rtx (mode);
3336 convert_move (target, temp, 0);
3337 return target;
3339 else
3340 return gen_lowpart (mode, temp);
3342 else
3343 delete_insns_since (last);
3348 /* One final attempt at implementing negation via subtraction,
3349 this time allowing widening of the operand. */
3350 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
3352 rtx temp;
3353 temp = expand_binop (mode,
3354 unoptab == negv_optab ? subv_optab : sub_optab,
3355 CONST0_RTX (mode), op0,
3356 target, unsignedp, OPTAB_LIB_WIDEN);
3357 if (temp)
3358 return temp;
3361 return 0;
3364 /* Emit code to compute the absolute value of OP0, with result to
3365 TARGET if convenient. (TARGET may be 0.) The return value says
3366 where the result actually is to be found.
3368 MODE is the mode of the operand; the mode of the result is
3369 different but can be deduced from MODE.
3374 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
3375 int result_unsignedp)
3377 rtx temp;
3379 if (GET_MODE_CLASS (mode) != MODE_INT
3380 || ! flag_trapv)
3381 result_unsignedp = 1;
3383 /* First try to do it with a special abs instruction. */
3384 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3385 op0, target, 0);
3386 if (temp != 0)
3387 return temp;
3389 /* For floating point modes, try clearing the sign bit. */
3390 if (SCALAR_FLOAT_MODE_P (mode))
3392 temp = expand_absneg_bit (ABS, mode, op0, target);
3393 if (temp)
3394 return temp;
3397 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3398 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3399 && !HONOR_SIGNED_ZEROS (mode))
3401 rtx last = get_last_insn ();
3403 temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3404 op0, NULL_RTX, 0);
3405 if (temp != 0)
3406 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3407 OPTAB_WIDEN);
3409 if (temp != 0)
3410 return temp;
3412 delete_insns_since (last);
3415 /* If this machine has expensive jumps, we can do integer absolute
3416 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3417 where W is the width of MODE. */
3419 if (GET_MODE_CLASS (mode) == MODE_INT
3420 && BRANCH_COST (optimize_insn_for_speed_p (),
3421 false) >= 2)
3423 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3424 GET_MODE_PRECISION (mode) - 1,
3425 NULL_RTX, 0);
3427 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3428 OPTAB_LIB_WIDEN);
3429 if (temp != 0)
3430 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3431 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3433 if (temp != 0)
3434 return temp;
3437 return NULL_RTX;
3441 expand_abs (enum machine_mode mode, rtx op0, rtx target,
3442 int result_unsignedp, int safe)
3444 rtx temp, op1;
3446 if (GET_MODE_CLASS (mode) != MODE_INT
3447 || ! flag_trapv)
3448 result_unsignedp = 1;
3450 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3451 if (temp != 0)
3452 return temp;
3454 /* If that does not win, use conditional jump and negate. */
3456 /* It is safe to use the target if it is the same
3457 as the source if this is also a pseudo register */
3458 if (op0 == target && REG_P (op0)
3459 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3460 safe = 1;
3462 op1 = gen_label_rtx ();
3463 if (target == 0 || ! safe
3464 || GET_MODE (target) != mode
3465 || (MEM_P (target) && MEM_VOLATILE_P (target))
3466 || (REG_P (target)
3467 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3468 target = gen_reg_rtx (mode);
3470 emit_move_insn (target, op0);
3471 NO_DEFER_POP;
3473 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3474 NULL_RTX, NULL_RTX, op1, -1);
3476 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3477 target, target, 0);
3478 if (op0 != target)
3479 emit_move_insn (target, op0);
3480 emit_label (op1);
3481 OK_DEFER_POP;
3482 return target;
3485 /* Emit code to compute the one's complement absolute value of OP0
3486 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3487 (TARGET may be NULL_RTX.) The return value says where the result
3488 actually is to be found.
3490 MODE is the mode of the operand; the mode of the result is
3491 different but can be deduced from MODE. */
3494 expand_one_cmpl_abs_nojump (enum machine_mode mode, rtx op0, rtx target)
3496 rtx temp;
3498 /* Not applicable for floating point modes. */
3499 if (FLOAT_MODE_P (mode))
3500 return NULL_RTX;
3502 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3503 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3505 rtx last = get_last_insn ();
3507 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3508 if (temp != 0)
3509 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3510 OPTAB_WIDEN);
3512 if (temp != 0)
3513 return temp;
3515 delete_insns_since (last);
3518 /* If this machine has expensive jumps, we can do one's complement
3519 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3521 if (GET_MODE_CLASS (mode) == MODE_INT
3522 && BRANCH_COST (optimize_insn_for_speed_p (),
3523 false) >= 2)
3525 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3526 GET_MODE_PRECISION (mode) - 1,
3527 NULL_RTX, 0);
3529 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3530 OPTAB_LIB_WIDEN);
3532 if (temp != 0)
3533 return temp;
3536 return NULL_RTX;
3539 /* A subroutine of expand_copysign, perform the copysign operation using the
3540 abs and neg primitives advertised to exist on the target. The assumption
3541 is that we have a split register file, and leaving op0 in fp registers,
3542 and not playing with subregs so much, will help the register allocator. */
3544 static rtx
3545 expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3546 int bitpos, bool op0_is_abs)
3548 enum machine_mode imode;
3549 enum insn_code icode;
3550 rtx sign, label;
3552 if (target == op1)
3553 target = NULL_RTX;
3555 /* Check if the back end provides an insn that handles signbit for the
3556 argument's mode. */
3557 icode = optab_handler (signbit_optab, mode);
3558 if (icode != CODE_FOR_nothing)
3560 imode = insn_data[(int) icode].operand[0].mode;
3561 sign = gen_reg_rtx (imode);
3562 emit_unop_insn (icode, sign, op1, UNKNOWN);
3564 else
3566 double_int mask;
3568 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3570 imode = int_mode_for_mode (mode);
3571 if (imode == BLKmode)
3572 return NULL_RTX;
3573 op1 = gen_lowpart (imode, op1);
3575 else
3577 int word;
3579 imode = word_mode;
3580 if (FLOAT_WORDS_BIG_ENDIAN)
3581 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3582 else
3583 word = bitpos / BITS_PER_WORD;
3584 bitpos = bitpos % BITS_PER_WORD;
3585 op1 = operand_subword_force (op1, word, mode);
3588 mask = double_int_zero.set_bit (bitpos);
3590 sign = expand_binop (imode, and_optab, op1,
3591 immed_double_int_const (mask, imode),
3592 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3595 if (!op0_is_abs)
3597 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3598 if (op0 == NULL)
3599 return NULL_RTX;
3600 target = op0;
3602 else
3604 if (target == NULL_RTX)
3605 target = copy_to_reg (op0);
3606 else
3607 emit_move_insn (target, op0);
3610 label = gen_label_rtx ();
3611 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3613 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3614 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3615 else
3616 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3617 if (op0 != target)
3618 emit_move_insn (target, op0);
3620 emit_label (label);
3622 return target;
3626 /* A subroutine of expand_copysign, perform the entire copysign operation
3627 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3628 is true if op0 is known to have its sign bit clear. */
3630 static rtx
3631 expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3632 int bitpos, bool op0_is_abs)
3634 enum machine_mode imode;
3635 double_int mask;
3636 int word, nwords, i;
3637 rtx temp, insns;
3639 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3641 imode = int_mode_for_mode (mode);
3642 if (imode == BLKmode)
3643 return NULL_RTX;
3644 word = 0;
3645 nwords = 1;
3647 else
3649 imode = word_mode;
3651 if (FLOAT_WORDS_BIG_ENDIAN)
3652 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3653 else
3654 word = bitpos / BITS_PER_WORD;
3655 bitpos = bitpos % BITS_PER_WORD;
3656 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3659 mask = double_int_zero.set_bit (bitpos);
3661 if (target == 0
3662 || target == op0
3663 || target == op1
3664 || (nwords > 1 && !valid_multiword_target_p (target)))
3665 target = gen_reg_rtx (mode);
3667 if (nwords > 1)
3669 start_sequence ();
3671 for (i = 0; i < nwords; ++i)
3673 rtx targ_piece = operand_subword (target, i, 1, mode);
3674 rtx op0_piece = operand_subword_force (op0, i, mode);
3676 if (i == word)
3678 if (!op0_is_abs)
3679 op0_piece
3680 = expand_binop (imode, and_optab, op0_piece,
3681 immed_double_int_const (~mask, imode),
3682 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3684 op1 = expand_binop (imode, and_optab,
3685 operand_subword_force (op1, i, mode),
3686 immed_double_int_const (mask, imode),
3687 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3689 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3690 targ_piece, 1, OPTAB_LIB_WIDEN);
3691 if (temp != targ_piece)
3692 emit_move_insn (targ_piece, temp);
3694 else
3695 emit_move_insn (targ_piece, op0_piece);
3698 insns = get_insns ();
3699 end_sequence ();
3701 emit_insn (insns);
3703 else
3705 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3706 immed_double_int_const (mask, imode),
3707 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3709 op0 = gen_lowpart (imode, op0);
3710 if (!op0_is_abs)
3711 op0 = expand_binop (imode, and_optab, op0,
3712 immed_double_int_const (~mask, imode),
3713 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3715 temp = expand_binop (imode, ior_optab, op0, op1,
3716 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3717 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3720 return target;
3723 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3724 scalar floating point mode. Return NULL if we do not know how to
3725 expand the operation inline. */
3728 expand_copysign (rtx op0, rtx op1, rtx target)
3730 enum machine_mode mode = GET_MODE (op0);
3731 const struct real_format *fmt;
3732 bool op0_is_abs;
3733 rtx temp;
3735 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3736 gcc_assert (GET_MODE (op1) == mode);
3738 /* First try to do it with a special instruction. */
3739 temp = expand_binop (mode, copysign_optab, op0, op1,
3740 target, 0, OPTAB_DIRECT);
3741 if (temp)
3742 return temp;
3744 fmt = REAL_MODE_FORMAT (mode);
3745 if (fmt == NULL || !fmt->has_signed_zero)
3746 return NULL_RTX;
3748 op0_is_abs = false;
3749 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3751 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3752 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3753 op0_is_abs = true;
3756 if (fmt->signbit_ro >= 0
3757 && (CONST_DOUBLE_AS_FLOAT_P (op0)
3758 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3759 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3761 temp = expand_copysign_absneg (mode, op0, op1, target,
3762 fmt->signbit_ro, op0_is_abs);
3763 if (temp)
3764 return temp;
3767 if (fmt->signbit_rw < 0)
3768 return NULL_RTX;
3769 return expand_copysign_bit (mode, op0, op1, target,
3770 fmt->signbit_rw, op0_is_abs);
3773 /* Generate an instruction whose insn-code is INSN_CODE,
3774 with two operands: an output TARGET and an input OP0.
3775 TARGET *must* be nonzero, and the output is always stored there.
3776 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3777 the value that is stored into TARGET.
3779 Return false if expansion failed. */
3781 bool
3782 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3783 enum rtx_code code)
3785 struct expand_operand ops[2];
3786 rtx pat;
3788 create_output_operand (&ops[0], target, GET_MODE (target));
3789 create_input_operand (&ops[1], op0, GET_MODE (op0));
3790 pat = maybe_gen_insn (icode, 2, ops);
3791 if (!pat)
3792 return false;
3794 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3795 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX);
3797 emit_insn (pat);
3799 if (ops[0].value != target)
3800 emit_move_insn (target, ops[0].value);
3801 return true;
3803 /* Generate an instruction whose insn-code is INSN_CODE,
3804 with two operands: an output TARGET and an input OP0.
3805 TARGET *must* be nonzero, and the output is always stored there.
3806 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3807 the value that is stored into TARGET. */
3809 void
3810 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3812 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3813 gcc_assert (ok);
3816 struct no_conflict_data
3818 rtx target, first, insn;
3819 bool must_stay;
3822 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3823 the currently examined clobber / store has to stay in the list of
3824 insns that constitute the actual libcall block. */
3825 static void
3826 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3828 struct no_conflict_data *p= (struct no_conflict_data *) p0;
3830 /* If this inns directly contributes to setting the target, it must stay. */
3831 if (reg_overlap_mentioned_p (p->target, dest))
3832 p->must_stay = true;
3833 /* If we haven't committed to keeping any other insns in the list yet,
3834 there is nothing more to check. */
3835 else if (p->insn == p->first)
3836 return;
3837 /* If this insn sets / clobbers a register that feeds one of the insns
3838 already in the list, this insn has to stay too. */
3839 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3840 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3841 || reg_used_between_p (dest, p->first, p->insn)
3842 /* Likewise if this insn depends on a register set by a previous
3843 insn in the list, or if it sets a result (presumably a hard
3844 register) that is set or clobbered by a previous insn.
3845 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3846 SET_DEST perform the former check on the address, and the latter
3847 check on the MEM. */
3848 || (GET_CODE (set) == SET
3849 && (modified_in_p (SET_SRC (set), p->first)
3850 || modified_in_p (SET_DEST (set), p->first)
3851 || modified_between_p (SET_SRC (set), p->first, p->insn)
3852 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3853 p->must_stay = true;
3857 /* Emit code to make a call to a constant function or a library call.
3859 INSNS is a list containing all insns emitted in the call.
3860 These insns leave the result in RESULT. Our block is to copy RESULT
3861 to TARGET, which is logically equivalent to EQUIV.
3863 We first emit any insns that set a pseudo on the assumption that these are
3864 loading constants into registers; doing so allows them to be safely cse'ed
3865 between blocks. Then we emit all the other insns in the block, followed by
3866 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3867 note with an operand of EQUIV. */
3869 static void
3870 emit_libcall_block_1 (rtx insns, rtx target, rtx result, rtx equiv,
3871 bool equiv_may_trap)
3873 rtx final_dest = target;
3874 rtx next, last, insn;
3876 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3877 into a MEM later. Protect the libcall block from this change. */
3878 if (! REG_P (target) || REG_USERVAR_P (target))
3879 target = gen_reg_rtx (GET_MODE (target));
3881 /* If we're using non-call exceptions, a libcall corresponding to an
3882 operation that may trap may also trap. */
3883 /* ??? See the comment in front of make_reg_eh_region_note. */
3884 if (cfun->can_throw_non_call_exceptions
3885 && (equiv_may_trap || may_trap_p (equiv)))
3887 for (insn = insns; insn; insn = NEXT_INSN (insn))
3888 if (CALL_P (insn))
3890 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3891 if (note)
3893 int lp_nr = INTVAL (XEXP (note, 0));
3894 if (lp_nr == 0 || lp_nr == INT_MIN)
3895 remove_note (insn, note);
3899 else
3901 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3902 reg note to indicate that this call cannot throw or execute a nonlocal
3903 goto (unless there is already a REG_EH_REGION note, in which case
3904 we update it). */
3905 for (insn = insns; insn; insn = NEXT_INSN (insn))
3906 if (CALL_P (insn))
3907 make_reg_eh_region_note_nothrow_nononlocal (insn);
3910 /* First emit all insns that set pseudos. Remove them from the list as
3911 we go. Avoid insns that set pseudos which were referenced in previous
3912 insns. These can be generated by move_by_pieces, for example,
3913 to update an address. Similarly, avoid insns that reference things
3914 set in previous insns. */
3916 for (insn = insns; insn; insn = next)
3918 rtx set = single_set (insn);
3920 next = NEXT_INSN (insn);
3922 if (set != 0 && REG_P (SET_DEST (set))
3923 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3925 struct no_conflict_data data;
3927 data.target = const0_rtx;
3928 data.first = insns;
3929 data.insn = insn;
3930 data.must_stay = 0;
3931 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3932 if (! data.must_stay)
3934 if (PREV_INSN (insn))
3935 NEXT_INSN (PREV_INSN (insn)) = next;
3936 else
3937 insns = next;
3939 if (next)
3940 PREV_INSN (next) = PREV_INSN (insn);
3942 add_insn (insn);
3946 /* Some ports use a loop to copy large arguments onto the stack.
3947 Don't move anything outside such a loop. */
3948 if (LABEL_P (insn))
3949 break;
3952 /* Write the remaining insns followed by the final copy. */
3953 for (insn = insns; insn; insn = next)
3955 next = NEXT_INSN (insn);
3957 add_insn (insn);
3960 last = emit_move_insn (target, result);
3961 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
3963 if (final_dest != target)
3964 emit_move_insn (final_dest, target);
3967 void
3968 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3970 emit_libcall_block_1 (insns, target, result, equiv, false);
3973 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3974 PURPOSE describes how this comparison will be used. CODE is the rtx
3975 comparison code we will be using.
3977 ??? Actually, CODE is slightly weaker than that. A target is still
3978 required to implement all of the normal bcc operations, but not
3979 required to implement all (or any) of the unordered bcc operations. */
3982 can_compare_p (enum rtx_code code, enum machine_mode mode,
3983 enum can_compare_purpose purpose)
3985 rtx test;
3986 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
3989 enum insn_code icode;
3991 if (purpose == ccp_jump
3992 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
3993 && insn_operand_matches (icode, 0, test))
3994 return 1;
3995 if (purpose == ccp_store_flag
3996 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
3997 && insn_operand_matches (icode, 1, test))
3998 return 1;
3999 if (purpose == ccp_cmov
4000 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
4001 return 1;
4003 mode = GET_MODE_WIDER_MODE (mode);
4004 PUT_MODE (test, mode);
4006 while (mode != VOIDmode);
4008 return 0;
4011 /* This function is called when we are going to emit a compare instruction that
4012 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
4014 *PMODE is the mode of the inputs (in case they are const_int).
4015 *PUNSIGNEDP nonzero says that the operands are unsigned;
4016 this matters if they need to be widened (as given by METHODS).
4018 If they have mode BLKmode, then SIZE specifies the size of both operands.
4020 This function performs all the setup necessary so that the caller only has
4021 to emit a single comparison insn. This setup can involve doing a BLKmode
4022 comparison or emitting a library call to perform the comparison if no insn
4023 is available to handle it.
4024 The values which are passed in through pointers can be modified; the caller
4025 should perform the comparison on the modified values. Constant
4026 comparisons must have already been folded. */
4028 static void
4029 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4030 int unsignedp, enum optab_methods methods,
4031 rtx *ptest, enum machine_mode *pmode)
4033 enum machine_mode mode = *pmode;
4034 rtx libfunc, test;
4035 enum machine_mode cmp_mode;
4036 enum mode_class mclass;
4038 /* The other methods are not needed. */
4039 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
4040 || methods == OPTAB_LIB_WIDEN);
4042 /* If we are optimizing, force expensive constants into a register. */
4043 if (CONSTANT_P (x) && optimize
4044 && (rtx_cost (x, COMPARE, 0, optimize_insn_for_speed_p ())
4045 > COSTS_N_INSNS (1)))
4046 x = force_reg (mode, x);
4048 if (CONSTANT_P (y) && optimize
4049 && (rtx_cost (y, COMPARE, 1, optimize_insn_for_speed_p ())
4050 > COSTS_N_INSNS (1)))
4051 y = force_reg (mode, y);
4053 #ifdef HAVE_cc0
4054 /* Make sure if we have a canonical comparison. The RTL
4055 documentation states that canonical comparisons are required only
4056 for targets which have cc0. */
4057 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
4058 #endif
4060 /* Don't let both operands fail to indicate the mode. */
4061 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
4062 x = force_reg (mode, x);
4063 if (mode == VOIDmode)
4064 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
4066 /* Handle all BLKmode compares. */
4068 if (mode == BLKmode)
4070 enum machine_mode result_mode;
4071 enum insn_code cmp_code;
4072 tree length_type;
4073 rtx libfunc;
4074 rtx result;
4075 rtx opalign
4076 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
4078 gcc_assert (size);
4080 /* Try to use a memory block compare insn - either cmpstr
4081 or cmpmem will do. */
4082 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
4083 cmp_mode != VOIDmode;
4084 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
4086 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
4087 if (cmp_code == CODE_FOR_nothing)
4088 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
4089 if (cmp_code == CODE_FOR_nothing)
4090 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
4091 if (cmp_code == CODE_FOR_nothing)
4092 continue;
4094 /* Must make sure the size fits the insn's mode. */
4095 if ((CONST_INT_P (size)
4096 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
4097 || (GET_MODE_BITSIZE (GET_MODE (size))
4098 > GET_MODE_BITSIZE (cmp_mode)))
4099 continue;
4101 result_mode = insn_data[cmp_code].operand[0].mode;
4102 result = gen_reg_rtx (result_mode);
4103 size = convert_to_mode (cmp_mode, size, 1);
4104 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
4106 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
4107 *pmode = result_mode;
4108 return;
4111 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
4112 goto fail;
4114 /* Otherwise call a library function, memcmp. */
4115 libfunc = memcmp_libfunc;
4116 length_type = sizetype;
4117 result_mode = TYPE_MODE (integer_type_node);
4118 cmp_mode = TYPE_MODE (length_type);
4119 size = convert_to_mode (TYPE_MODE (length_type), size,
4120 TYPE_UNSIGNED (length_type));
4122 result = emit_library_call_value (libfunc, 0, LCT_PURE,
4123 result_mode, 3,
4124 XEXP (x, 0), Pmode,
4125 XEXP (y, 0), Pmode,
4126 size, cmp_mode);
4127 x = result;
4128 y = const0_rtx;
4129 mode = result_mode;
4130 methods = OPTAB_LIB_WIDEN;
4131 unsignedp = false;
4134 /* Don't allow operands to the compare to trap, as that can put the
4135 compare and branch in different basic blocks. */
4136 if (cfun->can_throw_non_call_exceptions)
4138 if (may_trap_p (x))
4139 x = force_reg (mode, x);
4140 if (may_trap_p (y))
4141 y = force_reg (mode, y);
4144 if (GET_MODE_CLASS (mode) == MODE_CC)
4146 gcc_assert (can_compare_p (comparison, CCmode, ccp_jump));
4147 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4148 return;
4151 mclass = GET_MODE_CLASS (mode);
4152 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4153 cmp_mode = mode;
4156 enum insn_code icode;
4157 icode = optab_handler (cbranch_optab, cmp_mode);
4158 if (icode != CODE_FOR_nothing
4159 && insn_operand_matches (icode, 0, test))
4161 rtx last = get_last_insn ();
4162 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
4163 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
4164 if (op0 && op1
4165 && insn_operand_matches (icode, 1, op0)
4166 && insn_operand_matches (icode, 2, op1))
4168 XEXP (test, 0) = op0;
4169 XEXP (test, 1) = op1;
4170 *ptest = test;
4171 *pmode = cmp_mode;
4172 return;
4174 delete_insns_since (last);
4177 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
4178 break;
4179 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode);
4181 while (cmp_mode != VOIDmode);
4183 if (methods != OPTAB_LIB_WIDEN)
4184 goto fail;
4186 if (!SCALAR_FLOAT_MODE_P (mode))
4188 rtx result;
4189 enum machine_mode ret_mode;
4191 /* Handle a libcall just for the mode we are using. */
4192 libfunc = optab_libfunc (cmp_optab, mode);
4193 gcc_assert (libfunc);
4195 /* If we want unsigned, and this mode has a distinct unsigned
4196 comparison routine, use that. */
4197 if (unsignedp)
4199 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
4200 if (ulibfunc)
4201 libfunc = ulibfunc;
4204 ret_mode = targetm.libgcc_cmp_return_mode ();
4205 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4206 ret_mode, 2, x, mode, y, mode);
4208 /* There are two kinds of comparison routines. Biased routines
4209 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4210 of gcc expect that the comparison operation is equivalent
4211 to the modified comparison. For signed comparisons compare the
4212 result against 1 in the biased case, and zero in the unbiased
4213 case. For unsigned comparisons always compare against 1 after
4214 biasing the unbiased result by adding 1. This gives us a way to
4215 represent LTU.
4216 The comparisons in the fixed-point helper library are always
4217 biased. */
4218 x = result;
4219 y = const1_rtx;
4221 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
4223 if (unsignedp)
4224 x = plus_constant (ret_mode, result, 1);
4225 else
4226 y = const0_rtx;
4229 *pmode = word_mode;
4230 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
4231 ptest, pmode);
4233 else
4234 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
4236 return;
4238 fail:
4239 *ptest = NULL_RTX;
4242 /* Before emitting an insn with code ICODE, make sure that X, which is going
4243 to be used for operand OPNUM of the insn, is converted from mode MODE to
4244 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4245 that it is accepted by the operand predicate. Return the new value. */
4248 prepare_operand (enum insn_code icode, rtx x, int opnum, enum machine_mode mode,
4249 enum machine_mode wider_mode, int unsignedp)
4251 if (mode != wider_mode)
4252 x = convert_modes (wider_mode, mode, x, unsignedp);
4254 if (!insn_operand_matches (icode, opnum, x))
4256 if (reload_completed)
4257 return NULL_RTX;
4258 x = copy_to_mode_reg (insn_data[(int) icode].operand[opnum].mode, x);
4261 return x;
4264 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4265 we can do the branch. */
4267 static void
4268 emit_cmp_and_jump_insn_1 (rtx test, enum machine_mode mode, rtx label, int prob)
4270 enum machine_mode optab_mode;
4271 enum mode_class mclass;
4272 enum insn_code icode;
4273 rtx insn;
4275 mclass = GET_MODE_CLASS (mode);
4276 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
4277 icode = optab_handler (cbranch_optab, optab_mode);
4279 gcc_assert (icode != CODE_FOR_nothing);
4280 gcc_assert (insn_operand_matches (icode, 0, test));
4281 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
4282 XEXP (test, 1), label));
4283 if (prob != -1
4284 && profile_status != PROFILE_ABSENT
4285 && insn
4286 && JUMP_P (insn)
4287 && any_condjump_p (insn)
4288 && !find_reg_note (insn, REG_BR_PROB, 0))
4289 add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
4292 /* Generate code to compare X with Y so that the condition codes are
4293 set and to jump to LABEL if the condition is true. If X is a
4294 constant and Y is not a constant, then the comparison is swapped to
4295 ensure that the comparison RTL has the canonical form.
4297 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4298 need to be widened. UNSIGNEDP is also used to select the proper
4299 branch condition code.
4301 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4303 MODE is the mode of the inputs (in case they are const_int).
4305 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4306 It will be potentially converted into an unsigned variant based on
4307 UNSIGNEDP to select a proper jump instruction.
4309 PROB is the probability of jumping to LABEL. */
4311 void
4312 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4313 enum machine_mode mode, int unsignedp, rtx label,
4314 int prob)
4316 rtx op0 = x, op1 = y;
4317 rtx test;
4319 /* Swap operands and condition to ensure canonical RTL. */
4320 if (swap_commutative_operands_p (x, y)
4321 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4323 op0 = y, op1 = x;
4324 comparison = swap_condition (comparison);
4327 /* If OP0 is still a constant, then both X and Y must be constants
4328 or the opposite comparison is not supported. Force X into a register
4329 to create canonical RTL. */
4330 if (CONSTANT_P (op0))
4331 op0 = force_reg (mode, op0);
4333 if (unsignedp)
4334 comparison = unsigned_condition (comparison);
4336 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4337 &test, &mode);
4338 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
4342 /* Emit a library call comparison between floating point X and Y.
4343 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4345 static void
4346 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4347 rtx *ptest, enum machine_mode *pmode)
4349 enum rtx_code swapped = swap_condition (comparison);
4350 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4351 enum machine_mode orig_mode = GET_MODE (x);
4352 enum machine_mode mode, cmp_mode;
4353 rtx true_rtx, false_rtx;
4354 rtx value, target, insns, equiv;
4355 rtx libfunc = 0;
4356 bool reversed_p = false;
4357 cmp_mode = targetm.libgcc_cmp_return_mode ();
4359 for (mode = orig_mode;
4360 mode != VOIDmode;
4361 mode = GET_MODE_WIDER_MODE (mode))
4363 if (code_to_optab (comparison)
4364 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
4365 break;
4367 if (code_to_optab (swapped)
4368 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
4370 rtx tmp;
4371 tmp = x; x = y; y = tmp;
4372 comparison = swapped;
4373 break;
4376 if (code_to_optab (reversed)
4377 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4379 comparison = reversed;
4380 reversed_p = true;
4381 break;
4385 gcc_assert (mode != VOIDmode);
4387 if (mode != orig_mode)
4389 x = convert_to_mode (mode, x, 0);
4390 y = convert_to_mode (mode, y, 0);
4393 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4394 the RTL. The allows the RTL optimizers to delete the libcall if the
4395 condition can be determined at compile-time. */
4396 if (comparison == UNORDERED
4397 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4399 true_rtx = const_true_rtx;
4400 false_rtx = const0_rtx;
4402 else
4404 switch (comparison)
4406 case EQ:
4407 true_rtx = const0_rtx;
4408 false_rtx = const_true_rtx;
4409 break;
4411 case NE:
4412 true_rtx = const_true_rtx;
4413 false_rtx = const0_rtx;
4414 break;
4416 case GT:
4417 true_rtx = const1_rtx;
4418 false_rtx = const0_rtx;
4419 break;
4421 case GE:
4422 true_rtx = const0_rtx;
4423 false_rtx = constm1_rtx;
4424 break;
4426 case LT:
4427 true_rtx = constm1_rtx;
4428 false_rtx = const0_rtx;
4429 break;
4431 case LE:
4432 true_rtx = const0_rtx;
4433 false_rtx = const1_rtx;
4434 break;
4436 default:
4437 gcc_unreachable ();
4441 if (comparison == UNORDERED)
4443 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4444 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4445 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4446 temp, const_true_rtx, equiv);
4448 else
4450 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4451 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4452 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4453 equiv, true_rtx, false_rtx);
4456 start_sequence ();
4457 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4458 cmp_mode, 2, x, mode, y, mode);
4459 insns = get_insns ();
4460 end_sequence ();
4462 target = gen_reg_rtx (cmp_mode);
4463 emit_libcall_block (insns, target, value, equiv);
4465 if (comparison == UNORDERED
4466 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4467 || reversed_p)
4468 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4469 else
4470 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4472 *pmode = cmp_mode;
4475 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4477 void
4478 emit_indirect_jump (rtx loc)
4480 struct expand_operand ops[1];
4482 create_address_operand (&ops[0], loc);
4483 expand_jump_insn (CODE_FOR_indirect_jump, 1, ops);
4484 emit_barrier ();
4487 #ifdef HAVE_conditional_move
4489 /* Emit a conditional move instruction if the machine supports one for that
4490 condition and machine mode.
4492 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4493 the mode to use should they be constants. If it is VOIDmode, they cannot
4494 both be constants.
4496 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4497 should be stored there. MODE is the mode to use should they be constants.
4498 If it is VOIDmode, they cannot both be constants.
4500 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4501 is not supported. */
4504 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4505 enum machine_mode cmode, rtx op2, rtx op3,
4506 enum machine_mode mode, int unsignedp)
4508 rtx tem, comparison, last;
4509 enum insn_code icode;
4510 enum rtx_code reversed;
4512 /* If one operand is constant, make it the second one. Only do this
4513 if the other operand is not constant as well. */
4515 if (swap_commutative_operands_p (op0, op1))
4517 tem = op0;
4518 op0 = op1;
4519 op1 = tem;
4520 code = swap_condition (code);
4523 /* get_condition will prefer to generate LT and GT even if the old
4524 comparison was against zero, so undo that canonicalization here since
4525 comparisons against zero are cheaper. */
4526 if (code == LT && op1 == const1_rtx)
4527 code = LE, op1 = const0_rtx;
4528 else if (code == GT && op1 == constm1_rtx)
4529 code = GE, op1 = const0_rtx;
4531 if (cmode == VOIDmode)
4532 cmode = GET_MODE (op0);
4534 if (swap_commutative_operands_p (op2, op3)
4535 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4536 != UNKNOWN))
4538 tem = op2;
4539 op2 = op3;
4540 op3 = tem;
4541 code = reversed;
4544 if (mode == VOIDmode)
4545 mode = GET_MODE (op2);
4547 icode = direct_optab_handler (movcc_optab, mode);
4549 if (icode == CODE_FOR_nothing)
4550 return 0;
4552 if (!target)
4553 target = gen_reg_rtx (mode);
4555 code = unsignedp ? unsigned_condition (code) : code;
4556 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4558 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4559 return NULL and let the caller figure out how best to deal with this
4560 situation. */
4561 if (!COMPARISON_P (comparison))
4562 return NULL_RTX;
4564 /* State variables we need to save and restore if cmove can't be used. */
4565 int save_pending_stack_adjust = pending_stack_adjust;
4566 int save_stack_pointer_delta = stack_pointer_delta;
4567 last = get_last_insn ();
4568 do_pending_stack_adjust ();
4569 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4570 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4571 &comparison, &cmode);
4572 if (comparison)
4574 struct expand_operand ops[4];
4576 create_output_operand (&ops[0], target, mode);
4577 create_fixed_operand (&ops[1], comparison);
4578 create_input_operand (&ops[2], op2, mode);
4579 create_input_operand (&ops[3], op3, mode);
4580 if (maybe_expand_insn (icode, 4, ops))
4582 if (ops[0].value != target)
4583 convert_move (target, ops[0].value, false);
4584 return target;
4587 delete_insns_since (last);
4588 pending_stack_adjust = save_pending_stack_adjust;
4589 stack_pointer_delta = save_stack_pointer_delta;
4590 return NULL_RTX;
4593 /* Return nonzero if a conditional move of mode MODE is supported.
4595 This function is for combine so it can tell whether an insn that looks
4596 like a conditional move is actually supported by the hardware. If we
4597 guess wrong we lose a bit on optimization, but that's it. */
4598 /* ??? sparc64 supports conditionally moving integers values based on fp
4599 comparisons, and vice versa. How do we handle them? */
4602 can_conditionally_move_p (enum machine_mode mode)
4604 if (direct_optab_handler (movcc_optab, mode) != CODE_FOR_nothing)
4605 return 1;
4607 return 0;
4610 #endif /* HAVE_conditional_move */
4612 /* Emit a conditional addition instruction if the machine supports one for that
4613 condition and machine mode.
4615 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4616 the mode to use should they be constants. If it is VOIDmode, they cannot
4617 both be constants.
4619 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4620 should be stored there. MODE is the mode to use should they be constants.
4621 If it is VOIDmode, they cannot both be constants.
4623 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4624 is not supported. */
4627 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4628 enum machine_mode cmode, rtx op2, rtx op3,
4629 enum machine_mode mode, int unsignedp)
4631 rtx tem, comparison, last;
4632 enum insn_code icode;
4634 /* If one operand is constant, make it the second one. Only do this
4635 if the other operand is not constant as well. */
4637 if (swap_commutative_operands_p (op0, op1))
4639 tem = op0;
4640 op0 = op1;
4641 op1 = tem;
4642 code = swap_condition (code);
4645 /* get_condition will prefer to generate LT and GT even if the old
4646 comparison was against zero, so undo that canonicalization here since
4647 comparisons against zero are cheaper. */
4648 if (code == LT && op1 == const1_rtx)
4649 code = LE, op1 = const0_rtx;
4650 else if (code == GT && op1 == constm1_rtx)
4651 code = GE, op1 = const0_rtx;
4653 if (cmode == VOIDmode)
4654 cmode = GET_MODE (op0);
4656 if (mode == VOIDmode)
4657 mode = GET_MODE (op2);
4659 icode = optab_handler (addcc_optab, mode);
4661 if (icode == CODE_FOR_nothing)
4662 return 0;
4664 if (!target)
4665 target = gen_reg_rtx (mode);
4667 code = unsignedp ? unsigned_condition (code) : code;
4668 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4670 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4671 return NULL and let the caller figure out how best to deal with this
4672 situation. */
4673 if (!COMPARISON_P (comparison))
4674 return NULL_RTX;
4676 do_pending_stack_adjust ();
4677 last = get_last_insn ();
4678 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4679 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4680 &comparison, &cmode);
4681 if (comparison)
4683 struct expand_operand ops[4];
4685 create_output_operand (&ops[0], target, mode);
4686 create_fixed_operand (&ops[1], comparison);
4687 create_input_operand (&ops[2], op2, mode);
4688 create_input_operand (&ops[3], op3, mode);
4689 if (maybe_expand_insn (icode, 4, ops))
4691 if (ops[0].value != target)
4692 convert_move (target, ops[0].value, false);
4693 return target;
4696 delete_insns_since (last);
4697 return NULL_RTX;
4700 /* These functions attempt to generate an insn body, rather than
4701 emitting the insn, but if the gen function already emits them, we
4702 make no attempt to turn them back into naked patterns. */
4704 /* Generate and return an insn body to add Y to X. */
4707 gen_add2_insn (rtx x, rtx y)
4709 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
4711 gcc_assert (insn_operand_matches (icode, 0, x));
4712 gcc_assert (insn_operand_matches (icode, 1, x));
4713 gcc_assert (insn_operand_matches (icode, 2, y));
4715 return GEN_FCN (icode) (x, x, y);
4718 /* Generate and return an insn body to add r1 and c,
4719 storing the result in r0. */
4722 gen_add3_insn (rtx r0, rtx r1, rtx c)
4724 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
4726 if (icode == CODE_FOR_nothing
4727 || !insn_operand_matches (icode, 0, r0)
4728 || !insn_operand_matches (icode, 1, r1)
4729 || !insn_operand_matches (icode, 2, c))
4730 return NULL_RTX;
4732 return GEN_FCN (icode) (r0, r1, c);
4736 have_add2_insn (rtx x, rtx y)
4738 enum insn_code icode;
4740 gcc_assert (GET_MODE (x) != VOIDmode);
4742 icode = optab_handler (add_optab, GET_MODE (x));
4744 if (icode == CODE_FOR_nothing)
4745 return 0;
4747 if (!insn_operand_matches (icode, 0, x)
4748 || !insn_operand_matches (icode, 1, x)
4749 || !insn_operand_matches (icode, 2, y))
4750 return 0;
4752 return 1;
4755 /* Generate and return an insn body to subtract Y from X. */
4758 gen_sub2_insn (rtx x, rtx y)
4760 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
4762 gcc_assert (insn_operand_matches (icode, 0, x));
4763 gcc_assert (insn_operand_matches (icode, 1, x));
4764 gcc_assert (insn_operand_matches (icode, 2, y));
4766 return GEN_FCN (icode) (x, x, y);
4769 /* Generate and return an insn body to subtract r1 and c,
4770 storing the result in r0. */
4773 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4775 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
4777 if (icode == CODE_FOR_nothing
4778 || !insn_operand_matches (icode, 0, r0)
4779 || !insn_operand_matches (icode, 1, r1)
4780 || !insn_operand_matches (icode, 2, c))
4781 return NULL_RTX;
4783 return GEN_FCN (icode) (r0, r1, c);
4787 have_sub2_insn (rtx x, rtx y)
4789 enum insn_code icode;
4791 gcc_assert (GET_MODE (x) != VOIDmode);
4793 icode = optab_handler (sub_optab, GET_MODE (x));
4795 if (icode == CODE_FOR_nothing)
4796 return 0;
4798 if (!insn_operand_matches (icode, 0, x)
4799 || !insn_operand_matches (icode, 1, x)
4800 || !insn_operand_matches (icode, 2, y))
4801 return 0;
4803 return 1;
4806 /* Generate the body of an instruction to copy Y into X.
4807 It may be a list of insns, if one insn isn't enough. */
4810 gen_move_insn (rtx x, rtx y)
4812 rtx seq;
4814 start_sequence ();
4815 emit_move_insn_1 (x, y);
4816 seq = get_insns ();
4817 end_sequence ();
4818 return seq;
4821 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4822 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4823 no such operation exists, CODE_FOR_nothing will be returned. */
4825 enum insn_code
4826 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4827 int unsignedp)
4829 convert_optab tab;
4830 #ifdef HAVE_ptr_extend
4831 if (unsignedp < 0)
4832 return CODE_FOR_ptr_extend;
4833 #endif
4835 tab = unsignedp ? zext_optab : sext_optab;
4836 return convert_optab_handler (tab, to_mode, from_mode);
4839 /* Generate the body of an insn to extend Y (with mode MFROM)
4840 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4843 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4844 enum machine_mode mfrom, int unsignedp)
4846 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4847 return GEN_FCN (icode) (x, y);
4850 /* can_fix_p and can_float_p say whether the target machine
4851 can directly convert a given fixed point type to
4852 a given floating point type, or vice versa.
4853 The returned value is the CODE_FOR_... value to use,
4854 or CODE_FOR_nothing if these modes cannot be directly converted.
4856 *TRUNCP_PTR is set to 1 if it is necessary to output
4857 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4859 static enum insn_code
4860 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4861 int unsignedp, int *truncp_ptr)
4863 convert_optab tab;
4864 enum insn_code icode;
4866 tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4867 icode = convert_optab_handler (tab, fixmode, fltmode);
4868 if (icode != CODE_FOR_nothing)
4870 *truncp_ptr = 0;
4871 return icode;
4874 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4875 for this to work. We need to rework the fix* and ftrunc* patterns
4876 and documentation. */
4877 tab = unsignedp ? ufix_optab : sfix_optab;
4878 icode = convert_optab_handler (tab, fixmode, fltmode);
4879 if (icode != CODE_FOR_nothing
4880 && optab_handler (ftrunc_optab, fltmode) != CODE_FOR_nothing)
4882 *truncp_ptr = 1;
4883 return icode;
4886 *truncp_ptr = 0;
4887 return CODE_FOR_nothing;
4890 enum insn_code
4891 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4892 int unsignedp)
4894 convert_optab tab;
4896 tab = unsignedp ? ufloat_optab : sfloat_optab;
4897 return convert_optab_handler (tab, fltmode, fixmode);
4900 /* Function supportable_convert_operation
4902 Check whether an operation represented by the code CODE is a
4903 convert operation that is supported by the target platform in
4904 vector form (i.e., when operating on arguments of type VECTYPE_IN
4905 producing a result of type VECTYPE_OUT).
4907 Convert operations we currently support directly are FIX_TRUNC and FLOAT.
4908 This function checks if these operations are supported
4909 by the target platform either directly (via vector tree-codes), or via
4910 target builtins.
4912 Output:
4913 - CODE1 is code of vector operation to be used when
4914 vectorizing the operation, if available.
4915 - DECL is decl of target builtin functions to be used
4916 when vectorizing the operation, if available. In this case,
4917 CODE1 is CALL_EXPR. */
4919 bool
4920 supportable_convert_operation (enum tree_code code,
4921 tree vectype_out, tree vectype_in,
4922 tree *decl, enum tree_code *code1)
4924 enum machine_mode m1,m2;
4925 int truncp;
4927 m1 = TYPE_MODE (vectype_out);
4928 m2 = TYPE_MODE (vectype_in);
4930 /* First check if we can done conversion directly. */
4931 if ((code == FIX_TRUNC_EXPR
4932 && can_fix_p (m1,m2,TYPE_UNSIGNED (vectype_out), &truncp)
4933 != CODE_FOR_nothing)
4934 || (code == FLOAT_EXPR
4935 && can_float_p (m1,m2,TYPE_UNSIGNED (vectype_in))
4936 != CODE_FOR_nothing))
4938 *code1 = code;
4939 return true;
4942 /* Now check for builtin. */
4943 if (targetm.vectorize.builtin_conversion
4944 && targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in))
4946 *code1 = CALL_EXPR;
4947 *decl = targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in);
4948 return true;
4950 return false;
4954 /* Generate code to convert FROM to floating point
4955 and store in TO. FROM must be fixed point and not VOIDmode.
4956 UNSIGNEDP nonzero means regard FROM as unsigned.
4957 Normally this is done by correcting the final value
4958 if it is negative. */
4960 void
4961 expand_float (rtx to, rtx from, int unsignedp)
4963 enum insn_code icode;
4964 rtx target = to;
4965 enum machine_mode fmode, imode;
4966 bool can_do_signed = false;
4968 /* Crash now, because we won't be able to decide which mode to use. */
4969 gcc_assert (GET_MODE (from) != VOIDmode);
4971 /* Look for an insn to do the conversion. Do it in the specified
4972 modes if possible; otherwise convert either input, output or both to
4973 wider mode. If the integer mode is wider than the mode of FROM,
4974 we can do the conversion signed even if the input is unsigned. */
4976 for (fmode = GET_MODE (to); fmode != VOIDmode;
4977 fmode = GET_MODE_WIDER_MODE (fmode))
4978 for (imode = GET_MODE (from); imode != VOIDmode;
4979 imode = GET_MODE_WIDER_MODE (imode))
4981 int doing_unsigned = unsignedp;
4983 if (fmode != GET_MODE (to)
4984 && significand_size (fmode) < GET_MODE_PRECISION (GET_MODE (from)))
4985 continue;
4987 icode = can_float_p (fmode, imode, unsignedp);
4988 if (icode == CODE_FOR_nothing && unsignedp)
4990 enum insn_code scode = can_float_p (fmode, imode, 0);
4991 if (scode != CODE_FOR_nothing)
4992 can_do_signed = true;
4993 if (imode != GET_MODE (from))
4994 icode = scode, doing_unsigned = 0;
4997 if (icode != CODE_FOR_nothing)
4999 if (imode != GET_MODE (from))
5000 from = convert_to_mode (imode, from, unsignedp);
5002 if (fmode != GET_MODE (to))
5003 target = gen_reg_rtx (fmode);
5005 emit_unop_insn (icode, target, from,
5006 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
5008 if (target != to)
5009 convert_move (to, target, 0);
5010 return;
5014 /* Unsigned integer, and no way to convert directly. Convert as signed,
5015 then unconditionally adjust the result. */
5016 if (unsignedp && can_do_signed)
5018 rtx label = gen_label_rtx ();
5019 rtx temp;
5020 REAL_VALUE_TYPE offset;
5022 /* Look for a usable floating mode FMODE wider than the source and at
5023 least as wide as the target. Using FMODE will avoid rounding woes
5024 with unsigned values greater than the signed maximum value. */
5026 for (fmode = GET_MODE (to); fmode != VOIDmode;
5027 fmode = GET_MODE_WIDER_MODE (fmode))
5028 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
5029 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
5030 break;
5032 if (fmode == VOIDmode)
5034 /* There is no such mode. Pretend the target is wide enough. */
5035 fmode = GET_MODE (to);
5037 /* Avoid double-rounding when TO is narrower than FROM. */
5038 if ((significand_size (fmode) + 1)
5039 < GET_MODE_PRECISION (GET_MODE (from)))
5041 rtx temp1;
5042 rtx neglabel = gen_label_rtx ();
5044 /* Don't use TARGET if it isn't a register, is a hard register,
5045 or is the wrong mode. */
5046 if (!REG_P (target)
5047 || REGNO (target) < FIRST_PSEUDO_REGISTER
5048 || GET_MODE (target) != fmode)
5049 target = gen_reg_rtx (fmode);
5051 imode = GET_MODE (from);
5052 do_pending_stack_adjust ();
5054 /* Test whether the sign bit is set. */
5055 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
5056 0, neglabel);
5058 /* The sign bit is not set. Convert as signed. */
5059 expand_float (target, from, 0);
5060 emit_jump_insn (gen_jump (label));
5061 emit_barrier ();
5063 /* The sign bit is set.
5064 Convert to a usable (positive signed) value by shifting right
5065 one bit, while remembering if a nonzero bit was shifted
5066 out; i.e., compute (from & 1) | (from >> 1). */
5068 emit_label (neglabel);
5069 temp = expand_binop (imode, and_optab, from, const1_rtx,
5070 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5071 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
5072 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
5073 OPTAB_LIB_WIDEN);
5074 expand_float (target, temp, 0);
5076 /* Multiply by 2 to undo the shift above. */
5077 temp = expand_binop (fmode, add_optab, target, target,
5078 target, 0, OPTAB_LIB_WIDEN);
5079 if (temp != target)
5080 emit_move_insn (target, temp);
5082 do_pending_stack_adjust ();
5083 emit_label (label);
5084 goto done;
5088 /* If we are about to do some arithmetic to correct for an
5089 unsigned operand, do it in a pseudo-register. */
5091 if (GET_MODE (to) != fmode
5092 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
5093 target = gen_reg_rtx (fmode);
5095 /* Convert as signed integer to floating. */
5096 expand_float (target, from, 0);
5098 /* If FROM is negative (and therefore TO is negative),
5099 correct its value by 2**bitwidth. */
5101 do_pending_stack_adjust ();
5102 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
5103 0, label);
5106 real_2expN (&offset, GET_MODE_PRECISION (GET_MODE (from)), fmode);
5107 temp = expand_binop (fmode, add_optab, target,
5108 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
5109 target, 0, OPTAB_LIB_WIDEN);
5110 if (temp != target)
5111 emit_move_insn (target, temp);
5113 do_pending_stack_adjust ();
5114 emit_label (label);
5115 goto done;
5118 /* No hardware instruction available; call a library routine. */
5120 rtx libfunc;
5121 rtx insns;
5122 rtx value;
5123 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
5125 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
5126 from = convert_to_mode (SImode, from, unsignedp);
5128 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5129 gcc_assert (libfunc);
5131 start_sequence ();
5133 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5134 GET_MODE (to), 1, from,
5135 GET_MODE (from));
5136 insns = get_insns ();
5137 end_sequence ();
5139 emit_libcall_block (insns, target, value,
5140 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
5141 GET_MODE (to), from));
5144 done:
5146 /* Copy result to requested destination
5147 if we have been computing in a temp location. */
5149 if (target != to)
5151 if (GET_MODE (target) == GET_MODE (to))
5152 emit_move_insn (to, target);
5153 else
5154 convert_move (to, target, 0);
5158 /* Generate code to convert FROM to fixed point and store in TO. FROM
5159 must be floating point. */
5161 void
5162 expand_fix (rtx to, rtx from, int unsignedp)
5164 enum insn_code icode;
5165 rtx target = to;
5166 enum machine_mode fmode, imode;
5167 int must_trunc = 0;
5169 /* We first try to find a pair of modes, one real and one integer, at
5170 least as wide as FROM and TO, respectively, in which we can open-code
5171 this conversion. If the integer mode is wider than the mode of TO,
5172 we can do the conversion either signed or unsigned. */
5174 for (fmode = GET_MODE (from); fmode != VOIDmode;
5175 fmode = GET_MODE_WIDER_MODE (fmode))
5176 for (imode = GET_MODE (to); imode != VOIDmode;
5177 imode = GET_MODE_WIDER_MODE (imode))
5179 int doing_unsigned = unsignedp;
5181 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5182 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5183 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5185 if (icode != CODE_FOR_nothing)
5187 rtx last = get_last_insn ();
5188 if (fmode != GET_MODE (from))
5189 from = convert_to_mode (fmode, from, 0);
5191 if (must_trunc)
5193 rtx temp = gen_reg_rtx (GET_MODE (from));
5194 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
5195 temp, 0);
5198 if (imode != GET_MODE (to))
5199 target = gen_reg_rtx (imode);
5201 if (maybe_emit_unop_insn (icode, target, from,
5202 doing_unsigned ? UNSIGNED_FIX : FIX))
5204 if (target != to)
5205 convert_move (to, target, unsignedp);
5206 return;
5208 delete_insns_since (last);
5212 /* For an unsigned conversion, there is one more way to do it.
5213 If we have a signed conversion, we generate code that compares
5214 the real value to the largest representable positive number. If if
5215 is smaller, the conversion is done normally. Otherwise, subtract
5216 one plus the highest signed number, convert, and add it back.
5218 We only need to check all real modes, since we know we didn't find
5219 anything with a wider integer mode.
5221 This code used to extend FP value into mode wider than the destination.
5222 This is needed for decimal float modes which cannot accurately
5223 represent one plus the highest signed number of the same size, but
5224 not for binary modes. Consider, for instance conversion from SFmode
5225 into DImode.
5227 The hot path through the code is dealing with inputs smaller than 2^63
5228 and doing just the conversion, so there is no bits to lose.
5230 In the other path we know the value is positive in the range 2^63..2^64-1
5231 inclusive. (as for other input overflow happens and result is undefined)
5232 So we know that the most important bit set in mantissa corresponds to
5233 2^63. The subtraction of 2^63 should not generate any rounding as it
5234 simply clears out that bit. The rest is trivial. */
5236 if (unsignedp && GET_MODE_PRECISION (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
5237 for (fmode = GET_MODE (from); fmode != VOIDmode;
5238 fmode = GET_MODE_WIDER_MODE (fmode))
5239 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
5240 && (!DECIMAL_FLOAT_MODE_P (fmode)
5241 || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (GET_MODE (to))))
5243 int bitsize;
5244 REAL_VALUE_TYPE offset;
5245 rtx limit, lab1, lab2, insn;
5247 bitsize = GET_MODE_PRECISION (GET_MODE (to));
5248 real_2expN (&offset, bitsize - 1, fmode);
5249 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
5250 lab1 = gen_label_rtx ();
5251 lab2 = gen_label_rtx ();
5253 if (fmode != GET_MODE (from))
5254 from = convert_to_mode (fmode, from, 0);
5256 /* See if we need to do the subtraction. */
5257 do_pending_stack_adjust ();
5258 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
5259 0, lab1);
5261 /* If not, do the signed "fix" and branch around fixup code. */
5262 expand_fix (to, from, 0);
5263 emit_jump_insn (gen_jump (lab2));
5264 emit_barrier ();
5266 /* Otherwise, subtract 2**(N-1), convert to signed number,
5267 then add 2**(N-1). Do the addition using XOR since this
5268 will often generate better code. */
5269 emit_label (lab1);
5270 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5271 NULL_RTX, 0, OPTAB_LIB_WIDEN);
5272 expand_fix (to, target, 0);
5273 target = expand_binop (GET_MODE (to), xor_optab, to,
5274 gen_int_mode
5275 ((HOST_WIDE_INT) 1 << (bitsize - 1),
5276 GET_MODE (to)),
5277 to, 1, OPTAB_LIB_WIDEN);
5279 if (target != to)
5280 emit_move_insn (to, target);
5282 emit_label (lab2);
5284 if (optab_handler (mov_optab, GET_MODE (to)) != CODE_FOR_nothing)
5286 /* Make a place for a REG_NOTE and add it. */
5287 insn = emit_move_insn (to, to);
5288 set_dst_reg_note (insn, REG_EQUAL,
5289 gen_rtx_fmt_e (UNSIGNED_FIX, GET_MODE (to),
5290 copy_rtx (from)),
5291 to);
5294 return;
5297 /* We can't do it with an insn, so use a library call. But first ensure
5298 that the mode of TO is at least as wide as SImode, since those are the
5299 only library calls we know about. */
5301 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
5303 target = gen_reg_rtx (SImode);
5305 expand_fix (target, from, unsignedp);
5307 else
5309 rtx insns;
5310 rtx value;
5311 rtx libfunc;
5313 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5314 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5315 gcc_assert (libfunc);
5317 start_sequence ();
5319 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5320 GET_MODE (to), 1, from,
5321 GET_MODE (from));
5322 insns = get_insns ();
5323 end_sequence ();
5325 emit_libcall_block (insns, target, value,
5326 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5327 GET_MODE (to), from));
5330 if (target != to)
5332 if (GET_MODE (to) == GET_MODE (target))
5333 emit_move_insn (to, target);
5334 else
5335 convert_move (to, target, 0);
5339 /* Generate code to convert FROM or TO a fixed-point.
5340 If UINTP is true, either TO or FROM is an unsigned integer.
5341 If SATP is true, we need to saturate the result. */
5343 void
5344 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5346 enum machine_mode to_mode = GET_MODE (to);
5347 enum machine_mode from_mode = GET_MODE (from);
5348 convert_optab tab;
5349 enum rtx_code this_code;
5350 enum insn_code code;
5351 rtx insns, value;
5352 rtx libfunc;
5354 if (to_mode == from_mode)
5356 emit_move_insn (to, from);
5357 return;
5360 if (uintp)
5362 tab = satp ? satfractuns_optab : fractuns_optab;
5363 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5365 else
5367 tab = satp ? satfract_optab : fract_optab;
5368 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5370 code = convert_optab_handler (tab, to_mode, from_mode);
5371 if (code != CODE_FOR_nothing)
5373 emit_unop_insn (code, to, from, this_code);
5374 return;
5377 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5378 gcc_assert (libfunc);
5380 start_sequence ();
5381 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5382 1, from, from_mode);
5383 insns = get_insns ();
5384 end_sequence ();
5386 emit_libcall_block (insns, to, value,
5387 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
5390 /* Generate code to convert FROM to fixed point and store in TO. FROM
5391 must be floating point, TO must be signed. Use the conversion optab
5392 TAB to do the conversion. */
5394 bool
5395 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5397 enum insn_code icode;
5398 rtx target = to;
5399 enum machine_mode fmode, imode;
5401 /* We first try to find a pair of modes, one real and one integer, at
5402 least as wide as FROM and TO, respectively, in which we can open-code
5403 this conversion. If the integer mode is wider than the mode of TO,
5404 we can do the conversion either signed or unsigned. */
5406 for (fmode = GET_MODE (from); fmode != VOIDmode;
5407 fmode = GET_MODE_WIDER_MODE (fmode))
5408 for (imode = GET_MODE (to); imode != VOIDmode;
5409 imode = GET_MODE_WIDER_MODE (imode))
5411 icode = convert_optab_handler (tab, imode, fmode);
5412 if (icode != CODE_FOR_nothing)
5414 rtx last = get_last_insn ();
5415 if (fmode != GET_MODE (from))
5416 from = convert_to_mode (fmode, from, 0);
5418 if (imode != GET_MODE (to))
5419 target = gen_reg_rtx (imode);
5421 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5423 delete_insns_since (last);
5424 continue;
5426 if (target != to)
5427 convert_move (to, target, 0);
5428 return true;
5432 return false;
5435 /* Report whether we have an instruction to perform the operation
5436 specified by CODE on operands of mode MODE. */
5438 have_insn_for (enum rtx_code code, enum machine_mode mode)
5440 return (code_to_optab (code)
5441 && (optab_handler (code_to_optab (code), mode)
5442 != CODE_FOR_nothing));
5445 /* Initialize the libfunc fields of an entire group of entries in some
5446 optab. Each entry is set equal to a string consisting of a leading
5447 pair of underscores followed by a generic operation name followed by
5448 a mode name (downshifted to lowercase) followed by a single character
5449 representing the number of operands for the given operation (which is
5450 usually one of the characters '2', '3', or '4').
5452 OPTABLE is the table in which libfunc fields are to be initialized.
5453 OPNAME is the generic (string) name of the operation.
5454 SUFFIX is the character which specifies the number of operands for
5455 the given generic operation.
5456 MODE is the mode to generate for.
5459 static void
5460 gen_libfunc (optab optable, const char *opname, int suffix,
5461 enum machine_mode mode)
5463 unsigned opname_len = strlen (opname);
5464 const char *mname = GET_MODE_NAME (mode);
5465 unsigned mname_len = strlen (mname);
5466 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5467 int len = prefix_len + opname_len + mname_len + 1 + 1;
5468 char *libfunc_name = XALLOCAVEC (char, len);
5469 char *p;
5470 const char *q;
5472 p = libfunc_name;
5473 *p++ = '_';
5474 *p++ = '_';
5475 if (targetm.libfunc_gnu_prefix)
5477 *p++ = 'g';
5478 *p++ = 'n';
5479 *p++ = 'u';
5480 *p++ = '_';
5482 for (q = opname; *q; )
5483 *p++ = *q++;
5484 for (q = mname; *q; q++)
5485 *p++ = TOLOWER (*q);
5486 *p++ = suffix;
5487 *p = '\0';
5489 set_optab_libfunc (optable, mode,
5490 ggc_alloc_string (libfunc_name, p - libfunc_name));
5493 /* Like gen_libfunc, but verify that integer operation is involved. */
5495 void
5496 gen_int_libfunc (optab optable, const char *opname, char suffix,
5497 enum machine_mode mode)
5499 int maxsize = 2 * BITS_PER_WORD;
5501 if (GET_MODE_CLASS (mode) != MODE_INT)
5502 return;
5503 if (maxsize < LONG_LONG_TYPE_SIZE)
5504 maxsize = LONG_LONG_TYPE_SIZE;
5505 if (GET_MODE_CLASS (mode) != MODE_INT
5506 || mode < word_mode || GET_MODE_BITSIZE (mode) > maxsize)
5507 return;
5508 gen_libfunc (optable, opname, suffix, mode);
5511 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */
5513 void
5514 gen_fp_libfunc (optab optable, const char *opname, char suffix,
5515 enum machine_mode mode)
5517 char *dec_opname;
5519 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
5520 gen_libfunc (optable, opname, suffix, mode);
5521 if (DECIMAL_FLOAT_MODE_P (mode))
5523 dec_opname = XALLOCAVEC (char, sizeof (DECIMAL_PREFIX) + strlen (opname));
5524 /* For BID support, change the name to have either a bid_ or dpd_ prefix
5525 depending on the low level floating format used. */
5526 memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
5527 strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
5528 gen_libfunc (optable, dec_opname, suffix, mode);
5532 /* Like gen_libfunc, but verify that fixed-point operation is involved. */
5534 void
5535 gen_fixed_libfunc (optab optable, const char *opname, char suffix,
5536 enum machine_mode mode)
5538 if (!ALL_FIXED_POINT_MODE_P (mode))
5539 return;
5540 gen_libfunc (optable, opname, suffix, mode);
5543 /* Like gen_libfunc, but verify that signed fixed-point operation is
5544 involved. */
5546 void
5547 gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
5548 enum machine_mode mode)
5550 if (!SIGNED_FIXED_POINT_MODE_P (mode))
5551 return;
5552 gen_libfunc (optable, opname, suffix, mode);
5555 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
5556 involved. */
5558 void
5559 gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
5560 enum machine_mode mode)
5562 if (!UNSIGNED_FIXED_POINT_MODE_P (mode))
5563 return;
5564 gen_libfunc (optable, opname, suffix, mode);
5567 /* Like gen_libfunc, but verify that FP or INT operation is involved. */
5569 void
5570 gen_int_fp_libfunc (optab optable, const char *name, char suffix,
5571 enum machine_mode mode)
5573 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5574 gen_fp_libfunc (optable, name, suffix, mode);
5575 if (INTEGRAL_MODE_P (mode))
5576 gen_int_libfunc (optable, name, suffix, mode);
5579 /* Like gen_libfunc, but verify that FP or INT operation is involved
5580 and add 'v' suffix for integer operation. */
5582 void
5583 gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
5584 enum machine_mode mode)
5586 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5587 gen_fp_libfunc (optable, name, suffix, mode);
5588 if (GET_MODE_CLASS (mode) == MODE_INT)
5590 int len = strlen (name);
5591 char *v_name = XALLOCAVEC (char, len + 2);
5592 strcpy (v_name, name);
5593 v_name[len] = 'v';
5594 v_name[len + 1] = 0;
5595 gen_int_libfunc (optable, v_name, suffix, mode);
5599 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
5600 involved. */
5602 void
5603 gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
5604 enum machine_mode mode)
5606 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5607 gen_fp_libfunc (optable, name, suffix, mode);
5608 if (INTEGRAL_MODE_P (mode))
5609 gen_int_libfunc (optable, name, suffix, mode);
5610 if (ALL_FIXED_POINT_MODE_P (mode))
5611 gen_fixed_libfunc (optable, name, suffix, mode);
5614 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
5615 involved. */
5617 void
5618 gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5619 enum machine_mode mode)
5621 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5622 gen_fp_libfunc (optable, name, suffix, mode);
5623 if (INTEGRAL_MODE_P (mode))
5624 gen_int_libfunc (optable, name, suffix, mode);
5625 if (SIGNED_FIXED_POINT_MODE_P (mode))
5626 gen_signed_fixed_libfunc (optable, name, suffix, mode);
5629 /* Like gen_libfunc, but verify that INT or FIXED operation is
5630 involved. */
5632 void
5633 gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
5634 enum machine_mode mode)
5636 if (INTEGRAL_MODE_P (mode))
5637 gen_int_libfunc (optable, name, suffix, mode);
5638 if (ALL_FIXED_POINT_MODE_P (mode))
5639 gen_fixed_libfunc (optable, name, suffix, mode);
5642 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
5643 involved. */
5645 void
5646 gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5647 enum machine_mode mode)
5649 if (INTEGRAL_MODE_P (mode))
5650 gen_int_libfunc (optable, name, suffix, mode);
5651 if (SIGNED_FIXED_POINT_MODE_P (mode))
5652 gen_signed_fixed_libfunc (optable, name, suffix, mode);
5655 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
5656 involved. */
5658 void
5659 gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
5660 enum machine_mode mode)
5662 if (INTEGRAL_MODE_P (mode))
5663 gen_int_libfunc (optable, name, suffix, mode);
5664 if (UNSIGNED_FIXED_POINT_MODE_P (mode))
5665 gen_unsigned_fixed_libfunc (optable, name, suffix, mode);
5668 /* Initialize the libfunc fields of an entire group of entries of an
5669 inter-mode-class conversion optab. The string formation rules are
5670 similar to the ones for init_libfuncs, above, but instead of having
5671 a mode name and an operand count these functions have two mode names
5672 and no operand count. */
5674 void
5675 gen_interclass_conv_libfunc (convert_optab tab,
5676 const char *opname,
5677 enum machine_mode tmode,
5678 enum machine_mode fmode)
5680 size_t opname_len = strlen (opname);
5681 size_t mname_len = 0;
5683 const char *fname, *tname;
5684 const char *q;
5685 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5686 char *libfunc_name, *suffix;
5687 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5688 char *p;
5690 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5691 depends on which underlying decimal floating point format is used. */
5692 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5694 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5696 nondec_name = XALLOCAVEC (char, prefix_len + opname_len + mname_len + 1 + 1);
5697 nondec_name[0] = '_';
5698 nondec_name[1] = '_';
5699 if (targetm.libfunc_gnu_prefix)
5701 nondec_name[2] = 'g';
5702 nondec_name[3] = 'n';
5703 nondec_name[4] = 'u';
5704 nondec_name[5] = '_';
5707 memcpy (&nondec_name[prefix_len], opname, opname_len);
5708 nondec_suffix = nondec_name + opname_len + prefix_len;
5710 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
5711 dec_name[0] = '_';
5712 dec_name[1] = '_';
5713 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5714 memcpy (&dec_name[2+dec_len], opname, opname_len);
5715 dec_suffix = dec_name + dec_len + opname_len + 2;
5717 fname = GET_MODE_NAME (fmode);
5718 tname = GET_MODE_NAME (tmode);
5720 if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5722 libfunc_name = dec_name;
5723 suffix = dec_suffix;
5725 else
5727 libfunc_name = nondec_name;
5728 suffix = nondec_suffix;
5731 p = suffix;
5732 for (q = fname; *q; p++, q++)
5733 *p = TOLOWER (*q);
5734 for (q = tname; *q; p++, q++)
5735 *p = TOLOWER (*q);
5737 *p = '\0';
5739 set_conv_libfunc (tab, tmode, fmode,
5740 ggc_alloc_string (libfunc_name, p - libfunc_name));
5743 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5744 int->fp conversion. */
5746 void
5747 gen_int_to_fp_conv_libfunc (convert_optab tab,
5748 const char *opname,
5749 enum machine_mode tmode,
5750 enum machine_mode fmode)
5752 if (GET_MODE_CLASS (fmode) != MODE_INT)
5753 return;
5754 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5755 return;
5756 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5759 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
5760 naming scheme. */
5762 void
5763 gen_ufloat_conv_libfunc (convert_optab tab,
5764 const char *opname ATTRIBUTE_UNUSED,
5765 enum machine_mode tmode,
5766 enum machine_mode fmode)
5768 if (DECIMAL_FLOAT_MODE_P (tmode))
5769 gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode);
5770 else
5771 gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode);
5774 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5775 fp->int conversion. */
5777 void
5778 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
5779 const char *opname,
5780 enum machine_mode tmode,
5781 enum machine_mode fmode)
5783 if (GET_MODE_CLASS (fmode) != MODE_INT)
5784 return;
5785 if (GET_MODE_CLASS (tmode) != MODE_FLOAT)
5786 return;
5787 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5790 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5791 fp->int conversion with no decimal floating point involved. */
5793 void
5794 gen_fp_to_int_conv_libfunc (convert_optab tab,
5795 const char *opname,
5796 enum machine_mode tmode,
5797 enum machine_mode fmode)
5799 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5800 return;
5801 if (GET_MODE_CLASS (tmode) != MODE_INT)
5802 return;
5803 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5806 /* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
5807 The string formation rules are
5808 similar to the ones for init_libfunc, above. */
5810 void
5811 gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
5812 enum machine_mode tmode, enum machine_mode fmode)
5814 size_t opname_len = strlen (opname);
5815 size_t mname_len = 0;
5817 const char *fname, *tname;
5818 const char *q;
5819 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5820 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5821 char *libfunc_name, *suffix;
5822 char *p;
5824 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5825 depends on which underlying decimal floating point format is used. */
5826 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5828 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5830 nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
5831 nondec_name[0] = '_';
5832 nondec_name[1] = '_';
5833 if (targetm.libfunc_gnu_prefix)
5835 nondec_name[2] = 'g';
5836 nondec_name[3] = 'n';
5837 nondec_name[4] = 'u';
5838 nondec_name[5] = '_';
5840 memcpy (&nondec_name[prefix_len], opname, opname_len);
5841 nondec_suffix = nondec_name + opname_len + prefix_len;
5843 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
5844 dec_name[0] = '_';
5845 dec_name[1] = '_';
5846 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5847 memcpy (&dec_name[2 + dec_len], opname, opname_len);
5848 dec_suffix = dec_name + dec_len + opname_len + 2;
5850 fname = GET_MODE_NAME (fmode);
5851 tname = GET_MODE_NAME (tmode);
5853 if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5855 libfunc_name = dec_name;
5856 suffix = dec_suffix;
5858 else
5860 libfunc_name = nondec_name;
5861 suffix = nondec_suffix;
5864 p = suffix;
5865 for (q = fname; *q; p++, q++)
5866 *p = TOLOWER (*q);
5867 for (q = tname; *q; p++, q++)
5868 *p = TOLOWER (*q);
5870 *p++ = '2';
5871 *p = '\0';
5873 set_conv_libfunc (tab, tmode, fmode,
5874 ggc_alloc_string (libfunc_name, p - libfunc_name));
5877 /* Pick proper libcall for trunc_optab. We need to chose if we do
5878 truncation or extension and interclass or intraclass. */
5880 void
5881 gen_trunc_conv_libfunc (convert_optab tab,
5882 const char *opname,
5883 enum machine_mode tmode,
5884 enum machine_mode fmode)
5886 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5887 return;
5888 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5889 return;
5890 if (tmode == fmode)
5891 return;
5893 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
5894 || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
5895 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5897 if (GET_MODE_PRECISION (fmode) <= GET_MODE_PRECISION (tmode))
5898 return;
5900 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
5901 && GET_MODE_CLASS (fmode) == MODE_FLOAT)
5902 || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
5903 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5906 /* Pick proper libcall for extend_optab. We need to chose if we do
5907 truncation or extension and interclass or intraclass. */
5909 void
5910 gen_extend_conv_libfunc (convert_optab tab,
5911 const char *opname ATTRIBUTE_UNUSED,
5912 enum machine_mode tmode,
5913 enum machine_mode fmode)
5915 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5916 return;
5917 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5918 return;
5919 if (tmode == fmode)
5920 return;
5922 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
5923 || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
5924 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5926 if (GET_MODE_PRECISION (fmode) > GET_MODE_PRECISION (tmode))
5927 return;
5929 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
5930 && GET_MODE_CLASS (fmode) == MODE_FLOAT)
5931 || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
5932 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5935 /* Pick proper libcall for fract_optab. We need to chose if we do
5936 interclass or intraclass. */
5938 void
5939 gen_fract_conv_libfunc (convert_optab tab,
5940 const char *opname,
5941 enum machine_mode tmode,
5942 enum machine_mode fmode)
5944 if (tmode == fmode)
5945 return;
5946 if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode)))
5947 return;
5949 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
5950 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5951 else
5952 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5955 /* Pick proper libcall for fractuns_optab. */
5957 void
5958 gen_fractuns_conv_libfunc (convert_optab tab,
5959 const char *opname,
5960 enum machine_mode tmode,
5961 enum machine_mode fmode)
5963 if (tmode == fmode)
5964 return;
5965 /* One mode must be a fixed-point mode, and the other must be an integer
5966 mode. */
5967 if (!((ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT)
5968 || (ALL_FIXED_POINT_MODE_P (fmode)
5969 && GET_MODE_CLASS (tmode) == MODE_INT)))
5970 return;
5972 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5975 /* Pick proper libcall for satfract_optab. We need to chose if we do
5976 interclass or intraclass. */
5978 void
5979 gen_satfract_conv_libfunc (convert_optab tab,
5980 const char *opname,
5981 enum machine_mode tmode,
5982 enum machine_mode fmode)
5984 if (tmode == fmode)
5985 return;
5986 /* TMODE must be a fixed-point mode. */
5987 if (!ALL_FIXED_POINT_MODE_P (tmode))
5988 return;
5990 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
5991 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5992 else
5993 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5996 /* Pick proper libcall for satfractuns_optab. */
5998 void
5999 gen_satfractuns_conv_libfunc (convert_optab tab,
6000 const char *opname,
6001 enum machine_mode tmode,
6002 enum machine_mode fmode)
6004 if (tmode == fmode)
6005 return;
6006 /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
6007 if (!(ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT))
6008 return;
6010 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6013 /* A table of previously-created libfuncs, hashed by name. */
6014 static GTY ((param_is (union tree_node))) htab_t libfunc_decls;
6016 /* Hashtable callbacks for libfunc_decls. */
6018 static hashval_t
6019 libfunc_decl_hash (const void *entry)
6021 return IDENTIFIER_HASH_VALUE (DECL_NAME ((const_tree) entry));
6024 static int
6025 libfunc_decl_eq (const void *entry1, const void *entry2)
6027 return DECL_NAME ((const_tree) entry1) == (const_tree) entry2;
6030 /* Build a decl for a libfunc named NAME. */
6032 tree
6033 build_libfunc_function (const char *name)
6035 tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
6036 get_identifier (name),
6037 build_function_type (integer_type_node, NULL_TREE));
6038 /* ??? We don't have any type information except for this is
6039 a function. Pretend this is "int foo()". */
6040 DECL_ARTIFICIAL (decl) = 1;
6041 DECL_EXTERNAL (decl) = 1;
6042 TREE_PUBLIC (decl) = 1;
6043 gcc_assert (DECL_ASSEMBLER_NAME (decl));
6045 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
6046 are the flags assigned by targetm.encode_section_info. */
6047 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
6049 return decl;
6053 init_one_libfunc (const char *name)
6055 tree id, decl;
6056 void **slot;
6057 hashval_t hash;
6059 if (libfunc_decls == NULL)
6060 libfunc_decls = htab_create_ggc (37, libfunc_decl_hash,
6061 libfunc_decl_eq, NULL);
6063 /* See if we have already created a libfunc decl for this function. */
6064 id = get_identifier (name);
6065 hash = IDENTIFIER_HASH_VALUE (id);
6066 slot = htab_find_slot_with_hash (libfunc_decls, id, hash, INSERT);
6067 decl = (tree) *slot;
6068 if (decl == NULL)
6070 /* Create a new decl, so that it can be passed to
6071 targetm.encode_section_info. */
6072 decl = build_libfunc_function (name);
6073 *slot = decl;
6075 return XEXP (DECL_RTL (decl), 0);
6078 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */
6081 set_user_assembler_libfunc (const char *name, const char *asmspec)
6083 tree id, decl;
6084 void **slot;
6085 hashval_t hash;
6087 id = get_identifier (name);
6088 hash = IDENTIFIER_HASH_VALUE (id);
6089 slot = htab_find_slot_with_hash (libfunc_decls, id, hash, NO_INSERT);
6090 gcc_assert (slot);
6091 decl = (tree) *slot;
6092 set_user_assembler_name (decl, asmspec);
6093 return XEXP (DECL_RTL (decl), 0);
6096 /* Call this to reset the function entry for one optab (OPTABLE) in mode
6097 MODE to NAME, which should be either 0 or a string constant. */
6098 void
6099 set_optab_libfunc (optab op, enum machine_mode mode, const char *name)
6101 rtx val;
6102 struct libfunc_entry e;
6103 struct libfunc_entry **slot;
6105 e.op = op;
6106 e.mode1 = mode;
6107 e.mode2 = VOIDmode;
6109 if (name)
6110 val = init_one_libfunc (name);
6111 else
6112 val = 0;
6113 slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
6114 if (*slot == NULL)
6115 *slot = ggc_alloc_libfunc_entry ();
6116 (*slot)->op = op;
6117 (*slot)->mode1 = mode;
6118 (*slot)->mode2 = VOIDmode;
6119 (*slot)->libfunc = val;
6122 /* Call this to reset the function entry for one conversion optab
6123 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
6124 either 0 or a string constant. */
6125 void
6126 set_conv_libfunc (convert_optab optab, enum machine_mode tmode,
6127 enum machine_mode fmode, const char *name)
6129 rtx val;
6130 struct libfunc_entry e;
6131 struct libfunc_entry **slot;
6133 e.op = optab;
6134 e.mode1 = tmode;
6135 e.mode2 = fmode;
6137 if (name)
6138 val = init_one_libfunc (name);
6139 else
6140 val = 0;
6141 slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
6142 if (*slot == NULL)
6143 *slot = ggc_alloc_libfunc_entry ();
6144 (*slot)->op = optab;
6145 (*slot)->mode1 = tmode;
6146 (*slot)->mode2 = fmode;
6147 (*slot)->libfunc = val;
6150 /* Call this to initialize the contents of the optabs
6151 appropriately for the current target machine. */
6153 void
6154 init_optabs (void)
6156 if (libfunc_hash)
6157 htab_empty (libfunc_hash);
6158 else
6159 libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
6161 /* Fill in the optabs with the insns we support. */
6162 init_all_optabs (this_fn_optabs);
6164 /* The ffs function operates on `int'. Fall back on it if we do not
6165 have a libgcc2 function for that width. */
6166 if (INT_TYPE_SIZE < BITS_PER_WORD)
6167 set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, MODE_INT, 0),
6168 "ffs");
6170 /* Explicitly initialize the bswap libfuncs since we need them to be
6171 valid for things other than word_mode. */
6172 if (targetm.libfunc_gnu_prefix)
6174 set_optab_libfunc (bswap_optab, SImode, "__gnu_bswapsi2");
6175 set_optab_libfunc (bswap_optab, DImode, "__gnu_bswapdi2");
6177 else
6179 set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
6180 set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
6183 /* Use cabs for double complex abs, since systems generally have cabs.
6184 Don't define any libcall for float complex, so that cabs will be used. */
6185 if (complex_double_type_node)
6186 set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node),
6187 "cabs");
6189 abort_libfunc = init_one_libfunc ("abort");
6190 memcpy_libfunc = init_one_libfunc ("memcpy");
6191 memmove_libfunc = init_one_libfunc ("memmove");
6192 memcmp_libfunc = init_one_libfunc ("memcmp");
6193 memset_libfunc = init_one_libfunc ("memset");
6194 setbits_libfunc = init_one_libfunc ("__setbits");
6196 #ifndef DONT_USE_BUILTIN_SETJMP
6197 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
6198 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
6199 #else
6200 setjmp_libfunc = init_one_libfunc ("setjmp");
6201 longjmp_libfunc = init_one_libfunc ("longjmp");
6202 #endif
6203 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
6204 unwind_sjlj_unregister_libfunc
6205 = init_one_libfunc ("_Unwind_SjLj_Unregister");
6207 /* For function entry/exit instrumentation. */
6208 profile_function_entry_libfunc
6209 = init_one_libfunc ("__cyg_profile_func_enter");
6210 profile_function_exit_libfunc
6211 = init_one_libfunc ("__cyg_profile_func_exit");
6213 gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
6215 /* Allow the target to add more libcalls or rename some, etc. */
6216 targetm.init_libfuncs ();
6219 /* Use the current target and options to initialize
6220 TREE_OPTIMIZATION_OPTABS (OPTNODE). */
6222 void
6223 init_tree_optimization_optabs (tree optnode)
6225 /* Quick exit if we have already computed optabs for this target. */
6226 if (TREE_OPTIMIZATION_BASE_OPTABS (optnode) == this_target_optabs)
6227 return;
6229 /* Forget any previous information and set up for the current target. */
6230 TREE_OPTIMIZATION_BASE_OPTABS (optnode) = this_target_optabs;
6231 struct target_optabs *tmp_optabs = (struct target_optabs *)
6232 TREE_OPTIMIZATION_OPTABS (optnode);
6233 if (tmp_optabs)
6234 memset (tmp_optabs, 0, sizeof (struct target_optabs));
6235 else
6236 tmp_optabs = (struct target_optabs *)
6237 ggc_alloc_atomic (sizeof (struct target_optabs));
6239 /* Generate a new set of optabs into tmp_optabs. */
6240 init_all_optabs (tmp_optabs);
6242 /* If the optabs changed, record it. */
6243 if (memcmp (tmp_optabs, this_target_optabs, sizeof (struct target_optabs)))
6244 TREE_OPTIMIZATION_OPTABS (optnode) = tmp_optabs;
6245 else
6247 TREE_OPTIMIZATION_OPTABS (optnode) = NULL;
6248 ggc_free (tmp_optabs);
6252 /* A helper function for init_sync_libfuncs. Using the basename BASE,
6253 install libfuncs into TAB for BASE_N for 1 <= N <= MAX. */
6255 static void
6256 init_sync_libfuncs_1 (optab tab, const char *base, int max)
6258 enum machine_mode mode;
6259 char buf[64];
6260 size_t len = strlen (base);
6261 int i;
6263 gcc_assert (max <= 8);
6264 gcc_assert (len + 3 < sizeof (buf));
6266 memcpy (buf, base, len);
6267 buf[len] = '_';
6268 buf[len + 1] = '0';
6269 buf[len + 2] = '\0';
6271 mode = QImode;
6272 for (i = 1; i <= max; i *= 2)
6274 buf[len + 1] = '0' + i;
6275 set_optab_libfunc (tab, mode, buf);
6276 mode = GET_MODE_2XWIDER_MODE (mode);
6280 void
6281 init_sync_libfuncs (int max)
6283 if (!flag_sync_libcalls)
6284 return;
6286 init_sync_libfuncs_1 (sync_compare_and_swap_optab,
6287 "__sync_val_compare_and_swap", max);
6288 init_sync_libfuncs_1 (sync_lock_test_and_set_optab,
6289 "__sync_lock_test_and_set", max);
6291 init_sync_libfuncs_1 (sync_old_add_optab, "__sync_fetch_and_add", max);
6292 init_sync_libfuncs_1 (sync_old_sub_optab, "__sync_fetch_and_sub", max);
6293 init_sync_libfuncs_1 (sync_old_ior_optab, "__sync_fetch_and_or", max);
6294 init_sync_libfuncs_1 (sync_old_and_optab, "__sync_fetch_and_and", max);
6295 init_sync_libfuncs_1 (sync_old_xor_optab, "__sync_fetch_and_xor", max);
6296 init_sync_libfuncs_1 (sync_old_nand_optab, "__sync_fetch_and_nand", max);
6298 init_sync_libfuncs_1 (sync_new_add_optab, "__sync_add_and_fetch", max);
6299 init_sync_libfuncs_1 (sync_new_sub_optab, "__sync_sub_and_fetch", max);
6300 init_sync_libfuncs_1 (sync_new_ior_optab, "__sync_or_and_fetch", max);
6301 init_sync_libfuncs_1 (sync_new_and_optab, "__sync_and_and_fetch", max);
6302 init_sync_libfuncs_1 (sync_new_xor_optab, "__sync_xor_and_fetch", max);
6303 init_sync_libfuncs_1 (sync_new_nand_optab, "__sync_nand_and_fetch", max);
6306 /* Print information about the current contents of the optabs on
6307 STDERR. */
6309 DEBUG_FUNCTION void
6310 debug_optab_libfuncs (void)
6312 int i, j, k;
6314 /* Dump the arithmetic optabs. */
6315 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
6316 for (j = 0; j < NUM_MACHINE_MODES; ++j)
6318 rtx l = optab_libfunc ((optab) i, (enum machine_mode) j);
6319 if (l)
6321 gcc_assert (GET_CODE (l) == SYMBOL_REF);
6322 fprintf (stderr, "%s\t%s:\t%s\n",
6323 GET_RTX_NAME (optab_to_code ((optab) i)),
6324 GET_MODE_NAME (j),
6325 XSTR (l, 0));
6329 /* Dump the conversion optabs. */
6330 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
6331 for (j = 0; j < NUM_MACHINE_MODES; ++j)
6332 for (k = 0; k < NUM_MACHINE_MODES; ++k)
6334 rtx l = convert_optab_libfunc ((optab) i, (enum machine_mode) j,
6335 (enum machine_mode) k);
6336 if (l)
6338 gcc_assert (GET_CODE (l) == SYMBOL_REF);
6339 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
6340 GET_RTX_NAME (optab_to_code ((optab) i)),
6341 GET_MODE_NAME (j),
6342 GET_MODE_NAME (k),
6343 XSTR (l, 0));
6349 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6350 CODE. Return 0 on failure. */
6353 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
6355 enum machine_mode mode = GET_MODE (op1);
6356 enum insn_code icode;
6357 rtx insn;
6358 rtx trap_rtx;
6360 if (mode == VOIDmode)
6361 return 0;
6363 icode = optab_handler (ctrap_optab, mode);
6364 if (icode == CODE_FOR_nothing)
6365 return 0;
6367 /* Some targets only accept a zero trap code. */
6368 if (!insn_operand_matches (icode, 3, tcode))
6369 return 0;
6371 do_pending_stack_adjust ();
6372 start_sequence ();
6373 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
6374 &trap_rtx, &mode);
6375 if (!trap_rtx)
6376 insn = NULL_RTX;
6377 else
6378 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
6379 tcode);
6381 /* If that failed, then give up. */
6382 if (insn == 0)
6384 end_sequence ();
6385 return 0;
6388 emit_insn (insn);
6389 insn = get_insns ();
6390 end_sequence ();
6391 return insn;
6394 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6395 or unsigned operation code. */
6397 static enum rtx_code
6398 get_rtx_code (enum tree_code tcode, bool unsignedp)
6400 enum rtx_code code;
6401 switch (tcode)
6403 case EQ_EXPR:
6404 code = EQ;
6405 break;
6406 case NE_EXPR:
6407 code = NE;
6408 break;
6409 case LT_EXPR:
6410 code = unsignedp ? LTU : LT;
6411 break;
6412 case LE_EXPR:
6413 code = unsignedp ? LEU : LE;
6414 break;
6415 case GT_EXPR:
6416 code = unsignedp ? GTU : GT;
6417 break;
6418 case GE_EXPR:
6419 code = unsignedp ? GEU : GE;
6420 break;
6422 case UNORDERED_EXPR:
6423 code = UNORDERED;
6424 break;
6425 case ORDERED_EXPR:
6426 code = ORDERED;
6427 break;
6428 case UNLT_EXPR:
6429 code = UNLT;
6430 break;
6431 case UNLE_EXPR:
6432 code = UNLE;
6433 break;
6434 case UNGT_EXPR:
6435 code = UNGT;
6436 break;
6437 case UNGE_EXPR:
6438 code = UNGE;
6439 break;
6440 case UNEQ_EXPR:
6441 code = UNEQ;
6442 break;
6443 case LTGT_EXPR:
6444 code = LTGT;
6445 break;
6447 default:
6448 gcc_unreachable ();
6450 return code;
6453 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6454 unsigned operators. Do not generate compare instruction. */
6456 static rtx
6457 vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
6458 bool unsignedp, enum insn_code icode)
6460 struct expand_operand ops[2];
6461 rtx rtx_op0, rtx_op1;
6462 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
6464 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
6466 /* Expand operands. */
6467 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
6468 EXPAND_STACK_PARM);
6469 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
6470 EXPAND_STACK_PARM);
6472 create_input_operand (&ops[0], rtx_op0, GET_MODE (rtx_op0));
6473 create_input_operand (&ops[1], rtx_op1, GET_MODE (rtx_op1));
6474 if (!maybe_legitimize_operands (icode, 4, 2, ops))
6475 gcc_unreachable ();
6476 return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
6479 /* Return true if VEC_PERM_EXPR can be expanded using SIMD extensions
6480 of the CPU. SEL may be NULL, which stands for an unknown constant. */
6482 bool
6483 can_vec_perm_p (enum machine_mode mode, bool variable,
6484 const unsigned char *sel)
6486 enum machine_mode qimode;
6488 /* If the target doesn't implement a vector mode for the vector type,
6489 then no operations are supported. */
6490 if (!VECTOR_MODE_P (mode))
6491 return false;
6493 if (!variable)
6495 if (direct_optab_handler (vec_perm_const_optab, mode) != CODE_FOR_nothing
6496 && (sel == NULL
6497 || targetm.vectorize.vec_perm_const_ok == NULL
6498 || targetm.vectorize.vec_perm_const_ok (mode, sel)))
6499 return true;
6502 if (direct_optab_handler (vec_perm_optab, mode) != CODE_FOR_nothing)
6503 return true;
6505 /* We allow fallback to a QI vector mode, and adjust the mask. */
6506 if (GET_MODE_INNER (mode) == QImode)
6507 return false;
6508 qimode = mode_for_vector (QImode, GET_MODE_SIZE (mode));
6509 if (!VECTOR_MODE_P (qimode))
6510 return false;
6512 /* ??? For completeness, we ought to check the QImode version of
6513 vec_perm_const_optab. But all users of this implicit lowering
6514 feature implement the variable vec_perm_optab. */
6515 if (direct_optab_handler (vec_perm_optab, qimode) == CODE_FOR_nothing)
6516 return false;
6518 /* In order to support the lowering of variable permutations,
6519 we need to support shifts and adds. */
6520 if (variable)
6522 if (GET_MODE_UNIT_SIZE (mode) > 2
6523 && optab_handler (ashl_optab, mode) == CODE_FOR_nothing
6524 && optab_handler (vashl_optab, mode) == CODE_FOR_nothing)
6525 return false;
6526 if (optab_handler (add_optab, qimode) == CODE_FOR_nothing)
6527 return false;
6530 return true;
6533 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
6535 static rtx
6536 expand_vec_perm_1 (enum insn_code icode, rtx target,
6537 rtx v0, rtx v1, rtx sel)
6539 enum machine_mode tmode = GET_MODE (target);
6540 enum machine_mode smode = GET_MODE (sel);
6541 struct expand_operand ops[4];
6543 create_output_operand (&ops[0], target, tmode);
6544 create_input_operand (&ops[3], sel, smode);
6546 /* Make an effort to preserve v0 == v1. The target expander is able to
6547 rely on this to determine if we're permuting a single input operand. */
6548 if (rtx_equal_p (v0, v1))
6550 if (!insn_operand_matches (icode, 1, v0))
6551 v0 = force_reg (tmode, v0);
6552 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
6553 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
6555 create_fixed_operand (&ops[1], v0);
6556 create_fixed_operand (&ops[2], v0);
6558 else
6560 create_input_operand (&ops[1], v0, tmode);
6561 create_input_operand (&ops[2], v1, tmode);
6564 if (maybe_expand_insn (icode, 4, ops))
6565 return ops[0].value;
6566 return NULL_RTX;
6569 /* Generate instructions for vec_perm optab given its mode
6570 and three operands. */
6573 expand_vec_perm (enum machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
6575 enum insn_code icode;
6576 enum machine_mode qimode;
6577 unsigned int i, w, e, u;
6578 rtx tmp, sel_qi = NULL;
6579 rtvec vec;
6581 if (!target || GET_MODE (target) != mode)
6582 target = gen_reg_rtx (mode);
6584 w = GET_MODE_SIZE (mode);
6585 e = GET_MODE_NUNITS (mode);
6586 u = GET_MODE_UNIT_SIZE (mode);
6588 /* Set QIMODE to a different vector mode with byte elements.
6589 If no such mode, or if MODE already has byte elements, use VOIDmode. */
6590 qimode = VOIDmode;
6591 if (GET_MODE_INNER (mode) != QImode)
6593 qimode = mode_for_vector (QImode, w);
6594 if (!VECTOR_MODE_P (qimode))
6595 qimode = VOIDmode;
6598 /* If the input is a constant, expand it specially. */
6599 gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT);
6600 if (GET_CODE (sel) == CONST_VECTOR)
6602 icode = direct_optab_handler (vec_perm_const_optab, mode);
6603 if (icode != CODE_FOR_nothing)
6605 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
6606 if (tmp)
6607 return tmp;
6610 /* Fall back to a constant byte-based permutation. */
6611 if (qimode != VOIDmode)
6613 vec = rtvec_alloc (w);
6614 for (i = 0; i < e; ++i)
6616 unsigned int j, this_e;
6618 this_e = INTVAL (CONST_VECTOR_ELT (sel, i));
6619 this_e &= 2 * e - 1;
6620 this_e *= u;
6622 for (j = 0; j < u; ++j)
6623 RTVEC_ELT (vec, i * u + j) = GEN_INT (this_e + j);
6625 sel_qi = gen_rtx_CONST_VECTOR (qimode, vec);
6627 icode = direct_optab_handler (vec_perm_const_optab, qimode);
6628 if (icode != CODE_FOR_nothing)
6630 tmp = expand_vec_perm_1 (icode, gen_lowpart (qimode, target),
6631 gen_lowpart (qimode, v0),
6632 gen_lowpart (qimode, v1), sel_qi);
6633 if (tmp)
6634 return gen_lowpart (mode, tmp);
6639 /* Otherwise expand as a fully variable permuation. */
6640 icode = direct_optab_handler (vec_perm_optab, mode);
6641 if (icode != CODE_FOR_nothing)
6643 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
6644 if (tmp)
6645 return tmp;
6648 /* As a special case to aid several targets, lower the element-based
6649 permutation to a byte-based permutation and try again. */
6650 if (qimode == VOIDmode)
6651 return NULL_RTX;
6652 icode = direct_optab_handler (vec_perm_optab, qimode);
6653 if (icode == CODE_FOR_nothing)
6654 return NULL_RTX;
6656 if (sel_qi == NULL)
6658 /* Multiply each element by its byte size. */
6659 enum machine_mode selmode = GET_MODE (sel);
6660 if (u == 2)
6661 sel = expand_simple_binop (selmode, PLUS, sel, sel,
6662 sel, 0, OPTAB_DIRECT);
6663 else
6664 sel = expand_simple_binop (selmode, ASHIFT, sel,
6665 GEN_INT (exact_log2 (u)),
6666 sel, 0, OPTAB_DIRECT);
6667 gcc_assert (sel != NULL);
6669 /* Broadcast the low byte each element into each of its bytes. */
6670 vec = rtvec_alloc (w);
6671 for (i = 0; i < w; ++i)
6673 int this_e = i / u * u;
6674 if (BYTES_BIG_ENDIAN)
6675 this_e += u - 1;
6676 RTVEC_ELT (vec, i) = GEN_INT (this_e);
6678 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
6679 sel = gen_lowpart (qimode, sel);
6680 sel = expand_vec_perm (qimode, sel, sel, tmp, NULL);
6681 gcc_assert (sel != NULL);
6683 /* Add the byte offset to each byte element. */
6684 /* Note that the definition of the indicies here is memory ordering,
6685 so there should be no difference between big and little endian. */
6686 vec = rtvec_alloc (w);
6687 for (i = 0; i < w; ++i)
6688 RTVEC_ELT (vec, i) = GEN_INT (i % u);
6689 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
6690 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
6691 sel, 0, OPTAB_DIRECT);
6692 gcc_assert (sel_qi != NULL);
6695 tmp = expand_vec_perm_1 (icode, gen_lowpart (qimode, target),
6696 gen_lowpart (qimode, v0),
6697 gen_lowpart (qimode, v1), sel_qi);
6698 if (tmp)
6699 tmp = gen_lowpart (mode, tmp);
6700 return tmp;
6703 /* Return insn code for a conditional operator with a comparison in
6704 mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE. */
6706 static inline enum insn_code
6707 get_vcond_icode (enum machine_mode vmode, enum machine_mode cmode, bool uns)
6709 enum insn_code icode = CODE_FOR_nothing;
6710 if (uns)
6711 icode = convert_optab_handler (vcondu_optab, vmode, cmode);
6712 else
6713 icode = convert_optab_handler (vcond_optab, vmode, cmode);
6714 return icode;
6717 /* Return TRUE iff, appropriate vector insns are available
6718 for vector cond expr with vector type VALUE_TYPE and a comparison
6719 with operand vector types in CMP_OP_TYPE. */
6721 bool
6722 expand_vec_cond_expr_p (tree value_type, tree cmp_op_type)
6724 enum machine_mode value_mode = TYPE_MODE (value_type);
6725 enum machine_mode cmp_op_mode = TYPE_MODE (cmp_op_type);
6726 if (GET_MODE_SIZE (value_mode) != GET_MODE_SIZE (cmp_op_mode)
6727 || GET_MODE_NUNITS (value_mode) != GET_MODE_NUNITS (cmp_op_mode)
6728 || get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type),
6729 TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing)
6730 return false;
6731 return true;
6734 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
6735 three operands. */
6738 expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
6739 rtx target)
6741 struct expand_operand ops[6];
6742 enum insn_code icode;
6743 rtx comparison, rtx_op1, rtx_op2;
6744 enum machine_mode mode = TYPE_MODE (vec_cond_type);
6745 enum machine_mode cmp_op_mode;
6746 bool unsignedp;
6747 tree op0a, op0b;
6748 enum tree_code tcode;
6750 if (COMPARISON_CLASS_P (op0))
6752 op0a = TREE_OPERAND (op0, 0);
6753 op0b = TREE_OPERAND (op0, 1);
6754 tcode = TREE_CODE (op0);
6756 else
6758 /* Fake op0 < 0. */
6759 gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (op0)));
6760 op0a = op0;
6761 op0b = build_zero_cst (TREE_TYPE (op0));
6762 tcode = LT_EXPR;
6764 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
6765 cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
6768 gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
6769 && GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
6771 icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
6772 if (icode == CODE_FOR_nothing)
6773 return 0;
6775 comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode);
6776 rtx_op1 = expand_normal (op1);
6777 rtx_op2 = expand_normal (op2);
6779 create_output_operand (&ops[0], target, mode);
6780 create_input_operand (&ops[1], rtx_op1, mode);
6781 create_input_operand (&ops[2], rtx_op2, mode);
6782 create_fixed_operand (&ops[3], comparison);
6783 create_fixed_operand (&ops[4], XEXP (comparison, 0));
6784 create_fixed_operand (&ops[5], XEXP (comparison, 1));
6785 expand_insn (icode, 6, ops);
6786 return ops[0].value;
6789 /* Return non-zero if a highpart multiply is supported of can be synthisized.
6790 For the benefit of expand_mult_highpart, the return value is 1 for direct,
6791 2 for even/odd widening, and 3 for hi/lo widening. */
6794 can_mult_highpart_p (enum machine_mode mode, bool uns_p)
6796 optab op;
6797 unsigned char *sel;
6798 unsigned i, nunits;
6800 op = uns_p ? umul_highpart_optab : smul_highpart_optab;
6801 if (optab_handler (op, mode) != CODE_FOR_nothing)
6802 return 1;
6804 /* If the mode is an integral vector, synth from widening operations. */
6805 if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
6806 return 0;
6808 nunits = GET_MODE_NUNITS (mode);
6809 sel = XALLOCAVEC (unsigned char, nunits);
6811 op = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
6812 if (optab_handler (op, mode) != CODE_FOR_nothing)
6814 op = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
6815 if (optab_handler (op, mode) != CODE_FOR_nothing)
6817 for (i = 0; i < nunits; ++i)
6818 sel[i] = !BYTES_BIG_ENDIAN + (i & ~1) + ((i & 1) ? nunits : 0);
6819 if (can_vec_perm_p (mode, false, sel))
6820 return 2;
6824 op = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
6825 if (optab_handler (op, mode) != CODE_FOR_nothing)
6827 op = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
6828 if (optab_handler (op, mode) != CODE_FOR_nothing)
6830 for (i = 0; i < nunits; ++i)
6831 sel[i] = 2 * i + (BYTES_BIG_ENDIAN ? 0 : 1);
6832 if (can_vec_perm_p (mode, false, sel))
6833 return 3;
6837 return 0;
6840 /* Expand a highpart multiply. */
6843 expand_mult_highpart (enum machine_mode mode, rtx op0, rtx op1,
6844 rtx target, bool uns_p)
6846 struct expand_operand eops[3];
6847 enum insn_code icode;
6848 int method, i, nunits;
6849 enum machine_mode wmode;
6850 rtx m1, m2, perm;
6851 optab tab1, tab2;
6852 rtvec v;
6854 method = can_mult_highpart_p (mode, uns_p);
6855 switch (method)
6857 case 0:
6858 return NULL_RTX;
6859 case 1:
6860 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
6861 return expand_binop (mode, tab1, op0, op1, target, uns_p,
6862 OPTAB_LIB_WIDEN);
6863 case 2:
6864 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
6865 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
6866 break;
6867 case 3:
6868 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
6869 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
6870 if (BYTES_BIG_ENDIAN)
6872 optab t = tab1;
6873 tab1 = tab2;
6874 tab2 = t;
6876 break;
6877 default:
6878 gcc_unreachable ();
6881 icode = optab_handler (tab1, mode);
6882 nunits = GET_MODE_NUNITS (mode);
6883 wmode = insn_data[icode].operand[0].mode;
6884 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode) == nunits);
6885 gcc_checking_assert (GET_MODE_SIZE (wmode) == GET_MODE_SIZE (mode));
6887 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
6888 create_input_operand (&eops[1], op0, mode);
6889 create_input_operand (&eops[2], op1, mode);
6890 expand_insn (icode, 3, eops);
6891 m1 = gen_lowpart (mode, eops[0].value);
6893 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
6894 create_input_operand (&eops[1], op0, mode);
6895 create_input_operand (&eops[2], op1, mode);
6896 expand_insn (optab_handler (tab2, mode), 3, eops);
6897 m2 = gen_lowpart (mode, eops[0].value);
6899 v = rtvec_alloc (nunits);
6900 if (method == 2)
6902 for (i = 0; i < nunits; ++i)
6903 RTVEC_ELT (v, i) = GEN_INT (!BYTES_BIG_ENDIAN + (i & ~1)
6904 + ((i & 1) ? nunits : 0));
6906 else
6908 for (i = 0; i < nunits; ++i)
6909 RTVEC_ELT (v, i) = GEN_INT (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
6911 perm = gen_rtx_CONST_VECTOR (mode, v);
6913 return expand_vec_perm (mode, m1, m2, perm, target);
6916 /* Return true if there is a compare_and_swap pattern. */
6918 bool
6919 can_compare_and_swap_p (enum machine_mode mode, bool allow_libcall)
6921 enum insn_code icode;
6923 /* Check for __atomic_compare_and_swap. */
6924 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
6925 if (icode != CODE_FOR_nothing)
6926 return true;
6928 /* Check for __sync_compare_and_swap. */
6929 icode = optab_handler (sync_compare_and_swap_optab, mode);
6930 if (icode != CODE_FOR_nothing)
6931 return true;
6932 if (allow_libcall && optab_libfunc (sync_compare_and_swap_optab, mode))
6933 return true;
6935 /* No inline compare and swap. */
6936 return false;
6939 /* Return true if an atomic exchange can be performed. */
6941 bool
6942 can_atomic_exchange_p (enum machine_mode mode, bool allow_libcall)
6944 enum insn_code icode;
6946 /* Check for __atomic_exchange. */
6947 icode = direct_optab_handler (atomic_exchange_optab, mode);
6948 if (icode != CODE_FOR_nothing)
6949 return true;
6951 /* Don't check __sync_test_and_set, as on some platforms that
6952 has reduced functionality. Targets that really do support
6953 a proper exchange should simply be updated to the __atomics. */
6955 return can_compare_and_swap_p (mode, allow_libcall);
6959 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
6960 pattern. */
6962 static void
6963 find_cc_set (rtx x, const_rtx pat, void *data)
6965 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
6966 && GET_CODE (pat) == SET)
6968 rtx *p_cc_reg = (rtx *) data;
6969 gcc_assert (!*p_cc_reg);
6970 *p_cc_reg = x;
6974 /* This is a helper function for the other atomic operations. This function
6975 emits a loop that contains SEQ that iterates until a compare-and-swap
6976 operation at the end succeeds. MEM is the memory to be modified. SEQ is
6977 a set of instructions that takes a value from OLD_REG as an input and
6978 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
6979 set to the current contents of MEM. After SEQ, a compare-and-swap will
6980 attempt to update MEM with NEW_REG. The function returns true when the
6981 loop was generated successfully. */
6983 static bool
6984 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
6986 enum machine_mode mode = GET_MODE (mem);
6987 rtx label, cmp_reg, success, oldval;
6989 /* The loop we want to generate looks like
6991 cmp_reg = mem;
6992 label:
6993 old_reg = cmp_reg;
6994 seq;
6995 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
6996 if (success)
6997 goto label;
6999 Note that we only do the plain load from memory once. Subsequent
7000 iterations use the value loaded by the compare-and-swap pattern. */
7002 label = gen_label_rtx ();
7003 cmp_reg = gen_reg_rtx (mode);
7005 emit_move_insn (cmp_reg, mem);
7006 emit_label (label);
7007 emit_move_insn (old_reg, cmp_reg);
7008 if (seq)
7009 emit_insn (seq);
7011 success = NULL_RTX;
7012 oldval = cmp_reg;
7013 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
7014 new_reg, false, MEMMODEL_SEQ_CST,
7015 MEMMODEL_RELAXED))
7016 return false;
7018 if (oldval != cmp_reg)
7019 emit_move_insn (cmp_reg, oldval);
7021 /* Mark this jump predicted not taken. */
7022 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
7023 GET_MODE (success), 1, label, 0);
7024 return true;
7028 /* This function tries to emit an atomic_exchange intruction. VAL is written
7029 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
7030 using TARGET if possible. */
7032 static rtx
7033 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
7035 enum machine_mode mode = GET_MODE (mem);
7036 enum insn_code icode;
7038 /* If the target supports the exchange directly, great. */
7039 icode = direct_optab_handler (atomic_exchange_optab, mode);
7040 if (icode != CODE_FOR_nothing)
7042 struct expand_operand ops[4];
7044 create_output_operand (&ops[0], target, mode);
7045 create_fixed_operand (&ops[1], mem);
7046 create_input_operand (&ops[2], val, mode);
7047 create_integer_operand (&ops[3], model);
7048 if (maybe_expand_insn (icode, 4, ops))
7049 return ops[0].value;
7052 return NULL_RTX;
7055 /* This function tries to implement an atomic exchange operation using
7056 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
7057 The previous contents of *MEM are returned, using TARGET if possible.
7058 Since this instructionn is an acquire barrier only, stronger memory
7059 models may require additional barriers to be emitted. */
7061 static rtx
7062 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
7063 enum memmodel model)
7065 enum machine_mode mode = GET_MODE (mem);
7066 enum insn_code icode;
7067 rtx last_insn = get_last_insn ();
7069 icode = optab_handler (sync_lock_test_and_set_optab, mode);
7071 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
7072 exists, and the memory model is stronger than acquire, add a release
7073 barrier before the instruction. */
7075 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST
7076 || (model & MEMMODEL_MASK) == MEMMODEL_RELEASE
7077 || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
7078 expand_mem_thread_fence (model);
7080 if (icode != CODE_FOR_nothing)
7082 struct expand_operand ops[3];
7083 create_output_operand (&ops[0], target, mode);
7084 create_fixed_operand (&ops[1], mem);
7085 create_input_operand (&ops[2], val, mode);
7086 if (maybe_expand_insn (icode, 3, ops))
7087 return ops[0].value;
7090 /* If an external test-and-set libcall is provided, use that instead of
7091 any external compare-and-swap that we might get from the compare-and-
7092 swap-loop expansion later. */
7093 if (!can_compare_and_swap_p (mode, false))
7095 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
7096 if (libfunc != NULL)
7098 rtx addr;
7100 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7101 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
7102 mode, 2, addr, ptr_mode,
7103 val, mode);
7107 /* If the test_and_set can't be emitted, eliminate any barrier that might
7108 have been emitted. */
7109 delete_insns_since (last_insn);
7110 return NULL_RTX;
7113 /* This function tries to implement an atomic exchange operation using a
7114 compare_and_swap loop. VAL is written to *MEM. The previous contents of
7115 *MEM are returned, using TARGET if possible. No memory model is required
7116 since a compare_and_swap loop is seq-cst. */
7118 static rtx
7119 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
7121 enum machine_mode mode = GET_MODE (mem);
7123 if (can_compare_and_swap_p (mode, true))
7125 if (!target || !register_operand (target, mode))
7126 target = gen_reg_rtx (mode);
7127 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
7128 return target;
7131 return NULL_RTX;
7134 /* This function tries to implement an atomic test-and-set operation
7135 using the atomic_test_and_set instruction pattern. A boolean value
7136 is returned from the operation, using TARGET if possible. */
7138 #ifndef HAVE_atomic_test_and_set
7139 #define HAVE_atomic_test_and_set 0
7140 #define CODE_FOR_atomic_test_and_set CODE_FOR_nothing
7141 #endif
7143 static rtx
7144 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
7146 enum machine_mode pat_bool_mode;
7147 struct expand_operand ops[3];
7149 if (!HAVE_atomic_test_and_set)
7150 return NULL_RTX;
7152 /* While we always get QImode from __atomic_test_and_set, we get
7153 other memory modes from __sync_lock_test_and_set. Note that we
7154 use no endian adjustment here. This matches the 4.6 behavior
7155 in the Sparc backend. */
7156 gcc_checking_assert
7157 (insn_data[CODE_FOR_atomic_test_and_set].operand[1].mode == QImode);
7158 if (GET_MODE (mem) != QImode)
7159 mem = adjust_address_nv (mem, QImode, 0);
7161 pat_bool_mode = insn_data[CODE_FOR_atomic_test_and_set].operand[0].mode;
7162 create_output_operand (&ops[0], target, pat_bool_mode);
7163 create_fixed_operand (&ops[1], mem);
7164 create_integer_operand (&ops[2], model);
7166 if (maybe_expand_insn (CODE_FOR_atomic_test_and_set, 3, ops))
7167 return ops[0].value;
7168 return NULL_RTX;
7171 /* This function expands the legacy _sync_lock test_and_set operation which is
7172 generally an atomic exchange. Some limited targets only allow the
7173 constant 1 to be stored. This is an ACQUIRE operation.
7175 TARGET is an optional place to stick the return value.
7176 MEM is where VAL is stored. */
7179 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
7181 rtx ret;
7183 /* Try an atomic_exchange first. */
7184 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_ACQUIRE);
7185 if (ret)
7186 return ret;
7188 ret = maybe_emit_sync_lock_test_and_set (target, mem, val, MEMMODEL_ACQUIRE);
7189 if (ret)
7190 return ret;
7192 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
7193 if (ret)
7194 return ret;
7196 /* If there are no other options, try atomic_test_and_set if the value
7197 being stored is 1. */
7198 if (val == const1_rtx)
7199 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_ACQUIRE);
7201 return ret;
7204 /* This function expands the atomic test_and_set operation:
7205 atomically store a boolean TRUE into MEM and return the previous value.
7207 MEMMODEL is the memory model variant to use.
7208 TARGET is an optional place to stick the return value. */
7211 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
7213 enum machine_mode mode = GET_MODE (mem);
7214 rtx ret, trueval, subtarget;
7216 ret = maybe_emit_atomic_test_and_set (target, mem, model);
7217 if (ret)
7218 return ret;
7220 /* Be binary compatible with non-default settings of trueval, and different
7221 cpu revisions. E.g. one revision may have atomic-test-and-set, but
7222 another only has atomic-exchange. */
7223 if (targetm.atomic_test_and_set_trueval == 1)
7225 trueval = const1_rtx;
7226 subtarget = target ? target : gen_reg_rtx (mode);
7228 else
7230 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
7231 subtarget = gen_reg_rtx (mode);
7234 /* Try the atomic-exchange optab... */
7235 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
7237 /* ... then an atomic-compare-and-swap loop ... */
7238 if (!ret)
7239 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
7241 /* ... before trying the vaguely defined legacy lock_test_and_set. */
7242 if (!ret)
7243 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
7245 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
7246 things with the value 1. Thus we try again without trueval. */
7247 if (!ret && targetm.atomic_test_and_set_trueval != 1)
7248 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
7250 /* Failing all else, assume a single threaded environment and simply
7251 perform the operation. */
7252 if (!ret)
7254 emit_move_insn (subtarget, mem);
7255 emit_move_insn (mem, trueval);
7256 ret = subtarget;
7259 /* Recall that have to return a boolean value; rectify if trueval
7260 is not exactly one. */
7261 if (targetm.atomic_test_and_set_trueval != 1)
7262 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
7264 return ret;
7267 /* This function expands the atomic exchange operation:
7268 atomically store VAL in MEM and return the previous value in MEM.
7270 MEMMODEL is the memory model variant to use.
7271 TARGET is an optional place to stick the return value. */
7274 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
7276 rtx ret;
7278 ret = maybe_emit_atomic_exchange (target, mem, val, model);
7280 /* Next try a compare-and-swap loop for the exchange. */
7281 if (!ret)
7282 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
7284 return ret;
7287 /* This function expands the atomic compare exchange operation:
7289 *PTARGET_BOOL is an optional place to store the boolean success/failure.
7290 *PTARGET_OVAL is an optional place to store the old value from memory.
7291 Both target parameters may be NULL to indicate that we do not care about
7292 that return value. Both target parameters are updated on success to
7293 the actual location of the corresponding result.
7295 MEMMODEL is the memory model variant to use.
7297 The return value of the function is true for success. */
7299 bool
7300 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
7301 rtx mem, rtx expected, rtx desired,
7302 bool is_weak, enum memmodel succ_model,
7303 enum memmodel fail_model)
7305 enum machine_mode mode = GET_MODE (mem);
7306 struct expand_operand ops[8];
7307 enum insn_code icode;
7308 rtx target_oval, target_bool = NULL_RTX;
7309 rtx libfunc;
7311 /* Load expected into a register for the compare and swap. */
7312 if (MEM_P (expected))
7313 expected = copy_to_reg (expected);
7315 /* Make sure we always have some place to put the return oldval.
7316 Further, make sure that place is distinct from the input expected,
7317 just in case we need that path down below. */
7318 if (ptarget_oval == NULL
7319 || (target_oval = *ptarget_oval) == NULL
7320 || reg_overlap_mentioned_p (expected, target_oval))
7321 target_oval = gen_reg_rtx (mode);
7323 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
7324 if (icode != CODE_FOR_nothing)
7326 enum machine_mode bool_mode = insn_data[icode].operand[0].mode;
7328 /* Make sure we always have a place for the bool operand. */
7329 if (ptarget_bool == NULL
7330 || (target_bool = *ptarget_bool) == NULL
7331 || GET_MODE (target_bool) != bool_mode)
7332 target_bool = gen_reg_rtx (bool_mode);
7334 /* Emit the compare_and_swap. */
7335 create_output_operand (&ops[0], target_bool, bool_mode);
7336 create_output_operand (&ops[1], target_oval, mode);
7337 create_fixed_operand (&ops[2], mem);
7338 create_input_operand (&ops[3], expected, mode);
7339 create_input_operand (&ops[4], desired, mode);
7340 create_integer_operand (&ops[5], is_weak);
7341 create_integer_operand (&ops[6], succ_model);
7342 create_integer_operand (&ops[7], fail_model);
7343 expand_insn (icode, 8, ops);
7345 /* Return success/failure. */
7346 target_bool = ops[0].value;
7347 target_oval = ops[1].value;
7348 goto success;
7351 /* Otherwise fall back to the original __sync_val_compare_and_swap
7352 which is always seq-cst. */
7353 icode = optab_handler (sync_compare_and_swap_optab, mode);
7354 if (icode != CODE_FOR_nothing)
7356 rtx cc_reg;
7358 create_output_operand (&ops[0], target_oval, mode);
7359 create_fixed_operand (&ops[1], mem);
7360 create_input_operand (&ops[2], expected, mode);
7361 create_input_operand (&ops[3], desired, mode);
7362 if (!maybe_expand_insn (icode, 4, ops))
7363 return false;
7365 target_oval = ops[0].value;
7367 /* If the caller isn't interested in the boolean return value,
7368 skip the computation of it. */
7369 if (ptarget_bool == NULL)
7370 goto success;
7372 /* Otherwise, work out if the compare-and-swap succeeded. */
7373 cc_reg = NULL_RTX;
7374 if (have_insn_for (COMPARE, CCmode))
7375 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
7376 if (cc_reg)
7378 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
7379 const0_rtx, VOIDmode, 0, 1);
7380 goto success;
7382 goto success_bool_from_val;
7385 /* Also check for library support for __sync_val_compare_and_swap. */
7386 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
7387 if (libfunc != NULL)
7389 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7390 target_oval = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
7391 mode, 3, addr, ptr_mode,
7392 expected, mode, desired, mode);
7394 /* Compute the boolean return value only if requested. */
7395 if (ptarget_bool)
7396 goto success_bool_from_val;
7397 else
7398 goto success;
7401 /* Failure. */
7402 return false;
7404 success_bool_from_val:
7405 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
7406 expected, VOIDmode, 1, 1);
7407 success:
7408 /* Make sure that the oval output winds up where the caller asked. */
7409 if (ptarget_oval)
7410 *ptarget_oval = target_oval;
7411 if (ptarget_bool)
7412 *ptarget_bool = target_bool;
7413 return true;
7416 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
7418 static void
7419 expand_asm_memory_barrier (void)
7421 rtx asm_op, clob;
7423 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, empty_string, empty_string, 0,
7424 rtvec_alloc (0), rtvec_alloc (0),
7425 rtvec_alloc (0), UNKNOWN_LOCATION);
7426 MEM_VOLATILE_P (asm_op) = 1;
7428 clob = gen_rtx_SCRATCH (VOIDmode);
7429 clob = gen_rtx_MEM (BLKmode, clob);
7430 clob = gen_rtx_CLOBBER (VOIDmode, clob);
7432 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
7435 /* This routine will either emit the mem_thread_fence pattern or issue a
7436 sync_synchronize to generate a fence for memory model MEMMODEL. */
7438 #ifndef HAVE_mem_thread_fence
7439 # define HAVE_mem_thread_fence 0
7440 # define gen_mem_thread_fence(x) (gcc_unreachable (), NULL_RTX)
7441 #endif
7442 #ifndef HAVE_memory_barrier
7443 # define HAVE_memory_barrier 0
7444 # define gen_memory_barrier() (gcc_unreachable (), NULL_RTX)
7445 #endif
7447 void
7448 expand_mem_thread_fence (enum memmodel model)
7450 if (HAVE_mem_thread_fence)
7451 emit_insn (gen_mem_thread_fence (GEN_INT (model)));
7452 else if ((model & MEMMODEL_MASK) != MEMMODEL_RELAXED)
7454 if (HAVE_memory_barrier)
7455 emit_insn (gen_memory_barrier ());
7456 else if (synchronize_libfunc != NULL_RTX)
7457 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
7458 else
7459 expand_asm_memory_barrier ();
7463 /* This routine will either emit the mem_signal_fence pattern or issue a
7464 sync_synchronize to generate a fence for memory model MEMMODEL. */
7466 #ifndef HAVE_mem_signal_fence
7467 # define HAVE_mem_signal_fence 0
7468 # define gen_mem_signal_fence(x) (gcc_unreachable (), NULL_RTX)
7469 #endif
7471 void
7472 expand_mem_signal_fence (enum memmodel model)
7474 if (HAVE_mem_signal_fence)
7475 emit_insn (gen_mem_signal_fence (GEN_INT (model)));
7476 else if ((model & MEMMODEL_MASK) != MEMMODEL_RELAXED)
7478 /* By default targets are coherent between a thread and the signal
7479 handler running on the same thread. Thus this really becomes a
7480 compiler barrier, in that stores must not be sunk past
7481 (or raised above) a given point. */
7482 expand_asm_memory_barrier ();
7486 /* This function expands the atomic load operation:
7487 return the atomically loaded value in MEM.
7489 MEMMODEL is the memory model variant to use.
7490 TARGET is an option place to stick the return value. */
7493 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
7495 enum machine_mode mode = GET_MODE (mem);
7496 enum insn_code icode;
7498 /* If the target supports the load directly, great. */
7499 icode = direct_optab_handler (atomic_load_optab, mode);
7500 if (icode != CODE_FOR_nothing)
7502 struct expand_operand ops[3];
7504 create_output_operand (&ops[0], target, mode);
7505 create_fixed_operand (&ops[1], mem);
7506 create_integer_operand (&ops[2], model);
7507 if (maybe_expand_insn (icode, 3, ops))
7508 return ops[0].value;
7511 /* If the size of the object is greater than word size on this target,
7512 then we assume that a load will not be atomic. */
7513 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
7515 /* Issue val = compare_and_swap (mem, 0, 0).
7516 This may cause the occasional harmless store of 0 when the value is
7517 already 0, but it seems to be OK according to the standards guys. */
7518 if (expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
7519 const0_rtx, false, model, model))
7520 return target;
7521 else
7522 /* Otherwise there is no atomic load, leave the library call. */
7523 return NULL_RTX;
7526 /* Otherwise assume loads are atomic, and emit the proper barriers. */
7527 if (!target || target == const0_rtx)
7528 target = gen_reg_rtx (mode);
7530 /* For SEQ_CST, emit a barrier before the load. */
7531 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST)
7532 expand_mem_thread_fence (model);
7534 emit_move_insn (target, mem);
7536 /* Emit the appropriate barrier after the load. */
7537 expand_mem_thread_fence (model);
7539 return target;
7542 /* This function expands the atomic store operation:
7543 Atomically store VAL in MEM.
7544 MEMMODEL is the memory model variant to use.
7545 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
7546 function returns const0_rtx if a pattern was emitted. */
7549 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
7551 enum machine_mode mode = GET_MODE (mem);
7552 enum insn_code icode;
7553 struct expand_operand ops[3];
7555 /* If the target supports the store directly, great. */
7556 icode = direct_optab_handler (atomic_store_optab, mode);
7557 if (icode != CODE_FOR_nothing)
7559 create_fixed_operand (&ops[0], mem);
7560 create_input_operand (&ops[1], val, mode);
7561 create_integer_operand (&ops[2], model);
7562 if (maybe_expand_insn (icode, 3, ops))
7563 return const0_rtx;
7566 /* If using __sync_lock_release is a viable alternative, try it. */
7567 if (use_release)
7569 icode = direct_optab_handler (sync_lock_release_optab, mode);
7570 if (icode != CODE_FOR_nothing)
7572 create_fixed_operand (&ops[0], mem);
7573 create_input_operand (&ops[1], const0_rtx, mode);
7574 if (maybe_expand_insn (icode, 2, ops))
7576 /* lock_release is only a release barrier. */
7577 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST)
7578 expand_mem_thread_fence (model);
7579 return const0_rtx;
7584 /* If the size of the object is greater than word size on this target,
7585 a default store will not be atomic, Try a mem_exchange and throw away
7586 the result. If that doesn't work, don't do anything. */
7587 if (GET_MODE_PRECISION(mode) > BITS_PER_WORD)
7589 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
7590 if (!target)
7591 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val);
7592 if (target)
7593 return const0_rtx;
7594 else
7595 return NULL_RTX;
7598 /* Otherwise assume stores are atomic, and emit the proper barriers. */
7599 expand_mem_thread_fence (model);
7601 emit_move_insn (mem, val);
7603 /* For SEQ_CST, also emit a barrier after the store. */
7604 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST)
7605 expand_mem_thread_fence (model);
7607 return const0_rtx;
7611 /* Structure containing the pointers and values required to process the
7612 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
7614 struct atomic_op_functions
7616 direct_optab mem_fetch_before;
7617 direct_optab mem_fetch_after;
7618 direct_optab mem_no_result;
7619 optab fetch_before;
7620 optab fetch_after;
7621 direct_optab no_result;
7622 enum rtx_code reverse_code;
7626 /* Fill in structure pointed to by OP with the various optab entries for an
7627 operation of type CODE. */
7629 static void
7630 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
7632 gcc_assert (op!= NULL);
7634 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
7635 in the source code during compilation, and the optab entries are not
7636 computable until runtime. Fill in the values at runtime. */
7637 switch (code)
7639 case PLUS:
7640 op->mem_fetch_before = atomic_fetch_add_optab;
7641 op->mem_fetch_after = atomic_add_fetch_optab;
7642 op->mem_no_result = atomic_add_optab;
7643 op->fetch_before = sync_old_add_optab;
7644 op->fetch_after = sync_new_add_optab;
7645 op->no_result = sync_add_optab;
7646 op->reverse_code = MINUS;
7647 break;
7648 case MINUS:
7649 op->mem_fetch_before = atomic_fetch_sub_optab;
7650 op->mem_fetch_after = atomic_sub_fetch_optab;
7651 op->mem_no_result = atomic_sub_optab;
7652 op->fetch_before = sync_old_sub_optab;
7653 op->fetch_after = sync_new_sub_optab;
7654 op->no_result = sync_sub_optab;
7655 op->reverse_code = PLUS;
7656 break;
7657 case XOR:
7658 op->mem_fetch_before = atomic_fetch_xor_optab;
7659 op->mem_fetch_after = atomic_xor_fetch_optab;
7660 op->mem_no_result = atomic_xor_optab;
7661 op->fetch_before = sync_old_xor_optab;
7662 op->fetch_after = sync_new_xor_optab;
7663 op->no_result = sync_xor_optab;
7664 op->reverse_code = XOR;
7665 break;
7666 case AND:
7667 op->mem_fetch_before = atomic_fetch_and_optab;
7668 op->mem_fetch_after = atomic_and_fetch_optab;
7669 op->mem_no_result = atomic_and_optab;
7670 op->fetch_before = sync_old_and_optab;
7671 op->fetch_after = sync_new_and_optab;
7672 op->no_result = sync_and_optab;
7673 op->reverse_code = UNKNOWN;
7674 break;
7675 case IOR:
7676 op->mem_fetch_before = atomic_fetch_or_optab;
7677 op->mem_fetch_after = atomic_or_fetch_optab;
7678 op->mem_no_result = atomic_or_optab;
7679 op->fetch_before = sync_old_ior_optab;
7680 op->fetch_after = sync_new_ior_optab;
7681 op->no_result = sync_ior_optab;
7682 op->reverse_code = UNKNOWN;
7683 break;
7684 case NOT:
7685 op->mem_fetch_before = atomic_fetch_nand_optab;
7686 op->mem_fetch_after = atomic_nand_fetch_optab;
7687 op->mem_no_result = atomic_nand_optab;
7688 op->fetch_before = sync_old_nand_optab;
7689 op->fetch_after = sync_new_nand_optab;
7690 op->no_result = sync_nand_optab;
7691 op->reverse_code = UNKNOWN;
7692 break;
7693 default:
7694 gcc_unreachable ();
7698 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
7699 using memory order MODEL. If AFTER is true the operation needs to return
7700 the value of *MEM after the operation, otherwise the previous value.
7701 TARGET is an optional place to place the result. The result is unused if
7702 it is const0_rtx.
7703 Return the result if there is a better sequence, otherwise NULL_RTX. */
7705 static rtx
7706 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
7707 enum memmodel model, bool after)
7709 /* If the value is prefetched, or not used, it may be possible to replace
7710 the sequence with a native exchange operation. */
7711 if (!after || target == const0_rtx)
7713 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
7714 if (code == AND && val == const0_rtx)
7716 if (target == const0_rtx)
7717 target = gen_reg_rtx (GET_MODE (mem));
7718 return maybe_emit_atomic_exchange (target, mem, val, model);
7721 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
7722 if (code == IOR && val == constm1_rtx)
7724 if (target == const0_rtx)
7725 target = gen_reg_rtx (GET_MODE (mem));
7726 return maybe_emit_atomic_exchange (target, mem, val, model);
7730 return NULL_RTX;
7733 /* Try to emit an instruction for a specific operation varaition.
7734 OPTAB contains the OP functions.
7735 TARGET is an optional place to return the result. const0_rtx means unused.
7736 MEM is the memory location to operate on.
7737 VAL is the value to use in the operation.
7738 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
7739 MODEL is the memory model, if used.
7740 AFTER is true if the returned result is the value after the operation. */
7742 static rtx
7743 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
7744 rtx val, bool use_memmodel, enum memmodel model, bool after)
7746 enum machine_mode mode = GET_MODE (mem);
7747 struct expand_operand ops[4];
7748 enum insn_code icode;
7749 int op_counter = 0;
7750 int num_ops;
7752 /* Check to see if there is a result returned. */
7753 if (target == const0_rtx)
7755 if (use_memmodel)
7757 icode = direct_optab_handler (optab->mem_no_result, mode);
7758 create_integer_operand (&ops[2], model);
7759 num_ops = 3;
7761 else
7763 icode = direct_optab_handler (optab->no_result, mode);
7764 num_ops = 2;
7767 /* Otherwise, we need to generate a result. */
7768 else
7770 if (use_memmodel)
7772 icode = direct_optab_handler (after ? optab->mem_fetch_after
7773 : optab->mem_fetch_before, mode);
7774 create_integer_operand (&ops[3], model);
7775 num_ops = 4;
7777 else
7779 icode = optab_handler (after ? optab->fetch_after
7780 : optab->fetch_before, mode);
7781 num_ops = 3;
7783 create_output_operand (&ops[op_counter++], target, mode);
7785 if (icode == CODE_FOR_nothing)
7786 return NULL_RTX;
7788 create_fixed_operand (&ops[op_counter++], mem);
7789 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7790 create_convert_operand_to (&ops[op_counter++], val, mode, true);
7792 if (maybe_expand_insn (icode, num_ops, ops))
7793 return (target == const0_rtx ? const0_rtx : ops[0].value);
7795 return NULL_RTX;
7799 /* This function expands an atomic fetch_OP or OP_fetch operation:
7800 TARGET is an option place to stick the return value. const0_rtx indicates
7801 the result is unused.
7802 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7803 CODE is the operation being performed (OP)
7804 MEMMODEL is the memory model variant to use.
7805 AFTER is true to return the result of the operation (OP_fetch).
7806 AFTER is false to return the value before the operation (fetch_OP).
7808 This function will *only* generate instructions if there is a direct
7809 optab. No compare and swap loops or libcalls will be generated. */
7811 static rtx
7812 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
7813 enum rtx_code code, enum memmodel model,
7814 bool after)
7816 enum machine_mode mode = GET_MODE (mem);
7817 struct atomic_op_functions optab;
7818 rtx result;
7819 bool unused_result = (target == const0_rtx);
7821 get_atomic_op_for_code (&optab, code);
7823 /* Check to see if there are any better instructions. */
7824 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
7825 if (result)
7826 return result;
7828 /* Check for the case where the result isn't used and try those patterns. */
7829 if (unused_result)
7831 /* Try the memory model variant first. */
7832 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
7833 if (result)
7834 return result;
7836 /* Next try the old style withuot a memory model. */
7837 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
7838 if (result)
7839 return result;
7841 /* There is no no-result pattern, so try patterns with a result. */
7842 target = NULL_RTX;
7845 /* Try the __atomic version. */
7846 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
7847 if (result)
7848 return result;
7850 /* Try the older __sync version. */
7851 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
7852 if (result)
7853 return result;
7855 /* If the fetch value can be calculated from the other variation of fetch,
7856 try that operation. */
7857 if (after || unused_result || optab.reverse_code != UNKNOWN)
7859 /* Try the __atomic version, then the older __sync version. */
7860 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
7861 if (!result)
7862 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
7864 if (result)
7866 /* If the result isn't used, no need to do compensation code. */
7867 if (unused_result)
7868 return result;
7870 /* Issue compensation code. Fetch_after == fetch_before OP val.
7871 Fetch_before == after REVERSE_OP val. */
7872 if (!after)
7873 code = optab.reverse_code;
7874 if (code == NOT)
7876 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
7877 true, OPTAB_LIB_WIDEN);
7878 result = expand_simple_unop (mode, NOT, result, target, true);
7880 else
7881 result = expand_simple_binop (mode, code, result, val, target,
7882 true, OPTAB_LIB_WIDEN);
7883 return result;
7887 /* No direct opcode can be generated. */
7888 return NULL_RTX;
7893 /* This function expands an atomic fetch_OP or OP_fetch operation:
7894 TARGET is an option place to stick the return value. const0_rtx indicates
7895 the result is unused.
7896 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7897 CODE is the operation being performed (OP)
7898 MEMMODEL is the memory model variant to use.
7899 AFTER is true to return the result of the operation (OP_fetch).
7900 AFTER is false to return the value before the operation (fetch_OP). */
7902 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
7903 enum memmodel model, bool after)
7905 enum machine_mode mode = GET_MODE (mem);
7906 rtx result;
7907 bool unused_result = (target == const0_rtx);
7909 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
7910 after);
7912 if (result)
7913 return result;
7915 /* Add/sub can be implemented by doing the reverse operation with -(val). */
7916 if (code == PLUS || code == MINUS)
7918 rtx tmp;
7919 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
7921 start_sequence ();
7922 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
7923 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
7924 model, after);
7925 if (result)
7927 /* PLUS worked so emit the insns and return. */
7928 tmp = get_insns ();
7929 end_sequence ();
7930 emit_insn (tmp);
7931 return result;
7934 /* PLUS did not work, so throw away the negation code and continue. */
7935 end_sequence ();
7938 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
7939 if (!can_compare_and_swap_p (mode, false))
7941 rtx libfunc;
7942 bool fixup = false;
7943 enum rtx_code orig_code = code;
7944 struct atomic_op_functions optab;
7946 get_atomic_op_for_code (&optab, code);
7947 libfunc = optab_libfunc (after ? optab.fetch_after
7948 : optab.fetch_before, mode);
7949 if (libfunc == NULL
7950 && (after || unused_result || optab.reverse_code != UNKNOWN))
7952 fixup = true;
7953 if (!after)
7954 code = optab.reverse_code;
7955 libfunc = optab_libfunc (after ? optab.fetch_before
7956 : optab.fetch_after, mode);
7958 if (libfunc != NULL)
7960 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7961 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
7962 2, addr, ptr_mode, val, mode);
7964 if (!unused_result && fixup)
7965 result = expand_simple_binop (mode, code, result, val, target,
7966 true, OPTAB_LIB_WIDEN);
7967 return result;
7970 /* We need the original code for any further attempts. */
7971 code = orig_code;
7974 /* If nothing else has succeeded, default to a compare and swap loop. */
7975 if (can_compare_and_swap_p (mode, true))
7977 rtx insn;
7978 rtx t0 = gen_reg_rtx (mode), t1;
7980 start_sequence ();
7982 /* If the result is used, get a register for it. */
7983 if (!unused_result)
7985 if (!target || !register_operand (target, mode))
7986 target = gen_reg_rtx (mode);
7987 /* If fetch_before, copy the value now. */
7988 if (!after)
7989 emit_move_insn (target, t0);
7991 else
7992 target = const0_rtx;
7994 t1 = t0;
7995 if (code == NOT)
7997 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
7998 true, OPTAB_LIB_WIDEN);
7999 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
8001 else
8002 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
8003 OPTAB_LIB_WIDEN);
8005 /* For after, copy the value now. */
8006 if (!unused_result && after)
8007 emit_move_insn (target, t1);
8008 insn = get_insns ();
8009 end_sequence ();
8011 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
8012 return target;
8015 return NULL_RTX;
8018 /* Return true if OPERAND is suitable for operand number OPNO of
8019 instruction ICODE. */
8021 bool
8022 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
8024 return (!insn_data[(int) icode].operand[opno].predicate
8025 || (insn_data[(int) icode].operand[opno].predicate
8026 (operand, insn_data[(int) icode].operand[opno].mode)));
8029 /* TARGET is a target of a multiword operation that we are going to
8030 implement as a series of word-mode operations. Return true if
8031 TARGET is suitable for this purpose. */
8033 bool
8034 valid_multiword_target_p (rtx target)
8036 enum machine_mode mode;
8037 int i;
8039 mode = GET_MODE (target);
8040 for (i = 0; i < GET_MODE_SIZE (mode); i += UNITS_PER_WORD)
8041 if (!validate_subreg (word_mode, mode, target, i))
8042 return false;
8043 return true;
8046 /* Like maybe_legitimize_operand, but do not change the code of the
8047 current rtx value. */
8049 static bool
8050 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
8051 struct expand_operand *op)
8053 /* See if the operand matches in its current form. */
8054 if (insn_operand_matches (icode, opno, op->value))
8055 return true;
8057 /* If the operand is a memory whose address has no side effects,
8058 try forcing the address into a non-virtual pseudo register.
8059 The check for side effects is important because copy_to_mode_reg
8060 cannot handle things like auto-modified addresses. */
8061 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
8063 rtx addr, mem;
8065 mem = op->value;
8066 addr = XEXP (mem, 0);
8067 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
8068 && !side_effects_p (addr))
8070 rtx last;
8071 enum machine_mode mode;
8073 last = get_last_insn ();
8074 mode = get_address_mode (mem);
8075 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
8076 if (insn_operand_matches (icode, opno, mem))
8078 op->value = mem;
8079 return true;
8081 delete_insns_since (last);
8085 return false;
8088 /* Try to make OP match operand OPNO of instruction ICODE. Return true
8089 on success, storing the new operand value back in OP. */
8091 static bool
8092 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
8093 struct expand_operand *op)
8095 enum machine_mode mode, imode;
8096 bool old_volatile_ok, result;
8098 mode = op->mode;
8099 switch (op->type)
8101 case EXPAND_FIXED:
8102 old_volatile_ok = volatile_ok;
8103 volatile_ok = true;
8104 result = maybe_legitimize_operand_same_code (icode, opno, op);
8105 volatile_ok = old_volatile_ok;
8106 return result;
8108 case EXPAND_OUTPUT:
8109 gcc_assert (mode != VOIDmode);
8110 if (op->value
8111 && op->value != const0_rtx
8112 && GET_MODE (op->value) == mode
8113 && maybe_legitimize_operand_same_code (icode, opno, op))
8114 return true;
8116 op->value = gen_reg_rtx (mode);
8117 break;
8119 case EXPAND_INPUT:
8120 input:
8121 gcc_assert (mode != VOIDmode);
8122 gcc_assert (GET_MODE (op->value) == VOIDmode
8123 || GET_MODE (op->value) == mode);
8124 if (maybe_legitimize_operand_same_code (icode, opno, op))
8125 return true;
8127 op->value = copy_to_mode_reg (mode, op->value);
8128 break;
8130 case EXPAND_CONVERT_TO:
8131 gcc_assert (mode != VOIDmode);
8132 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
8133 goto input;
8135 case EXPAND_CONVERT_FROM:
8136 if (GET_MODE (op->value) != VOIDmode)
8137 mode = GET_MODE (op->value);
8138 else
8139 /* The caller must tell us what mode this value has. */
8140 gcc_assert (mode != VOIDmode);
8142 imode = insn_data[(int) icode].operand[opno].mode;
8143 if (imode != VOIDmode && imode != mode)
8145 op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
8146 mode = imode;
8148 goto input;
8150 case EXPAND_ADDRESS:
8151 gcc_assert (mode != VOIDmode);
8152 op->value = convert_memory_address (mode, op->value);
8153 goto input;
8155 case EXPAND_INTEGER:
8156 mode = insn_data[(int) icode].operand[opno].mode;
8157 if (mode != VOIDmode && const_int_operand (op->value, mode))
8158 goto input;
8159 break;
8161 return insn_operand_matches (icode, opno, op->value);
8164 /* Make OP describe an input operand that should have the same value
8165 as VALUE, after any mode conversion that the target might request.
8166 TYPE is the type of VALUE. */
8168 void
8169 create_convert_operand_from_type (struct expand_operand *op,
8170 rtx value, tree type)
8172 create_convert_operand_from (op, value, TYPE_MODE (type),
8173 TYPE_UNSIGNED (type));
8176 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
8177 of instruction ICODE. Return true on success, leaving the new operand
8178 values in the OPS themselves. Emit no code on failure. */
8180 bool
8181 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
8182 unsigned int nops, struct expand_operand *ops)
8184 rtx last;
8185 unsigned int i;
8187 last = get_last_insn ();
8188 for (i = 0; i < nops; i++)
8189 if (!maybe_legitimize_operand (icode, opno + i, &ops[i]))
8191 delete_insns_since (last);
8192 return false;
8194 return true;
8197 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
8198 as its operands. Return the instruction pattern on success,
8199 and emit any necessary set-up code. Return null and emit no
8200 code on failure. */
8203 maybe_gen_insn (enum insn_code icode, unsigned int nops,
8204 struct expand_operand *ops)
8206 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
8207 if (!maybe_legitimize_operands (icode, 0, nops, ops))
8208 return NULL_RTX;
8210 switch (nops)
8212 case 1:
8213 return GEN_FCN (icode) (ops[0].value);
8214 case 2:
8215 return GEN_FCN (icode) (ops[0].value, ops[1].value);
8216 case 3:
8217 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
8218 case 4:
8219 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8220 ops[3].value);
8221 case 5:
8222 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8223 ops[3].value, ops[4].value);
8224 case 6:
8225 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8226 ops[3].value, ops[4].value, ops[5].value);
8227 case 7:
8228 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8229 ops[3].value, ops[4].value, ops[5].value,
8230 ops[6].value);
8231 case 8:
8232 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8233 ops[3].value, ops[4].value, ops[5].value,
8234 ops[6].value, ops[7].value);
8236 gcc_unreachable ();
8239 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
8240 as its operands. Return true on success and emit no code on failure. */
8242 bool
8243 maybe_expand_insn (enum insn_code icode, unsigned int nops,
8244 struct expand_operand *ops)
8246 rtx pat = maybe_gen_insn (icode, nops, ops);
8247 if (pat)
8249 emit_insn (pat);
8250 return true;
8252 return false;
8255 /* Like maybe_expand_insn, but for jumps. */
8257 bool
8258 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
8259 struct expand_operand *ops)
8261 rtx pat = maybe_gen_insn (icode, nops, ops);
8262 if (pat)
8264 emit_jump_insn (pat);
8265 return true;
8267 return false;
8270 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
8271 as its operands. */
8273 void
8274 expand_insn (enum insn_code icode, unsigned int nops,
8275 struct expand_operand *ops)
8277 if (!maybe_expand_insn (icode, nops, ops))
8278 gcc_unreachable ();
8281 /* Like expand_insn, but for jumps. */
8283 void
8284 expand_jump_insn (enum insn_code icode, unsigned int nops,
8285 struct expand_operand *ops)
8287 if (!maybe_expand_jump_insn (icode, nops, ops))
8288 gcc_unreachable ();
8291 /* Reduce conditional compilation elsewhere. */
8292 #ifndef HAVE_insv
8293 #define HAVE_insv 0
8294 #define CODE_FOR_insv CODE_FOR_nothing
8295 #endif
8296 #ifndef HAVE_extv
8297 #define HAVE_extv 0
8298 #define CODE_FOR_extv CODE_FOR_nothing
8299 #endif
8300 #ifndef HAVE_extzv
8301 #define HAVE_extzv 0
8302 #define CODE_FOR_extzv CODE_FOR_nothing
8303 #endif
8305 /* Enumerates the possible types of structure operand to an
8306 extraction_insn. */
8307 enum extraction_type { ET_unaligned_mem, ET_reg };
8309 /* Check whether insv, extv or extzv pattern ICODE can be used for an
8310 insertion or extraction of type TYPE on a structure of mode MODE.
8311 Return true if so and fill in *INSN accordingly. STRUCT_OP is the
8312 operand number of the structure (the first sign_extract or zero_extract
8313 operand) and FIELD_OP is the operand number of the field (the other
8314 side of the set from the sign_extract or zero_extract). */
8316 static bool
8317 get_traditional_extraction_insn (extraction_insn *insn,
8318 enum extraction_type type,
8319 enum machine_mode mode,
8320 enum insn_code icode,
8321 int struct_op, int field_op)
8323 const struct insn_data_d *data = &insn_data[icode];
8325 enum machine_mode struct_mode = data->operand[struct_op].mode;
8326 if (struct_mode == VOIDmode)
8327 struct_mode = word_mode;
8328 if (mode != struct_mode)
8329 return false;
8331 enum machine_mode field_mode = data->operand[field_op].mode;
8332 if (field_mode == VOIDmode)
8333 field_mode = word_mode;
8335 enum machine_mode pos_mode = data->operand[struct_op + 2].mode;
8336 if (pos_mode == VOIDmode)
8337 pos_mode = word_mode;
8339 insn->icode = icode;
8340 insn->field_mode = field_mode;
8341 insn->struct_mode = (type == ET_unaligned_mem ? byte_mode : struct_mode);
8342 insn->pos_mode = pos_mode;
8343 return true;
8346 /* Return true if an optab exists to perform an insertion or extraction
8347 of type TYPE in mode MODE. Describe the instruction in *INSN if so.
8349 REG_OPTAB is the optab to use for register structures and
8350 MISALIGN_OPTAB is the optab to use for misaligned memory structures.
8351 POS_OP is the operand number of the bit position. */
8353 static bool
8354 get_optab_extraction_insn (struct extraction_insn *insn,
8355 enum extraction_type type,
8356 enum machine_mode mode, direct_optab reg_optab,
8357 direct_optab misalign_optab, int pos_op)
8359 direct_optab optab = (type == ET_unaligned_mem ? misalign_optab : reg_optab);
8360 enum insn_code icode = direct_optab_handler (optab, mode);
8361 if (icode == CODE_FOR_nothing)
8362 return false;
8364 const struct insn_data_d *data = &insn_data[icode];
8366 insn->icode = icode;
8367 insn->field_mode = mode;
8368 insn->struct_mode = (type == ET_unaligned_mem ? BLKmode : mode);
8369 insn->pos_mode = data->operand[pos_op].mode;
8370 if (insn->pos_mode == VOIDmode)
8371 insn->pos_mode = word_mode;
8372 return true;
8375 /* Return true if an instruction exists to perform an insertion or
8376 extraction (PATTERN says which) of type TYPE in mode MODE.
8377 Describe the instruction in *INSN if so. */
8379 static bool
8380 get_extraction_insn (extraction_insn *insn,
8381 enum extraction_pattern pattern,
8382 enum extraction_type type,
8383 enum machine_mode mode)
8385 switch (pattern)
8387 case EP_insv:
8388 if (HAVE_insv
8389 && get_traditional_extraction_insn (insn, type, mode,
8390 CODE_FOR_insv, 0, 3))
8391 return true;
8392 return get_optab_extraction_insn (insn, type, mode, insv_optab,
8393 insvmisalign_optab, 2);
8395 case EP_extv:
8396 if (HAVE_extv
8397 && get_traditional_extraction_insn (insn, type, mode,
8398 CODE_FOR_extv, 1, 0))
8399 return true;
8400 return get_optab_extraction_insn (insn, type, mode, extv_optab,
8401 extvmisalign_optab, 3);
8403 case EP_extzv:
8404 if (HAVE_extzv
8405 && get_traditional_extraction_insn (insn, type, mode,
8406 CODE_FOR_extzv, 1, 0))
8407 return true;
8408 return get_optab_extraction_insn (insn, type, mode, extzv_optab,
8409 extzvmisalign_optab, 3);
8411 default:
8412 gcc_unreachable ();
8416 /* Return true if an instruction exists to access a field of mode
8417 FIELDMODE in a structure that has STRUCT_BITS significant bits.
8418 Describe the "best" such instruction in *INSN if so. PATTERN and
8419 TYPE describe the type of insertion or extraction we want to perform.
8421 For an insertion, the number of significant structure bits includes
8422 all bits of the target. For an extraction, it need only include the
8423 most significant bit of the field. Larger widths are acceptable
8424 in both cases. */
8426 static bool
8427 get_best_extraction_insn (extraction_insn *insn,
8428 enum extraction_pattern pattern,
8429 enum extraction_type type,
8430 unsigned HOST_WIDE_INT struct_bits,
8431 enum machine_mode field_mode)
8433 enum machine_mode mode = smallest_mode_for_size (struct_bits, MODE_INT);
8434 while (mode != VOIDmode)
8436 if (get_extraction_insn (insn, pattern, type, mode))
8438 while (mode != VOIDmode
8439 && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (field_mode)
8440 && !TRULY_NOOP_TRUNCATION_MODES_P (insn->field_mode,
8441 field_mode))
8443 get_extraction_insn (insn, pattern, type, mode);
8444 mode = GET_MODE_WIDER_MODE (mode);
8446 return true;
8448 mode = GET_MODE_WIDER_MODE (mode);
8450 return false;
8453 /* Return true if an instruction exists to access a field of mode
8454 FIELDMODE in a register structure that has STRUCT_BITS significant bits.
8455 Describe the "best" such instruction in *INSN if so. PATTERN describes
8456 the type of insertion or extraction we want to perform.
8458 For an insertion, the number of significant structure bits includes
8459 all bits of the target. For an extraction, it need only include the
8460 most significant bit of the field. Larger widths are acceptable
8461 in both cases. */
8463 bool
8464 get_best_reg_extraction_insn (extraction_insn *insn,
8465 enum extraction_pattern pattern,
8466 unsigned HOST_WIDE_INT struct_bits,
8467 enum machine_mode field_mode)
8469 return get_best_extraction_insn (insn, pattern, ET_reg, struct_bits,
8470 field_mode);
8473 /* Return true if an instruction exists to access a field of BITSIZE
8474 bits starting BITNUM bits into a memory structure. Describe the
8475 "best" such instruction in *INSN if so. PATTERN describes the type
8476 of insertion or extraction we want to perform and FIELDMODE is the
8477 natural mode of the extracted field.
8479 The instructions considered here only access bytes that overlap
8480 the bitfield; they do not touch any surrounding bytes. */
8482 bool
8483 get_best_mem_extraction_insn (extraction_insn *insn,
8484 enum extraction_pattern pattern,
8485 HOST_WIDE_INT bitsize, HOST_WIDE_INT bitnum,
8486 enum machine_mode field_mode)
8488 unsigned HOST_WIDE_INT struct_bits = (bitnum % BITS_PER_UNIT
8489 + bitsize
8490 + BITS_PER_UNIT - 1);
8491 struct_bits -= struct_bits % BITS_PER_UNIT;
8492 return get_best_extraction_insn (insn, pattern, ET_unaligned_mem,
8493 struct_bits, field_mode);
8496 #include "gt-optabs.h"