GCCPY:
[official-gcc.git] / gcc / optabs.c
blob8a3d3a921abb49ec9aa839006eb5c556f309f7ed
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 #if SWITCHABLE_TARGET
48 struct target_optabs *this_target_optabs = &default_target_optabs;
49 struct target_libfuncs *this_target_libfuncs = &default_target_libfuncs;
50 #endif
52 #define libfunc_hash \
53 (this_target_libfuncs->x_libfunc_hash)
55 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
56 enum machine_mode *);
57 static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
58 static void emit_libcall_block_1 (rtx, rtx, rtx, rtx, bool);
60 /* Debug facility for use in GDB. */
61 void debug_optab_libfuncs (void);
63 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
64 #if ENABLE_DECIMAL_BID_FORMAT
65 #define DECIMAL_PREFIX "bid_"
66 #else
67 #define DECIMAL_PREFIX "dpd_"
68 #endif
70 /* Used for libfunc_hash. */
72 static hashval_t
73 hash_libfunc (const void *p)
75 const struct libfunc_entry *const e = (const struct libfunc_entry *) p;
76 return ((e->mode1 + e->mode2 * NUM_MACHINE_MODES) ^ e->op);
79 /* Used for libfunc_hash. */
81 static int
82 eq_libfunc (const void *p, const void *q)
84 const struct libfunc_entry *const e1 = (const struct libfunc_entry *) p;
85 const struct libfunc_entry *const e2 = (const struct libfunc_entry *) q;
86 return e1->op == e2->op && e1->mode1 == e2->mode1 && e1->mode2 == e2->mode2;
89 /* Return libfunc corresponding operation defined by OPTAB converting
90 from MODE2 to MODE1. Trigger lazy initialization if needed, return NULL
91 if no libfunc is available. */
92 rtx
93 convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
94 enum machine_mode mode2)
96 struct libfunc_entry e;
97 struct libfunc_entry **slot;
99 /* ??? This ought to be an assert, but not all of the places
100 that we expand optabs know about the optabs that got moved
101 to being direct. */
102 if (!(optab >= FIRST_CONV_OPTAB && optab <= LAST_CONVLIB_OPTAB))
103 return NULL_RTX;
105 e.op = optab;
106 e.mode1 = mode1;
107 e.mode2 = mode2;
108 slot = (struct libfunc_entry **)
109 htab_find_slot (libfunc_hash, &e, NO_INSERT);
110 if (!slot)
112 const struct convert_optab_libcall_d *d
113 = &convlib_def[optab - FIRST_CONV_OPTAB];
115 if (d->libcall_gen == NULL)
116 return NULL;
118 d->libcall_gen (optab, d->libcall_basename, mode1, mode2);
119 slot = (struct libfunc_entry **)
120 htab_find_slot (libfunc_hash, &e, NO_INSERT);
121 if (!slot)
122 return NULL;
124 return (*slot)->libfunc;
127 /* Return libfunc corresponding operation defined by OPTAB in MODE.
128 Trigger lazy initialization if needed, return NULL if no libfunc is
129 available. */
131 optab_libfunc (optab optab, enum machine_mode mode)
133 struct libfunc_entry e;
134 struct libfunc_entry **slot;
136 /* ??? This ought to be an assert, but not all of the places
137 that we expand optabs know about the optabs that got moved
138 to being direct. */
139 if (!(optab >= FIRST_NORM_OPTAB && optab <= LAST_NORMLIB_OPTAB))
140 return NULL_RTX;
142 e.op = optab;
143 e.mode1 = mode;
144 e.mode2 = VOIDmode;
145 slot = (struct libfunc_entry **)
146 htab_find_slot (libfunc_hash, &e, NO_INSERT);
147 if (!slot)
149 const struct optab_libcall_d *d
150 = &normlib_def[optab - FIRST_NORM_OPTAB];
152 if (d->libcall_gen == NULL)
153 return NULL;
155 d->libcall_gen (optab, d->libcall_basename, d->libcall_suffix, mode);
156 slot = (struct libfunc_entry **)
157 htab_find_slot (libfunc_hash, &e, NO_INSERT);
158 if (!slot)
159 return NULL;
161 return (*slot)->libfunc;
165 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
166 the result of operation CODE applied to OP0 (and OP1 if it is a binary
167 operation).
169 If the last insn does not set TARGET, don't do anything, but return 1.
171 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
172 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
173 try again, ensuring that TARGET is not one of the operands. */
175 static int
176 add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
178 rtx last_insn, set;
179 rtx note;
181 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
183 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
184 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
185 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
186 && GET_RTX_CLASS (code) != RTX_COMPARE
187 && GET_RTX_CLASS (code) != RTX_UNARY)
188 return 1;
190 if (GET_CODE (target) == ZERO_EXTRACT)
191 return 1;
193 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
194 a value changing in the insn, so the note would be invalid for CSE. */
195 if (reg_overlap_mentioned_p (target, op0)
196 || (op1 && reg_overlap_mentioned_p (target, op1)))
197 return 0;
199 for (last_insn = insns;
200 NEXT_INSN (last_insn) != NULL_RTX;
201 last_insn = NEXT_INSN (last_insn))
204 set = single_set (last_insn);
205 if (set == NULL_RTX)
206 return 1;
208 if (! rtx_equal_p (SET_DEST (set), target)
209 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
210 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
211 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
212 return 1;
214 if (GET_RTX_CLASS (code) == RTX_UNARY)
215 switch (code)
217 case FFS:
218 case CLZ:
219 case CTZ:
220 case CLRSB:
221 case POPCOUNT:
222 case PARITY:
223 case BSWAP:
224 if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
226 note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
227 if (GET_MODE_SIZE (GET_MODE (op0))
228 > GET_MODE_SIZE (GET_MODE (target)))
229 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
230 note, GET_MODE (op0));
231 else
232 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
233 note, GET_MODE (op0));
234 break;
236 /* FALLTHRU */
237 default:
238 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
239 break;
241 else
242 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
244 set_unique_reg_note (last_insn, REG_EQUAL, note);
246 return 1;
249 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
250 for a widening operation would be. In most cases this would be OP0, but if
251 that's a constant it'll be VOIDmode, which isn't useful. */
253 static enum machine_mode
254 widened_mode (enum machine_mode to_mode, rtx op0, rtx op1)
256 enum machine_mode m0 = GET_MODE (op0);
257 enum machine_mode m1 = GET_MODE (op1);
258 enum machine_mode result;
260 if (m0 == VOIDmode && m1 == VOIDmode)
261 return to_mode;
262 else if (m0 == VOIDmode || GET_MODE_SIZE (m0) < GET_MODE_SIZE (m1))
263 result = m1;
264 else
265 result = m0;
267 if (GET_MODE_SIZE (result) > GET_MODE_SIZE (to_mode))
268 return to_mode;
270 return result;
273 /* Find a widening optab even if it doesn't widen as much as we want.
274 E.g. if from_mode is HImode, and to_mode is DImode, and there is no
275 direct HI->SI insn, then return SI->DI, if that exists.
276 If PERMIT_NON_WIDENING is non-zero then this can be used with
277 non-widening optabs also. */
279 enum insn_code
280 find_widening_optab_handler_and_mode (optab op, enum machine_mode to_mode,
281 enum machine_mode from_mode,
282 int permit_non_widening,
283 enum machine_mode *found_mode)
285 for (; (permit_non_widening || from_mode != to_mode)
286 && GET_MODE_SIZE (from_mode) <= GET_MODE_SIZE (to_mode)
287 && from_mode != VOIDmode;
288 from_mode = GET_MODE_WIDER_MODE (from_mode))
290 enum insn_code handler = widening_optab_handler (op, to_mode,
291 from_mode);
293 if (handler != CODE_FOR_nothing)
295 if (found_mode)
296 *found_mode = from_mode;
297 return handler;
301 return CODE_FOR_nothing;
304 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
305 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
306 not actually do a sign-extend or zero-extend, but can leave the
307 higher-order bits of the result rtx undefined, for example, in the case
308 of logical operations, but not right shifts. */
310 static rtx
311 widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
312 int unsignedp, int no_extend)
314 rtx result;
316 /* If we don't have to extend and this is a constant, return it. */
317 if (no_extend && GET_MODE (op) == VOIDmode)
318 return op;
320 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
321 extend since it will be more efficient to do so unless the signedness of
322 a promoted object differs from our extension. */
323 if (! no_extend
324 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
325 && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
326 return convert_modes (mode, oldmode, op, unsignedp);
328 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
329 SUBREG. */
330 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
331 return gen_lowpart (mode, force_reg (GET_MODE (op), op));
333 /* Otherwise, get an object of MODE, clobber it, and set the low-order
334 part to OP. */
336 result = gen_reg_rtx (mode);
337 emit_clobber (result);
338 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
339 return result;
342 /* Return the optab used for computing the operation given by the tree code,
343 CODE and the tree EXP. This function is not always usable (for example, it
344 cannot give complete results for multiplication or division) but probably
345 ought to be relied on more widely throughout the expander. */
346 optab
347 optab_for_tree_code (enum tree_code code, const_tree type,
348 enum optab_subtype subtype)
350 bool trapv;
351 switch (code)
353 case BIT_AND_EXPR:
354 return and_optab;
356 case BIT_IOR_EXPR:
357 return ior_optab;
359 case BIT_NOT_EXPR:
360 return one_cmpl_optab;
362 case BIT_XOR_EXPR:
363 return xor_optab;
365 case MULT_HIGHPART_EXPR:
366 return TYPE_UNSIGNED (type) ? umul_highpart_optab : smul_highpart_optab;
368 case TRUNC_MOD_EXPR:
369 case CEIL_MOD_EXPR:
370 case FLOOR_MOD_EXPR:
371 case ROUND_MOD_EXPR:
372 return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
374 case RDIV_EXPR:
375 case TRUNC_DIV_EXPR:
376 case CEIL_DIV_EXPR:
377 case FLOOR_DIV_EXPR:
378 case ROUND_DIV_EXPR:
379 case EXACT_DIV_EXPR:
380 if (TYPE_SATURATING(type))
381 return TYPE_UNSIGNED(type) ? usdiv_optab : ssdiv_optab;
382 return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
384 case LSHIFT_EXPR:
385 if (TREE_CODE (type) == VECTOR_TYPE)
387 if (subtype == optab_vector)
388 return TYPE_SATURATING (type) ? unknown_optab : vashl_optab;
390 gcc_assert (subtype == optab_scalar);
392 if (TYPE_SATURATING(type))
393 return TYPE_UNSIGNED(type) ? usashl_optab : ssashl_optab;
394 return ashl_optab;
396 case RSHIFT_EXPR:
397 if (TREE_CODE (type) == VECTOR_TYPE)
399 if (subtype == optab_vector)
400 return TYPE_UNSIGNED (type) ? vlshr_optab : vashr_optab;
402 gcc_assert (subtype == optab_scalar);
404 return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
406 case LROTATE_EXPR:
407 if (TREE_CODE (type) == VECTOR_TYPE)
409 if (subtype == optab_vector)
410 return vrotl_optab;
412 gcc_assert (subtype == optab_scalar);
414 return rotl_optab;
416 case RROTATE_EXPR:
417 if (TREE_CODE (type) == VECTOR_TYPE)
419 if (subtype == optab_vector)
420 return vrotr_optab;
422 gcc_assert (subtype == optab_scalar);
424 return rotr_optab;
426 case MAX_EXPR:
427 return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
429 case MIN_EXPR:
430 return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
432 case REALIGN_LOAD_EXPR:
433 return vec_realign_load_optab;
435 case WIDEN_SUM_EXPR:
436 return TYPE_UNSIGNED (type) ? usum_widen_optab : ssum_widen_optab;
438 case DOT_PROD_EXPR:
439 return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
441 case WIDEN_MULT_PLUS_EXPR:
442 return (TYPE_UNSIGNED (type)
443 ? (TYPE_SATURATING (type)
444 ? usmadd_widen_optab : umadd_widen_optab)
445 : (TYPE_SATURATING (type)
446 ? ssmadd_widen_optab : smadd_widen_optab));
448 case WIDEN_MULT_MINUS_EXPR:
449 return (TYPE_UNSIGNED (type)
450 ? (TYPE_SATURATING (type)
451 ? usmsub_widen_optab : umsub_widen_optab)
452 : (TYPE_SATURATING (type)
453 ? ssmsub_widen_optab : smsub_widen_optab));
455 case FMA_EXPR:
456 return fma_optab;
458 case REDUC_MAX_EXPR:
459 return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab;
461 case REDUC_MIN_EXPR:
462 return TYPE_UNSIGNED (type) ? reduc_umin_optab : reduc_smin_optab;
464 case REDUC_PLUS_EXPR:
465 return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
467 case VEC_LSHIFT_EXPR:
468 return vec_shl_optab;
470 case VEC_RSHIFT_EXPR:
471 return vec_shr_optab;
473 case VEC_WIDEN_MULT_HI_EXPR:
474 return TYPE_UNSIGNED (type) ?
475 vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
477 case VEC_WIDEN_MULT_LO_EXPR:
478 return TYPE_UNSIGNED (type) ?
479 vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
481 case VEC_WIDEN_MULT_EVEN_EXPR:
482 return TYPE_UNSIGNED (type) ?
483 vec_widen_umult_even_optab : vec_widen_smult_even_optab;
485 case VEC_WIDEN_MULT_ODD_EXPR:
486 return TYPE_UNSIGNED (type) ?
487 vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
489 case VEC_WIDEN_LSHIFT_HI_EXPR:
490 return TYPE_UNSIGNED (type) ?
491 vec_widen_ushiftl_hi_optab : vec_widen_sshiftl_hi_optab;
493 case VEC_WIDEN_LSHIFT_LO_EXPR:
494 return TYPE_UNSIGNED (type) ?
495 vec_widen_ushiftl_lo_optab : vec_widen_sshiftl_lo_optab;
497 case VEC_UNPACK_HI_EXPR:
498 return TYPE_UNSIGNED (type) ?
499 vec_unpacku_hi_optab : vec_unpacks_hi_optab;
501 case VEC_UNPACK_LO_EXPR:
502 return TYPE_UNSIGNED (type) ?
503 vec_unpacku_lo_optab : vec_unpacks_lo_optab;
505 case VEC_UNPACK_FLOAT_HI_EXPR:
506 /* The signedness is determined from input operand. */
507 return TYPE_UNSIGNED (type) ?
508 vec_unpacku_float_hi_optab : vec_unpacks_float_hi_optab;
510 case VEC_UNPACK_FLOAT_LO_EXPR:
511 /* The signedness is determined from input operand. */
512 return TYPE_UNSIGNED (type) ?
513 vec_unpacku_float_lo_optab : vec_unpacks_float_lo_optab;
515 case VEC_PACK_TRUNC_EXPR:
516 return vec_pack_trunc_optab;
518 case VEC_PACK_SAT_EXPR:
519 return TYPE_UNSIGNED (type) ? vec_pack_usat_optab : vec_pack_ssat_optab;
521 case VEC_PACK_FIX_TRUNC_EXPR:
522 /* The signedness is determined from output operand. */
523 return TYPE_UNSIGNED (type) ?
524 vec_pack_ufix_trunc_optab : vec_pack_sfix_trunc_optab;
526 default:
527 break;
530 trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
531 switch (code)
533 case POINTER_PLUS_EXPR:
534 case PLUS_EXPR:
535 if (TYPE_SATURATING(type))
536 return TYPE_UNSIGNED(type) ? usadd_optab : ssadd_optab;
537 return trapv ? addv_optab : add_optab;
539 case MINUS_EXPR:
540 if (TYPE_SATURATING(type))
541 return TYPE_UNSIGNED(type) ? ussub_optab : sssub_optab;
542 return trapv ? subv_optab : sub_optab;
544 case MULT_EXPR:
545 if (TYPE_SATURATING(type))
546 return TYPE_UNSIGNED(type) ? usmul_optab : ssmul_optab;
547 return trapv ? smulv_optab : smul_optab;
549 case NEGATE_EXPR:
550 if (TYPE_SATURATING(type))
551 return TYPE_UNSIGNED(type) ? usneg_optab : ssneg_optab;
552 return trapv ? negv_optab : neg_optab;
554 case ABS_EXPR:
555 return trapv ? absv_optab : abs_optab;
557 default:
558 return unknown_optab;
563 /* Expand vector widening operations.
565 There are two different classes of operations handled here:
566 1) Operations whose result is wider than all the arguments to the operation.
567 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
568 In this case OP0 and optionally OP1 would be initialized,
569 but WIDE_OP wouldn't (not relevant for this case).
570 2) Operations whose result is of the same size as the last argument to the
571 operation, but wider than all the other arguments to the operation.
572 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
573 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
575 E.g, when called to expand the following operations, this is how
576 the arguments will be initialized:
577 nops OP0 OP1 WIDE_OP
578 widening-sum 2 oprnd0 - oprnd1
579 widening-dot-product 3 oprnd0 oprnd1 oprnd2
580 widening-mult 2 oprnd0 oprnd1 -
581 type-promotion (vec-unpack) 1 oprnd0 - - */
584 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
585 rtx target, int unsignedp)
587 struct expand_operand eops[4];
588 tree oprnd0, oprnd1, oprnd2;
589 enum machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
590 optab widen_pattern_optab;
591 enum insn_code icode;
592 int nops = TREE_CODE_LENGTH (ops->code);
593 int op;
595 oprnd0 = ops->op0;
596 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
597 widen_pattern_optab =
598 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
599 if (ops->code == WIDEN_MULT_PLUS_EXPR
600 || ops->code == WIDEN_MULT_MINUS_EXPR)
601 icode = find_widening_optab_handler (widen_pattern_optab,
602 TYPE_MODE (TREE_TYPE (ops->op2)),
603 tmode0, 0);
604 else
605 icode = optab_handler (widen_pattern_optab, tmode0);
606 gcc_assert (icode != CODE_FOR_nothing);
608 if (nops >= 2)
610 oprnd1 = ops->op1;
611 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
614 /* The last operand is of a wider mode than the rest of the operands. */
615 if (nops == 2)
616 wmode = tmode1;
617 else if (nops == 3)
619 gcc_assert (tmode1 == tmode0);
620 gcc_assert (op1);
621 oprnd2 = ops->op2;
622 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
625 op = 0;
626 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
627 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
628 if (op1)
629 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
630 if (wide_op)
631 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
632 expand_insn (icode, op, eops);
633 return eops[0].value;
636 /* Generate code to perform an operation specified by TERNARY_OPTAB
637 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
639 UNSIGNEDP is for the case where we have to widen the operands
640 to perform the operation. It says to use zero-extension.
642 If TARGET is nonzero, the value
643 is generated there, if it is convenient to do so.
644 In all cases an rtx is returned for the locus of the value;
645 this may or may not be TARGET. */
648 expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
649 rtx op1, rtx op2, rtx target, int unsignedp)
651 struct expand_operand ops[4];
652 enum insn_code icode = optab_handler (ternary_optab, mode);
654 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
656 create_output_operand (&ops[0], target, mode);
657 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
658 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
659 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
660 expand_insn (icode, 4, ops);
661 return ops[0].value;
665 /* Like expand_binop, but return a constant rtx if the result can be
666 calculated at compile time. The arguments and return value are
667 otherwise the same as for expand_binop. */
670 simplify_expand_binop (enum machine_mode mode, optab binoptab,
671 rtx op0, rtx op1, rtx target, int unsignedp,
672 enum optab_methods methods)
674 if (CONSTANT_P (op0) && CONSTANT_P (op1))
676 rtx x = simplify_binary_operation (optab_to_code (binoptab),
677 mode, op0, op1);
678 if (x)
679 return x;
682 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
685 /* Like simplify_expand_binop, but always put the result in TARGET.
686 Return true if the expansion succeeded. */
688 bool
689 force_expand_binop (enum machine_mode mode, optab binoptab,
690 rtx op0, rtx op1, rtx target, int unsignedp,
691 enum optab_methods methods)
693 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
694 target, unsignedp, methods);
695 if (x == 0)
696 return false;
697 if (x != target)
698 emit_move_insn (target, x);
699 return true;
702 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */
705 expand_vec_shift_expr (sepops ops, rtx target)
707 struct expand_operand eops[3];
708 enum insn_code icode;
709 rtx rtx_op1, rtx_op2;
710 enum machine_mode mode = TYPE_MODE (ops->type);
711 tree vec_oprnd = ops->op0;
712 tree shift_oprnd = ops->op1;
713 optab shift_optab;
715 switch (ops->code)
717 case VEC_RSHIFT_EXPR:
718 shift_optab = vec_shr_optab;
719 break;
720 case VEC_LSHIFT_EXPR:
721 shift_optab = vec_shl_optab;
722 break;
723 default:
724 gcc_unreachable ();
727 icode = optab_handler (shift_optab, mode);
728 gcc_assert (icode != CODE_FOR_nothing);
730 rtx_op1 = expand_normal (vec_oprnd);
731 rtx_op2 = expand_normal (shift_oprnd);
733 create_output_operand (&eops[0], target, mode);
734 create_input_operand (&eops[1], rtx_op1, GET_MODE (rtx_op1));
735 create_convert_operand_from_type (&eops[2], rtx_op2, TREE_TYPE (shift_oprnd));
736 expand_insn (icode, 3, eops);
738 return eops[0].value;
741 /* Create a new vector value in VMODE with all elements set to OP. The
742 mode of OP must be the element mode of VMODE. If OP is a constant,
743 then the return value will be a constant. */
745 static rtx
746 expand_vector_broadcast (enum machine_mode vmode, rtx op)
748 enum insn_code icode;
749 rtvec vec;
750 rtx ret;
751 int i, n;
753 gcc_checking_assert (VECTOR_MODE_P (vmode));
755 n = GET_MODE_NUNITS (vmode);
756 vec = rtvec_alloc (n);
757 for (i = 0; i < n; ++i)
758 RTVEC_ELT (vec, i) = op;
760 if (CONSTANT_P (op))
761 return gen_rtx_CONST_VECTOR (vmode, vec);
763 /* ??? If the target doesn't have a vec_init, then we have no easy way
764 of performing this operation. Most of this sort of generic support
765 is hidden away in the vector lowering support in gimple. */
766 icode = optab_handler (vec_init_optab, vmode);
767 if (icode == CODE_FOR_nothing)
768 return NULL;
770 ret = gen_reg_rtx (vmode);
771 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
773 return ret;
776 /* This subroutine of expand_doubleword_shift handles the cases in which
777 the effective shift value is >= BITS_PER_WORD. The arguments and return
778 value are the same as for the parent routine, except that SUPERWORD_OP1
779 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
780 INTO_TARGET may be null if the caller has decided to calculate it. */
782 static bool
783 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
784 rtx outof_target, rtx into_target,
785 int unsignedp, enum optab_methods methods)
787 if (into_target != 0)
788 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
789 into_target, unsignedp, methods))
790 return false;
792 if (outof_target != 0)
794 /* For a signed right shift, we must fill OUTOF_TARGET with copies
795 of the sign bit, otherwise we must fill it with zeros. */
796 if (binoptab != ashr_optab)
797 emit_move_insn (outof_target, CONST0_RTX (word_mode));
798 else
799 if (!force_expand_binop (word_mode, binoptab,
800 outof_input, GEN_INT (BITS_PER_WORD - 1),
801 outof_target, unsignedp, methods))
802 return false;
804 return true;
807 /* This subroutine of expand_doubleword_shift handles the cases in which
808 the effective shift value is < BITS_PER_WORD. The arguments and return
809 value are the same as for the parent routine. */
811 static bool
812 expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
813 rtx outof_input, rtx into_input, rtx op1,
814 rtx outof_target, rtx into_target,
815 int unsignedp, enum optab_methods methods,
816 unsigned HOST_WIDE_INT shift_mask)
818 optab reverse_unsigned_shift, unsigned_shift;
819 rtx tmp, carries;
821 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
822 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
824 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
825 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
826 the opposite direction to BINOPTAB. */
827 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
829 carries = outof_input;
830 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
831 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
832 0, true, methods);
834 else
836 /* We must avoid shifting by BITS_PER_WORD bits since that is either
837 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
838 has unknown behavior. Do a single shift first, then shift by the
839 remainder. It's OK to use ~OP1 as the remainder if shift counts
840 are truncated to the mode size. */
841 carries = expand_binop (word_mode, reverse_unsigned_shift,
842 outof_input, const1_rtx, 0, unsignedp, methods);
843 if (shift_mask == BITS_PER_WORD - 1)
845 tmp = immed_double_const (-1, -1, op1_mode);
846 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
847 0, true, methods);
849 else
851 tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
852 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
853 0, true, methods);
856 if (tmp == 0 || carries == 0)
857 return false;
858 carries = expand_binop (word_mode, reverse_unsigned_shift,
859 carries, tmp, 0, unsignedp, methods);
860 if (carries == 0)
861 return false;
863 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
864 so the result can go directly into INTO_TARGET if convenient. */
865 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
866 into_target, unsignedp, methods);
867 if (tmp == 0)
868 return false;
870 /* Now OR in the bits carried over from OUTOF_INPUT. */
871 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
872 into_target, unsignedp, methods))
873 return false;
875 /* Use a standard word_mode shift for the out-of half. */
876 if (outof_target != 0)
877 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
878 outof_target, unsignedp, methods))
879 return false;
881 return true;
885 #ifdef HAVE_conditional_move
886 /* Try implementing expand_doubleword_shift using conditional moves.
887 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
888 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
889 are the shift counts to use in the former and latter case. All other
890 arguments are the same as the parent routine. */
892 static bool
893 expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
894 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
895 rtx outof_input, rtx into_input,
896 rtx subword_op1, rtx superword_op1,
897 rtx outof_target, rtx into_target,
898 int unsignedp, enum optab_methods methods,
899 unsigned HOST_WIDE_INT shift_mask)
901 rtx outof_superword, into_superword;
903 /* Put the superword version of the output into OUTOF_SUPERWORD and
904 INTO_SUPERWORD. */
905 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
906 if (outof_target != 0 && subword_op1 == superword_op1)
908 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
909 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
910 into_superword = outof_target;
911 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
912 outof_superword, 0, unsignedp, methods))
913 return false;
915 else
917 into_superword = gen_reg_rtx (word_mode);
918 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
919 outof_superword, into_superword,
920 unsignedp, methods))
921 return false;
924 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
925 if (!expand_subword_shift (op1_mode, binoptab,
926 outof_input, into_input, subword_op1,
927 outof_target, into_target,
928 unsignedp, methods, shift_mask))
929 return false;
931 /* Select between them. Do the INTO half first because INTO_SUPERWORD
932 might be the current value of OUTOF_TARGET. */
933 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
934 into_target, into_superword, word_mode, false))
935 return false;
937 if (outof_target != 0)
938 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
939 outof_target, outof_superword,
940 word_mode, false))
941 return false;
943 return true;
945 #endif
947 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
948 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
949 input operand; the shift moves bits in the direction OUTOF_INPUT->
950 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
951 of the target. OP1 is the shift count and OP1_MODE is its mode.
952 If OP1 is constant, it will have been truncated as appropriate
953 and is known to be nonzero.
955 If SHIFT_MASK is zero, the result of word shifts is undefined when the
956 shift count is outside the range [0, BITS_PER_WORD). This routine must
957 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
959 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
960 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
961 fill with zeros or sign bits as appropriate.
963 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
964 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
965 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
966 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
967 are undefined.
969 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
970 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
971 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
972 function wants to calculate it itself.
974 Return true if the shift could be successfully synthesized. */
976 static bool
977 expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
978 rtx outof_input, rtx into_input, rtx op1,
979 rtx outof_target, rtx into_target,
980 int unsignedp, enum optab_methods methods,
981 unsigned HOST_WIDE_INT shift_mask)
983 rtx superword_op1, tmp, cmp1, cmp2;
984 rtx subword_label, done_label;
985 enum rtx_code cmp_code;
987 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
988 fill the result with sign or zero bits as appropriate. If so, the value
989 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
990 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
991 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
993 This isn't worthwhile for constant shifts since the optimizers will
994 cope better with in-range shift counts. */
995 if (shift_mask >= BITS_PER_WORD
996 && outof_target != 0
997 && !CONSTANT_P (op1))
999 if (!expand_doubleword_shift (op1_mode, binoptab,
1000 outof_input, into_input, op1,
1001 0, into_target,
1002 unsignedp, methods, shift_mask))
1003 return false;
1004 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
1005 outof_target, unsignedp, methods))
1006 return false;
1007 return true;
1010 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
1011 is true when the effective shift value is less than BITS_PER_WORD.
1012 Set SUPERWORD_OP1 to the shift count that should be used to shift
1013 OUTOF_INPUT into INTO_TARGET when the condition is false. */
1014 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
1015 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
1017 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
1018 is a subword shift count. */
1019 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
1020 0, true, methods);
1021 cmp2 = CONST0_RTX (op1_mode);
1022 cmp_code = EQ;
1023 superword_op1 = op1;
1025 else
1027 /* Set CMP1 to OP1 - BITS_PER_WORD. */
1028 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
1029 0, true, methods);
1030 cmp2 = CONST0_RTX (op1_mode);
1031 cmp_code = LT;
1032 superword_op1 = cmp1;
1034 if (cmp1 == 0)
1035 return false;
1037 /* If we can compute the condition at compile time, pick the
1038 appropriate subroutine. */
1039 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
1040 if (tmp != 0 && CONST_INT_P (tmp))
1042 if (tmp == const0_rtx)
1043 return expand_superword_shift (binoptab, outof_input, superword_op1,
1044 outof_target, into_target,
1045 unsignedp, methods);
1046 else
1047 return expand_subword_shift (op1_mode, binoptab,
1048 outof_input, into_input, op1,
1049 outof_target, into_target,
1050 unsignedp, methods, shift_mask);
1053 #ifdef HAVE_conditional_move
1054 /* Try using conditional moves to generate straight-line code. */
1056 rtx start = get_last_insn ();
1057 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
1058 cmp_code, cmp1, cmp2,
1059 outof_input, into_input,
1060 op1, superword_op1,
1061 outof_target, into_target,
1062 unsignedp, methods, shift_mask))
1063 return true;
1064 delete_insns_since (start);
1066 #endif
1068 /* As a last resort, use branches to select the correct alternative. */
1069 subword_label = gen_label_rtx ();
1070 done_label = gen_label_rtx ();
1072 NO_DEFER_POP;
1073 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
1074 0, 0, subword_label, -1);
1075 OK_DEFER_POP;
1077 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
1078 outof_target, into_target,
1079 unsignedp, methods))
1080 return false;
1082 emit_jump_insn (gen_jump (done_label));
1083 emit_barrier ();
1084 emit_label (subword_label);
1086 if (!expand_subword_shift (op1_mode, binoptab,
1087 outof_input, into_input, op1,
1088 outof_target, into_target,
1089 unsignedp, methods, shift_mask))
1090 return false;
1092 emit_label (done_label);
1093 return true;
1096 /* Subroutine of expand_binop. Perform a double word multiplication of
1097 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1098 as the target's word_mode. This function return NULL_RTX if anything
1099 goes wrong, in which case it may have already emitted instructions
1100 which need to be deleted.
1102 If we want to multiply two two-word values and have normal and widening
1103 multiplies of single-word values, we can do this with three smaller
1104 multiplications.
1106 The multiplication proceeds as follows:
1107 _______________________
1108 [__op0_high_|__op0_low__]
1109 _______________________
1110 * [__op1_high_|__op1_low__]
1111 _______________________________________________
1112 _______________________
1113 (1) [__op0_low__*__op1_low__]
1114 _______________________
1115 (2a) [__op0_low__*__op1_high_]
1116 _______________________
1117 (2b) [__op0_high_*__op1_low__]
1118 _______________________
1119 (3) [__op0_high_*__op1_high_]
1122 This gives a 4-word result. Since we are only interested in the
1123 lower 2 words, partial result (3) and the upper words of (2a) and
1124 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1125 calculated using non-widening multiplication.
1127 (1), however, needs to be calculated with an unsigned widening
1128 multiplication. If this operation is not directly supported we
1129 try using a signed widening multiplication and adjust the result.
1130 This adjustment works as follows:
1132 If both operands are positive then no adjustment is needed.
1134 If the operands have different signs, for example op0_low < 0 and
1135 op1_low >= 0, the instruction treats the most significant bit of
1136 op0_low as a sign bit instead of a bit with significance
1137 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1138 with 2**BITS_PER_WORD - op0_low, and two's complements the
1139 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1140 the result.
1142 Similarly, if both operands are negative, we need to add
1143 (op0_low + op1_low) * 2**BITS_PER_WORD.
1145 We use a trick to adjust quickly. We logically shift op0_low right
1146 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1147 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1148 logical shift exists, we do an arithmetic right shift and subtract
1149 the 0 or -1. */
1151 static rtx
1152 expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
1153 bool umulp, enum optab_methods methods)
1155 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1156 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1157 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
1158 rtx product, adjust, product_high, temp;
1160 rtx op0_high = operand_subword_force (op0, high, mode);
1161 rtx op0_low = operand_subword_force (op0, low, mode);
1162 rtx op1_high = operand_subword_force (op1, high, mode);
1163 rtx op1_low = operand_subword_force (op1, low, mode);
1165 /* If we're using an unsigned multiply to directly compute the product
1166 of the low-order words of the operands and perform any required
1167 adjustments of the operands, we begin by trying two more multiplications
1168 and then computing the appropriate sum.
1170 We have checked above that the required addition is provided.
1171 Full-word addition will normally always succeed, especially if
1172 it is provided at all, so we don't worry about its failure. The
1173 multiplication may well fail, however, so we do handle that. */
1175 if (!umulp)
1177 /* ??? This could be done with emit_store_flag where available. */
1178 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1179 NULL_RTX, 1, methods);
1180 if (temp)
1181 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
1182 NULL_RTX, 0, OPTAB_DIRECT);
1183 else
1185 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1186 NULL_RTX, 0, methods);
1187 if (!temp)
1188 return NULL_RTX;
1189 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
1190 NULL_RTX, 0, OPTAB_DIRECT);
1193 if (!op0_high)
1194 return NULL_RTX;
1197 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
1198 NULL_RTX, 0, OPTAB_DIRECT);
1199 if (!adjust)
1200 return NULL_RTX;
1202 /* OP0_HIGH should now be dead. */
1204 if (!umulp)
1206 /* ??? This could be done with emit_store_flag where available. */
1207 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1208 NULL_RTX, 1, methods);
1209 if (temp)
1210 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
1211 NULL_RTX, 0, OPTAB_DIRECT);
1212 else
1214 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1215 NULL_RTX, 0, methods);
1216 if (!temp)
1217 return NULL_RTX;
1218 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
1219 NULL_RTX, 0, OPTAB_DIRECT);
1222 if (!op1_high)
1223 return NULL_RTX;
1226 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
1227 NULL_RTX, 0, OPTAB_DIRECT);
1228 if (!temp)
1229 return NULL_RTX;
1231 /* OP1_HIGH should now be dead. */
1233 adjust = expand_binop (word_mode, add_optab, adjust, temp,
1234 NULL_RTX, 0, OPTAB_DIRECT);
1236 if (target && !REG_P (target))
1237 target = NULL_RTX;
1239 if (umulp)
1240 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1241 target, 1, OPTAB_DIRECT);
1242 else
1243 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1244 target, 1, OPTAB_DIRECT);
1246 if (!product)
1247 return NULL_RTX;
1249 product_high = operand_subword (product, high, 1, mode);
1250 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
1251 NULL_RTX, 0, OPTAB_DIRECT);
1252 emit_move_insn (product_high, adjust);
1253 return product;
1256 /* Wrapper around expand_binop which takes an rtx code to specify
1257 the operation to perform, not an optab pointer. All other
1258 arguments are the same. */
1260 expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
1261 rtx op1, rtx target, int unsignedp,
1262 enum optab_methods methods)
1264 optab binop = code_to_optab (code);
1265 gcc_assert (binop);
1267 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1270 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1271 binop. Order them according to commutative_operand_precedence and, if
1272 possible, try to put TARGET or a pseudo first. */
1273 static bool
1274 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1276 int op0_prec = commutative_operand_precedence (op0);
1277 int op1_prec = commutative_operand_precedence (op1);
1279 if (op0_prec < op1_prec)
1280 return true;
1282 if (op0_prec > op1_prec)
1283 return false;
1285 /* With equal precedence, both orders are ok, but it is better if the
1286 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1287 if (target == 0 || REG_P (target))
1288 return (REG_P (op1) && !REG_P (op0)) || target == op1;
1289 else
1290 return rtx_equal_p (op1, target);
1293 /* Return true if BINOPTAB implements a shift operation. */
1295 static bool
1296 shift_optab_p (optab binoptab)
1298 switch (optab_to_code (binoptab))
1300 case ASHIFT:
1301 case SS_ASHIFT:
1302 case US_ASHIFT:
1303 case ASHIFTRT:
1304 case LSHIFTRT:
1305 case ROTATE:
1306 case ROTATERT:
1307 return true;
1309 default:
1310 return false;
1314 /* Return true if BINOPTAB implements a commutative binary operation. */
1316 static bool
1317 commutative_optab_p (optab binoptab)
1319 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
1320 || binoptab == smul_widen_optab
1321 || binoptab == umul_widen_optab
1322 || binoptab == smul_highpart_optab
1323 || binoptab == umul_highpart_optab);
1326 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
1327 optimizing, and if the operand is a constant that costs more than
1328 1 instruction, force the constant into a register and return that
1329 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1331 static rtx
1332 avoid_expensive_constant (enum machine_mode mode, optab binoptab,
1333 int opn, rtx x, bool unsignedp)
1335 bool speed = optimize_insn_for_speed_p ();
1337 if (mode != VOIDmode
1338 && optimize
1339 && CONSTANT_P (x)
1340 && (rtx_cost (x, optab_to_code (binoptab), opn, speed)
1341 > set_src_cost (x, speed)))
1343 if (CONST_INT_P (x))
1345 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
1346 if (intval != INTVAL (x))
1347 x = GEN_INT (intval);
1349 else
1350 x = convert_modes (mode, VOIDmode, x, unsignedp);
1351 x = force_reg (mode, x);
1353 return x;
1356 /* Helper function for expand_binop: handle the case where there
1357 is an insn that directly implements the indicated operation.
1358 Returns null if this is not possible. */
1359 static rtx
1360 expand_binop_directly (enum machine_mode mode, optab binoptab,
1361 rtx op0, rtx op1,
1362 rtx target, int unsignedp, enum optab_methods methods,
1363 rtx last)
1365 enum machine_mode from_mode = widened_mode (mode, op0, op1);
1366 enum insn_code icode = find_widening_optab_handler (binoptab, mode,
1367 from_mode, 1);
1368 enum machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
1369 enum machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
1370 enum machine_mode mode0, mode1, tmp_mode;
1371 struct expand_operand ops[3];
1372 bool commutative_p;
1373 rtx pat;
1374 rtx xop0 = op0, xop1 = op1;
1375 rtx swap;
1377 /* If it is a commutative operator and the modes would match
1378 if we would swap the operands, we can save the conversions. */
1379 commutative_p = commutative_optab_p (binoptab);
1380 if (commutative_p
1381 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1382 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode1)
1384 swap = xop0;
1385 xop0 = xop1;
1386 xop1 = swap;
1389 /* If we are optimizing, force expensive constants into a register. */
1390 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1391 if (!shift_optab_p (binoptab))
1392 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1394 /* In case the insn wants input operands in modes different from
1395 those of the actual operands, convert the operands. It would
1396 seem that we don't need to convert CONST_INTs, but we do, so
1397 that they're properly zero-extended, sign-extended or truncated
1398 for their mode. */
1400 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1401 if (xmode0 != VOIDmode && xmode0 != mode0)
1403 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1404 mode0 = xmode0;
1407 mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
1408 if (xmode1 != VOIDmode && xmode1 != mode1)
1410 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1411 mode1 = xmode1;
1414 /* If operation is commutative,
1415 try to make the first operand a register.
1416 Even better, try to make it the same as the target.
1417 Also try to make the last operand a constant. */
1418 if (commutative_p
1419 && swap_commutative_operands_with_target (target, xop0, xop1))
1421 swap = xop1;
1422 xop1 = xop0;
1423 xop0 = swap;
1426 /* Now, if insn's predicates don't allow our operands, put them into
1427 pseudo regs. */
1429 if (binoptab == vec_pack_trunc_optab
1430 || binoptab == vec_pack_usat_optab
1431 || binoptab == vec_pack_ssat_optab
1432 || binoptab == vec_pack_ufix_trunc_optab
1433 || binoptab == vec_pack_sfix_trunc_optab)
1435 /* The mode of the result is different then the mode of the
1436 arguments. */
1437 tmp_mode = insn_data[(int) icode].operand[0].mode;
1438 if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1440 delete_insns_since (last);
1441 return NULL_RTX;
1444 else
1445 tmp_mode = mode;
1447 create_output_operand (&ops[0], target, tmp_mode);
1448 create_input_operand (&ops[1], xop0, mode0);
1449 create_input_operand (&ops[2], xop1, mode1);
1450 pat = maybe_gen_insn (icode, 3, ops);
1451 if (pat)
1453 /* If PAT is composed of more than one insn, try to add an appropriate
1454 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1455 operand, call expand_binop again, this time without a target. */
1456 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1457 && ! add_equal_note (pat, ops[0].value, optab_to_code (binoptab),
1458 ops[1].value, ops[2].value))
1460 delete_insns_since (last);
1461 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1462 unsignedp, methods);
1465 emit_insn (pat);
1466 return ops[0].value;
1468 delete_insns_since (last);
1469 return NULL_RTX;
1472 /* Generate code to perform an operation specified by BINOPTAB
1473 on operands OP0 and OP1, with result having machine-mode MODE.
1475 UNSIGNEDP is for the case where we have to widen the operands
1476 to perform the operation. It says to use zero-extension.
1478 If TARGET is nonzero, the value
1479 is generated there, if it is convenient to do so.
1480 In all cases an rtx is returned for the locus of the value;
1481 this may or may not be TARGET. */
1484 expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
1485 rtx target, int unsignedp, enum optab_methods methods)
1487 enum optab_methods next_methods
1488 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1489 ? OPTAB_WIDEN : methods);
1490 enum mode_class mclass;
1491 enum machine_mode wider_mode;
1492 rtx libfunc;
1493 rtx temp;
1494 rtx entry_last = get_last_insn ();
1495 rtx last;
1497 mclass = GET_MODE_CLASS (mode);
1499 /* If subtracting an integer constant, convert this into an addition of
1500 the negated constant. */
1502 if (binoptab == sub_optab && CONST_INT_P (op1))
1504 op1 = negate_rtx (mode, op1);
1505 binoptab = add_optab;
1508 /* Record where to delete back to if we backtrack. */
1509 last = get_last_insn ();
1511 /* If we can do it with a three-operand insn, do so. */
1513 if (methods != OPTAB_MUST_WIDEN
1514 && find_widening_optab_handler (binoptab, mode,
1515 widened_mode (mode, op0, op1), 1)
1516 != CODE_FOR_nothing)
1518 temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1519 unsignedp, methods, last);
1520 if (temp)
1521 return temp;
1524 /* If we were trying to rotate, and that didn't work, try rotating
1525 the other direction before falling back to shifts and bitwise-or. */
1526 if (((binoptab == rotl_optab
1527 && optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
1528 || (binoptab == rotr_optab
1529 && optab_handler (rotl_optab, mode) != CODE_FOR_nothing))
1530 && mclass == MODE_INT)
1532 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1533 rtx newop1;
1534 unsigned int bits = GET_MODE_PRECISION (mode);
1536 if (CONST_INT_P (op1))
1537 newop1 = GEN_INT (bits - INTVAL (op1));
1538 else if (targetm.shift_truncation_mask (mode) == bits - 1)
1539 newop1 = negate_rtx (GET_MODE (op1), op1);
1540 else
1541 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1542 GEN_INT (bits), op1,
1543 NULL_RTX, unsignedp, OPTAB_DIRECT);
1545 temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1546 target, unsignedp, methods, last);
1547 if (temp)
1548 return temp;
1551 /* If this is a multiply, see if we can do a widening operation that
1552 takes operands of this mode and makes a wider mode. */
1554 if (binoptab == smul_optab
1555 && GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1556 && (widening_optab_handler ((unsignedp ? umul_widen_optab
1557 : smul_widen_optab),
1558 GET_MODE_2XWIDER_MODE (mode), mode)
1559 != CODE_FOR_nothing))
1561 temp = expand_binop (GET_MODE_2XWIDER_MODE (mode),
1562 unsignedp ? umul_widen_optab : smul_widen_optab,
1563 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1565 if (temp != 0)
1567 if (GET_MODE_CLASS (mode) == MODE_INT
1568 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1569 return gen_lowpart (mode, temp);
1570 else
1571 return convert_to_mode (mode, temp, unsignedp);
1575 /* If this is a vector shift by a scalar, see if we can do a vector
1576 shift by a vector. If so, broadcast the scalar into a vector. */
1577 if (mclass == MODE_VECTOR_INT)
1579 optab otheroptab = unknown_optab;
1581 if (binoptab == ashl_optab)
1582 otheroptab = vashl_optab;
1583 else if (binoptab == ashr_optab)
1584 otheroptab = vashr_optab;
1585 else if (binoptab == lshr_optab)
1586 otheroptab = vlshr_optab;
1587 else if (binoptab == rotl_optab)
1588 otheroptab = vrotl_optab;
1589 else if (binoptab == rotr_optab)
1590 otheroptab = vrotr_optab;
1592 if (otheroptab && optab_handler (otheroptab, mode) != CODE_FOR_nothing)
1594 rtx vop1 = expand_vector_broadcast (mode, op1);
1595 if (vop1)
1597 temp = expand_binop_directly (mode, otheroptab, op0, vop1,
1598 target, unsignedp, methods, last);
1599 if (temp)
1600 return temp;
1605 /* Look for a wider mode of the same class for which we think we
1606 can open-code the operation. Check for a widening multiply at the
1607 wider mode as well. */
1609 if (CLASS_HAS_WIDER_MODES_P (mclass)
1610 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1611 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1612 wider_mode != VOIDmode;
1613 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1615 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1616 || (binoptab == smul_optab
1617 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1618 && (find_widening_optab_handler ((unsignedp
1619 ? umul_widen_optab
1620 : smul_widen_optab),
1621 GET_MODE_WIDER_MODE (wider_mode),
1622 mode, 0)
1623 != CODE_FOR_nothing)))
1625 rtx xop0 = op0, xop1 = op1;
1626 int no_extend = 0;
1628 /* For certain integer operations, we need not actually extend
1629 the narrow operands, as long as we will truncate
1630 the results to the same narrowness. */
1632 if ((binoptab == ior_optab || binoptab == and_optab
1633 || binoptab == xor_optab
1634 || binoptab == add_optab || binoptab == sub_optab
1635 || binoptab == smul_optab || binoptab == ashl_optab)
1636 && mclass == MODE_INT)
1638 no_extend = 1;
1639 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1640 xop0, unsignedp);
1641 if (binoptab != ashl_optab)
1642 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1643 xop1, unsignedp);
1646 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1648 /* The second operand of a shift must always be extended. */
1649 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1650 no_extend && binoptab != ashl_optab);
1652 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1653 unsignedp, OPTAB_DIRECT);
1654 if (temp)
1656 if (mclass != MODE_INT
1657 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1659 if (target == 0)
1660 target = gen_reg_rtx (mode);
1661 convert_move (target, temp, 0);
1662 return target;
1664 else
1665 return gen_lowpart (mode, temp);
1667 else
1668 delete_insns_since (last);
1672 /* If operation is commutative,
1673 try to make the first operand a register.
1674 Even better, try to make it the same as the target.
1675 Also try to make the last operand a constant. */
1676 if (commutative_optab_p (binoptab)
1677 && swap_commutative_operands_with_target (target, op0, op1))
1679 temp = op1;
1680 op1 = op0;
1681 op0 = temp;
1684 /* These can be done a word at a time. */
1685 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1686 && mclass == MODE_INT
1687 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1688 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1690 int i;
1691 rtx insns;
1693 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1694 won't be accurate, so use a new target. */
1695 if (target == 0
1696 || target == op0
1697 || target == op1
1698 || !valid_multiword_target_p (target))
1699 target = gen_reg_rtx (mode);
1701 start_sequence ();
1703 /* Do the actual arithmetic. */
1704 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1706 rtx target_piece = operand_subword (target, i, 1, mode);
1707 rtx x = expand_binop (word_mode, binoptab,
1708 operand_subword_force (op0, i, mode),
1709 operand_subword_force (op1, i, mode),
1710 target_piece, unsignedp, next_methods);
1712 if (x == 0)
1713 break;
1715 if (target_piece != x)
1716 emit_move_insn (target_piece, x);
1719 insns = get_insns ();
1720 end_sequence ();
1722 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1724 emit_insn (insns);
1725 return target;
1729 /* Synthesize double word shifts from single word shifts. */
1730 if ((binoptab == lshr_optab || binoptab == ashl_optab
1731 || binoptab == ashr_optab)
1732 && mclass == MODE_INT
1733 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1734 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1735 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode)
1736 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1737 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1738 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1740 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1741 enum machine_mode op1_mode;
1743 double_shift_mask = targetm.shift_truncation_mask (mode);
1744 shift_mask = targetm.shift_truncation_mask (word_mode);
1745 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1747 /* Apply the truncation to constant shifts. */
1748 if (double_shift_mask > 0 && CONST_INT_P (op1))
1749 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1751 if (op1 == CONST0_RTX (op1_mode))
1752 return op0;
1754 /* Make sure that this is a combination that expand_doubleword_shift
1755 can handle. See the comments there for details. */
1756 if (double_shift_mask == 0
1757 || (shift_mask == BITS_PER_WORD - 1
1758 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1760 rtx insns;
1761 rtx into_target, outof_target;
1762 rtx into_input, outof_input;
1763 int left_shift, outof_word;
1765 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1766 won't be accurate, so use a new target. */
1767 if (target == 0
1768 || target == op0
1769 || target == op1
1770 || !valid_multiword_target_p (target))
1771 target = gen_reg_rtx (mode);
1773 start_sequence ();
1775 /* OUTOF_* is the word we are shifting bits away from, and
1776 INTO_* is the word that we are shifting bits towards, thus
1777 they differ depending on the direction of the shift and
1778 WORDS_BIG_ENDIAN. */
1780 left_shift = binoptab == ashl_optab;
1781 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1783 outof_target = operand_subword (target, outof_word, 1, mode);
1784 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1786 outof_input = operand_subword_force (op0, outof_word, mode);
1787 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1789 if (expand_doubleword_shift (op1_mode, binoptab,
1790 outof_input, into_input, op1,
1791 outof_target, into_target,
1792 unsignedp, next_methods, shift_mask))
1794 insns = get_insns ();
1795 end_sequence ();
1797 emit_insn (insns);
1798 return target;
1800 end_sequence ();
1804 /* Synthesize double word rotates from single word shifts. */
1805 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1806 && mclass == MODE_INT
1807 && CONST_INT_P (op1)
1808 && GET_MODE_PRECISION (mode) == 2 * BITS_PER_WORD
1809 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1810 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1812 rtx insns;
1813 rtx into_target, outof_target;
1814 rtx into_input, outof_input;
1815 rtx inter;
1816 int shift_count, left_shift, outof_word;
1818 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1819 won't be accurate, so use a new target. Do this also if target is not
1820 a REG, first because having a register instead may open optimization
1821 opportunities, and second because if target and op0 happen to be MEMs
1822 designating the same location, we would risk clobbering it too early
1823 in the code sequence we generate below. */
1824 if (target == 0
1825 || target == op0
1826 || target == op1
1827 || !REG_P (target)
1828 || !valid_multiword_target_p (target))
1829 target = gen_reg_rtx (mode);
1831 start_sequence ();
1833 shift_count = INTVAL (op1);
1835 /* OUTOF_* is the word we are shifting bits away from, and
1836 INTO_* is the word that we are shifting bits towards, thus
1837 they differ depending on the direction of the shift and
1838 WORDS_BIG_ENDIAN. */
1840 left_shift = (binoptab == rotl_optab);
1841 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1843 outof_target = operand_subword (target, outof_word, 1, mode);
1844 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1846 outof_input = operand_subword_force (op0, outof_word, mode);
1847 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1849 if (shift_count == BITS_PER_WORD)
1851 /* This is just a word swap. */
1852 emit_move_insn (outof_target, into_input);
1853 emit_move_insn (into_target, outof_input);
1854 inter = const0_rtx;
1856 else
1858 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1859 rtx first_shift_count, second_shift_count;
1860 optab reverse_unsigned_shift, unsigned_shift;
1862 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1863 ? lshr_optab : ashl_optab);
1865 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1866 ? ashl_optab : lshr_optab);
1868 if (shift_count > BITS_PER_WORD)
1870 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1871 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1873 else
1875 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1876 second_shift_count = GEN_INT (shift_count);
1879 into_temp1 = expand_binop (word_mode, unsigned_shift,
1880 outof_input, first_shift_count,
1881 NULL_RTX, unsignedp, next_methods);
1882 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1883 into_input, second_shift_count,
1884 NULL_RTX, unsignedp, next_methods);
1886 if (into_temp1 != 0 && into_temp2 != 0)
1887 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1888 into_target, unsignedp, next_methods);
1889 else
1890 inter = 0;
1892 if (inter != 0 && inter != into_target)
1893 emit_move_insn (into_target, inter);
1895 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1896 into_input, first_shift_count,
1897 NULL_RTX, unsignedp, next_methods);
1898 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1899 outof_input, second_shift_count,
1900 NULL_RTX, unsignedp, next_methods);
1902 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1903 inter = expand_binop (word_mode, ior_optab,
1904 outof_temp1, outof_temp2,
1905 outof_target, unsignedp, next_methods);
1907 if (inter != 0 && inter != outof_target)
1908 emit_move_insn (outof_target, inter);
1911 insns = get_insns ();
1912 end_sequence ();
1914 if (inter != 0)
1916 emit_insn (insns);
1917 return target;
1921 /* These can be done a word at a time by propagating carries. */
1922 if ((binoptab == add_optab || binoptab == sub_optab)
1923 && mclass == MODE_INT
1924 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1925 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1927 unsigned int i;
1928 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1929 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1930 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1931 rtx xop0, xop1, xtarget;
1933 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1934 value is one of those, use it. Otherwise, use 1 since it is the
1935 one easiest to get. */
1936 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1937 int normalizep = STORE_FLAG_VALUE;
1938 #else
1939 int normalizep = 1;
1940 #endif
1942 /* Prepare the operands. */
1943 xop0 = force_reg (mode, op0);
1944 xop1 = force_reg (mode, op1);
1946 xtarget = gen_reg_rtx (mode);
1948 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1949 target = xtarget;
1951 /* Indicate for flow that the entire target reg is being set. */
1952 if (REG_P (target))
1953 emit_clobber (xtarget);
1955 /* Do the actual arithmetic. */
1956 for (i = 0; i < nwords; i++)
1958 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1959 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1960 rtx op0_piece = operand_subword_force (xop0, index, mode);
1961 rtx op1_piece = operand_subword_force (xop1, index, mode);
1962 rtx x;
1964 /* Main add/subtract of the input operands. */
1965 x = expand_binop (word_mode, binoptab,
1966 op0_piece, op1_piece,
1967 target_piece, unsignedp, next_methods);
1968 if (x == 0)
1969 break;
1971 if (i + 1 < nwords)
1973 /* Store carry from main add/subtract. */
1974 carry_out = gen_reg_rtx (word_mode);
1975 carry_out = emit_store_flag_force (carry_out,
1976 (binoptab == add_optab
1977 ? LT : GT),
1978 x, op0_piece,
1979 word_mode, 1, normalizep);
1982 if (i > 0)
1984 rtx newx;
1986 /* Add/subtract previous carry to main result. */
1987 newx = expand_binop (word_mode,
1988 normalizep == 1 ? binoptab : otheroptab,
1989 x, carry_in,
1990 NULL_RTX, 1, next_methods);
1992 if (i + 1 < nwords)
1994 /* Get out carry from adding/subtracting carry in. */
1995 rtx carry_tmp = gen_reg_rtx (word_mode);
1996 carry_tmp = emit_store_flag_force (carry_tmp,
1997 (binoptab == add_optab
1998 ? LT : GT),
1999 newx, x,
2000 word_mode, 1, normalizep);
2002 /* Logical-ior the two poss. carry together. */
2003 carry_out = expand_binop (word_mode, ior_optab,
2004 carry_out, carry_tmp,
2005 carry_out, 0, next_methods);
2006 if (carry_out == 0)
2007 break;
2009 emit_move_insn (target_piece, newx);
2011 else
2013 if (x != target_piece)
2014 emit_move_insn (target_piece, x);
2017 carry_in = carry_out;
2020 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
2022 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing
2023 || ! rtx_equal_p (target, xtarget))
2025 rtx temp = emit_move_insn (target, xtarget);
2027 set_dst_reg_note (temp, REG_EQUAL,
2028 gen_rtx_fmt_ee (optab_to_code (binoptab),
2029 mode, copy_rtx (xop0),
2030 copy_rtx (xop1)),
2031 target);
2033 else
2034 target = xtarget;
2036 return target;
2039 else
2040 delete_insns_since (last);
2043 /* Attempt to synthesize double word multiplies using a sequence of word
2044 mode multiplications. We first attempt to generate a sequence using a
2045 more efficient unsigned widening multiply, and if that fails we then
2046 try using a signed widening multiply. */
2048 if (binoptab == smul_optab
2049 && mclass == MODE_INT
2050 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2051 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
2052 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
2054 rtx product = NULL_RTX;
2055 if (widening_optab_handler (umul_widen_optab, mode, word_mode)
2056 != CODE_FOR_nothing)
2058 product = expand_doubleword_mult (mode, op0, op1, target,
2059 true, methods);
2060 if (!product)
2061 delete_insns_since (last);
2064 if (product == NULL_RTX
2065 && widening_optab_handler (smul_widen_optab, mode, word_mode)
2066 != CODE_FOR_nothing)
2068 product = expand_doubleword_mult (mode, op0, op1, target,
2069 false, methods);
2070 if (!product)
2071 delete_insns_since (last);
2074 if (product != NULL_RTX)
2076 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing)
2078 temp = emit_move_insn (target ? target : product, product);
2079 set_dst_reg_note (temp,
2080 REG_EQUAL,
2081 gen_rtx_fmt_ee (MULT, mode,
2082 copy_rtx (op0),
2083 copy_rtx (op1)),
2084 target ? target : product);
2086 return product;
2090 /* It can't be open-coded in this mode.
2091 Use a library call if one is available and caller says that's ok. */
2093 libfunc = optab_libfunc (binoptab, mode);
2094 if (libfunc
2095 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
2097 rtx insns;
2098 rtx op1x = op1;
2099 enum machine_mode op1_mode = mode;
2100 rtx value;
2102 start_sequence ();
2104 if (shift_optab_p (binoptab))
2106 op1_mode = targetm.libgcc_shift_count_mode ();
2107 /* Specify unsigned here,
2108 since negative shift counts are meaningless. */
2109 op1x = convert_to_mode (op1_mode, op1, 1);
2112 if (GET_MODE (op0) != VOIDmode
2113 && GET_MODE (op0) != mode)
2114 op0 = convert_to_mode (mode, op0, unsignedp);
2116 /* Pass 1 for NO_QUEUE so we don't lose any increments
2117 if the libcall is cse'd or moved. */
2118 value = emit_library_call_value (libfunc,
2119 NULL_RTX, LCT_CONST, mode, 2,
2120 op0, mode, op1x, op1_mode);
2122 insns = get_insns ();
2123 end_sequence ();
2125 target = gen_reg_rtx (mode);
2126 emit_libcall_block_1 (insns, target, value,
2127 gen_rtx_fmt_ee (optab_to_code (binoptab),
2128 mode, op0, op1),
2129 trapv_binoptab_p (binoptab));
2131 return target;
2134 delete_insns_since (last);
2136 /* It can't be done in this mode. Can we do it in a wider mode? */
2138 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
2139 || methods == OPTAB_MUST_WIDEN))
2141 /* Caller says, don't even try. */
2142 delete_insns_since (entry_last);
2143 return 0;
2146 /* Compute the value of METHODS to pass to recursive calls.
2147 Don't allow widening to be tried recursively. */
2149 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
2151 /* Look for a wider mode of the same class for which it appears we can do
2152 the operation. */
2154 if (CLASS_HAS_WIDER_MODES_P (mclass))
2156 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2157 wider_mode != VOIDmode;
2158 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2160 if (find_widening_optab_handler (binoptab, wider_mode, mode, 1)
2161 != CODE_FOR_nothing
2162 || (methods == OPTAB_LIB
2163 && optab_libfunc (binoptab, wider_mode)))
2165 rtx xop0 = op0, xop1 = op1;
2166 int no_extend = 0;
2168 /* For certain integer operations, we need not actually extend
2169 the narrow operands, as long as we will truncate
2170 the results to the same narrowness. */
2172 if ((binoptab == ior_optab || binoptab == and_optab
2173 || binoptab == xor_optab
2174 || binoptab == add_optab || binoptab == sub_optab
2175 || binoptab == smul_optab || binoptab == ashl_optab)
2176 && mclass == MODE_INT)
2177 no_extend = 1;
2179 xop0 = widen_operand (xop0, wider_mode, mode,
2180 unsignedp, no_extend);
2182 /* The second operand of a shift must always be extended. */
2183 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
2184 no_extend && binoptab != ashl_optab);
2186 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
2187 unsignedp, methods);
2188 if (temp)
2190 if (mclass != MODE_INT
2191 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2193 if (target == 0)
2194 target = gen_reg_rtx (mode);
2195 convert_move (target, temp, 0);
2196 return target;
2198 else
2199 return gen_lowpart (mode, temp);
2201 else
2202 delete_insns_since (last);
2207 delete_insns_since (entry_last);
2208 return 0;
2211 /* Expand a binary operator which has both signed and unsigned forms.
2212 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2213 signed operations.
2215 If we widen unsigned operands, we may use a signed wider operation instead
2216 of an unsigned wider operation, since the result would be the same. */
2219 sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
2220 rtx op0, rtx op1, rtx target, int unsignedp,
2221 enum optab_methods methods)
2223 rtx temp;
2224 optab direct_optab = unsignedp ? uoptab : soptab;
2225 bool save_enable;
2227 /* Do it without widening, if possible. */
2228 temp = expand_binop (mode, direct_optab, op0, op1, target,
2229 unsignedp, OPTAB_DIRECT);
2230 if (temp || methods == OPTAB_DIRECT)
2231 return temp;
2233 /* Try widening to a signed int. Disable any direct use of any
2234 signed insn in the current mode. */
2235 save_enable = swap_optab_enable (soptab, mode, false);
2237 temp = expand_binop (mode, soptab, op0, op1, target,
2238 unsignedp, OPTAB_WIDEN);
2240 /* For unsigned operands, try widening to an unsigned int. */
2241 if (!temp && unsignedp)
2242 temp = expand_binop (mode, uoptab, op0, op1, target,
2243 unsignedp, OPTAB_WIDEN);
2244 if (temp || methods == OPTAB_WIDEN)
2245 goto egress;
2247 /* Use the right width libcall if that exists. */
2248 temp = expand_binop (mode, direct_optab, op0, op1, target,
2249 unsignedp, OPTAB_LIB);
2250 if (temp || methods == OPTAB_LIB)
2251 goto egress;
2253 /* Must widen and use a libcall, use either signed or unsigned. */
2254 temp = expand_binop (mode, soptab, op0, op1, target,
2255 unsignedp, methods);
2256 if (!temp && unsignedp)
2257 temp = expand_binop (mode, uoptab, op0, op1, target,
2258 unsignedp, methods);
2260 egress:
2261 /* Undo the fiddling above. */
2262 if (save_enable)
2263 swap_optab_enable (soptab, mode, true);
2264 return temp;
2267 /* Generate code to perform an operation specified by UNOPPTAB
2268 on operand OP0, with two results to TARG0 and TARG1.
2269 We assume that the order of the operands for the instruction
2270 is TARG0, TARG1, OP0.
2272 Either TARG0 or TARG1 may be zero, but what that means is that
2273 the result is not actually wanted. We will generate it into
2274 a dummy pseudo-reg and discard it. They may not both be zero.
2276 Returns 1 if this operation can be performed; 0 if not. */
2279 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2280 int unsignedp)
2282 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2283 enum mode_class mclass;
2284 enum machine_mode wider_mode;
2285 rtx entry_last = get_last_insn ();
2286 rtx last;
2288 mclass = GET_MODE_CLASS (mode);
2290 if (!targ0)
2291 targ0 = gen_reg_rtx (mode);
2292 if (!targ1)
2293 targ1 = gen_reg_rtx (mode);
2295 /* Record where to go back to if we fail. */
2296 last = get_last_insn ();
2298 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2300 struct expand_operand ops[3];
2301 enum insn_code icode = optab_handler (unoptab, mode);
2303 create_fixed_operand (&ops[0], targ0);
2304 create_fixed_operand (&ops[1], targ1);
2305 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
2306 if (maybe_expand_insn (icode, 3, ops))
2307 return 1;
2310 /* It can't be done in this mode. Can we do it in a wider mode? */
2312 if (CLASS_HAS_WIDER_MODES_P (mclass))
2314 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2315 wider_mode != VOIDmode;
2316 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2318 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2320 rtx t0 = gen_reg_rtx (wider_mode);
2321 rtx t1 = gen_reg_rtx (wider_mode);
2322 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2324 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2326 convert_move (targ0, t0, unsignedp);
2327 convert_move (targ1, t1, unsignedp);
2328 return 1;
2330 else
2331 delete_insns_since (last);
2336 delete_insns_since (entry_last);
2337 return 0;
2340 /* Generate code to perform an operation specified by BINOPTAB
2341 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2342 We assume that the order of the operands for the instruction
2343 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2344 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2346 Either TARG0 or TARG1 may be zero, but what that means is that
2347 the result is not actually wanted. We will generate it into
2348 a dummy pseudo-reg and discard it. They may not both be zero.
2350 Returns 1 if this operation can be performed; 0 if not. */
2353 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2354 int unsignedp)
2356 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2357 enum mode_class mclass;
2358 enum machine_mode wider_mode;
2359 rtx entry_last = get_last_insn ();
2360 rtx last;
2362 mclass = GET_MODE_CLASS (mode);
2364 if (!targ0)
2365 targ0 = gen_reg_rtx (mode);
2366 if (!targ1)
2367 targ1 = gen_reg_rtx (mode);
2369 /* Record where to go back to if we fail. */
2370 last = get_last_insn ();
2372 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2374 struct expand_operand ops[4];
2375 enum insn_code icode = optab_handler (binoptab, mode);
2376 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2377 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2378 rtx xop0 = op0, xop1 = op1;
2380 /* If we are optimizing, force expensive constants into a register. */
2381 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2382 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2384 create_fixed_operand (&ops[0], targ0);
2385 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2386 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
2387 create_fixed_operand (&ops[3], targ1);
2388 if (maybe_expand_insn (icode, 4, ops))
2389 return 1;
2390 delete_insns_since (last);
2393 /* It can't be done in this mode. Can we do it in a wider mode? */
2395 if (CLASS_HAS_WIDER_MODES_P (mclass))
2397 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2398 wider_mode != VOIDmode;
2399 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2401 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2403 rtx t0 = gen_reg_rtx (wider_mode);
2404 rtx t1 = gen_reg_rtx (wider_mode);
2405 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2406 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2408 if (expand_twoval_binop (binoptab, cop0, cop1,
2409 t0, t1, unsignedp))
2411 convert_move (targ0, t0, unsignedp);
2412 convert_move (targ1, t1, unsignedp);
2413 return 1;
2415 else
2416 delete_insns_since (last);
2421 delete_insns_since (entry_last);
2422 return 0;
2425 /* Expand the two-valued library call indicated by BINOPTAB, but
2426 preserve only one of the values. If TARG0 is non-NULL, the first
2427 value is placed into TARG0; otherwise the second value is placed
2428 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2429 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2430 This routine assumes that the value returned by the library call is
2431 as if the return value was of an integral mode twice as wide as the
2432 mode of OP0. Returns 1 if the call was successful. */
2434 bool
2435 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2436 rtx targ0, rtx targ1, enum rtx_code code)
2438 enum machine_mode mode;
2439 enum machine_mode libval_mode;
2440 rtx libval;
2441 rtx insns;
2442 rtx libfunc;
2444 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2445 gcc_assert (!targ0 != !targ1);
2447 mode = GET_MODE (op0);
2448 libfunc = optab_libfunc (binoptab, mode);
2449 if (!libfunc)
2450 return false;
2452 /* The value returned by the library function will have twice as
2453 many bits as the nominal MODE. */
2454 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2455 MODE_INT);
2456 start_sequence ();
2457 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2458 libval_mode, 2,
2459 op0, mode,
2460 op1, mode);
2461 /* Get the part of VAL containing the value that we want. */
2462 libval = simplify_gen_subreg (mode, libval, libval_mode,
2463 targ0 ? 0 : GET_MODE_SIZE (mode));
2464 insns = get_insns ();
2465 end_sequence ();
2466 /* Move the into the desired location. */
2467 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2468 gen_rtx_fmt_ee (code, mode, op0, op1));
2470 return true;
2474 /* Wrapper around expand_unop which takes an rtx code to specify
2475 the operation to perform, not an optab pointer. All other
2476 arguments are the same. */
2478 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2479 rtx target, int unsignedp)
2481 optab unop = code_to_optab (code);
2482 gcc_assert (unop);
2484 return expand_unop (mode, unop, op0, target, unsignedp);
2487 /* Try calculating
2488 (clz:narrow x)
2490 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2492 A similar operation can be used for clrsb. UNOPTAB says which operation
2493 we are trying to expand. */
2494 static rtx
2495 widen_leading (enum machine_mode mode, rtx op0, rtx target, optab unoptab)
2497 enum mode_class mclass = GET_MODE_CLASS (mode);
2498 if (CLASS_HAS_WIDER_MODES_P (mclass))
2500 enum machine_mode wider_mode;
2501 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2502 wider_mode != VOIDmode;
2503 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2505 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2507 rtx xop0, temp, last;
2509 last = get_last_insn ();
2511 if (target == 0)
2512 target = gen_reg_rtx (mode);
2513 xop0 = widen_operand (op0, wider_mode, mode,
2514 unoptab != clrsb_optab, false);
2515 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2516 unoptab != clrsb_optab);
2517 if (temp != 0)
2518 temp = expand_binop (wider_mode, sub_optab, temp,
2519 GEN_INT (GET_MODE_PRECISION (wider_mode)
2520 - GET_MODE_PRECISION (mode)),
2521 target, true, OPTAB_DIRECT);
2522 if (temp == 0)
2523 delete_insns_since (last);
2525 return temp;
2529 return 0;
2532 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2533 quantities, choosing which based on whether the high word is nonzero. */
2534 static rtx
2535 expand_doubleword_clz (enum machine_mode mode, rtx op0, rtx target)
2537 rtx xop0 = force_reg (mode, op0);
2538 rtx subhi = gen_highpart (word_mode, xop0);
2539 rtx sublo = gen_lowpart (word_mode, xop0);
2540 rtx hi0_label = gen_label_rtx ();
2541 rtx after_label = gen_label_rtx ();
2542 rtx seq, temp, result;
2544 /* If we were not given a target, use a word_mode register, not a
2545 'mode' register. The result will fit, and nobody is expecting
2546 anything bigger (the return type of __builtin_clz* is int). */
2547 if (!target)
2548 target = gen_reg_rtx (word_mode);
2550 /* In any case, write to a word_mode scratch in both branches of the
2551 conditional, so we can ensure there is a single move insn setting
2552 'target' to tag a REG_EQUAL note on. */
2553 result = gen_reg_rtx (word_mode);
2555 start_sequence ();
2557 /* If the high word is not equal to zero,
2558 then clz of the full value is clz of the high word. */
2559 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2560 word_mode, true, hi0_label);
2562 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2563 if (!temp)
2564 goto fail;
2566 if (temp != result)
2567 convert_move (result, temp, true);
2569 emit_jump_insn (gen_jump (after_label));
2570 emit_barrier ();
2572 /* Else clz of the full value is clz of the low word plus the number
2573 of bits in the high word. */
2574 emit_label (hi0_label);
2576 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2577 if (!temp)
2578 goto fail;
2579 temp = expand_binop (word_mode, add_optab, temp,
2580 GEN_INT (GET_MODE_BITSIZE (word_mode)),
2581 result, true, OPTAB_DIRECT);
2582 if (!temp)
2583 goto fail;
2584 if (temp != result)
2585 convert_move (result, temp, true);
2587 emit_label (after_label);
2588 convert_move (target, result, true);
2590 seq = get_insns ();
2591 end_sequence ();
2593 add_equal_note (seq, target, CLZ, xop0, 0);
2594 emit_insn (seq);
2595 return target;
2597 fail:
2598 end_sequence ();
2599 return 0;
2602 /* Try calculating
2603 (bswap:narrow x)
2605 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2606 static rtx
2607 widen_bswap (enum machine_mode mode, rtx op0, rtx target)
2609 enum mode_class mclass = GET_MODE_CLASS (mode);
2610 enum machine_mode wider_mode;
2611 rtx x, last;
2613 if (!CLASS_HAS_WIDER_MODES_P (mclass))
2614 return NULL_RTX;
2616 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2617 wider_mode != VOIDmode;
2618 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2619 if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing)
2620 goto found;
2621 return NULL_RTX;
2623 found:
2624 last = get_last_insn ();
2626 x = widen_operand (op0, wider_mode, mode, true, true);
2627 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2629 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2630 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2631 if (x != 0)
2632 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2633 GET_MODE_BITSIZE (wider_mode)
2634 - GET_MODE_BITSIZE (mode),
2635 NULL_RTX, true);
2637 if (x != 0)
2639 if (target == 0)
2640 target = gen_reg_rtx (mode);
2641 emit_move_insn (target, gen_lowpart (mode, x));
2643 else
2644 delete_insns_since (last);
2646 return target;
2649 /* Try calculating bswap as two bswaps of two word-sized operands. */
2651 static rtx
2652 expand_doubleword_bswap (enum machine_mode mode, rtx op, rtx target)
2654 rtx t0, t1;
2656 t1 = expand_unop (word_mode, bswap_optab,
2657 operand_subword_force (op, 0, mode), NULL_RTX, true);
2658 t0 = expand_unop (word_mode, bswap_optab,
2659 operand_subword_force (op, 1, mode), NULL_RTX, true);
2661 if (target == 0 || !valid_multiword_target_p (target))
2662 target = gen_reg_rtx (mode);
2663 if (REG_P (target))
2664 emit_clobber (target);
2665 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2666 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2668 return target;
2671 /* Try calculating (parity x) as (and (popcount x) 1), where
2672 popcount can also be done in a wider mode. */
2673 static rtx
2674 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2676 enum mode_class mclass = GET_MODE_CLASS (mode);
2677 if (CLASS_HAS_WIDER_MODES_P (mclass))
2679 enum machine_mode wider_mode;
2680 for (wider_mode = mode; wider_mode != VOIDmode;
2681 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2683 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2685 rtx xop0, temp, last;
2687 last = get_last_insn ();
2689 if (target == 0)
2690 target = gen_reg_rtx (mode);
2691 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2692 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2693 true);
2694 if (temp != 0)
2695 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2696 target, true, OPTAB_DIRECT);
2697 if (temp == 0)
2698 delete_insns_since (last);
2700 return temp;
2704 return 0;
2707 /* Try calculating ctz(x) as K - clz(x & -x) ,
2708 where K is GET_MODE_PRECISION(mode) - 1.
2710 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2711 don't have to worry about what the hardware does in that case. (If
2712 the clz instruction produces the usual value at 0, which is K, the
2713 result of this code sequence will be -1; expand_ffs, below, relies
2714 on this. It might be nice to have it be K instead, for consistency
2715 with the (very few) processors that provide a ctz with a defined
2716 value, but that would take one more instruction, and it would be
2717 less convenient for expand_ffs anyway. */
2719 static rtx
2720 expand_ctz (enum machine_mode mode, rtx op0, rtx target)
2722 rtx seq, temp;
2724 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2725 return 0;
2727 start_sequence ();
2729 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2730 if (temp)
2731 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2732 true, OPTAB_DIRECT);
2733 if (temp)
2734 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2735 if (temp)
2736 temp = expand_binop (mode, sub_optab, GEN_INT (GET_MODE_PRECISION (mode) - 1),
2737 temp, target,
2738 true, OPTAB_DIRECT);
2739 if (temp == 0)
2741 end_sequence ();
2742 return 0;
2745 seq = get_insns ();
2746 end_sequence ();
2748 add_equal_note (seq, temp, CTZ, op0, 0);
2749 emit_insn (seq);
2750 return temp;
2754 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2755 else with the sequence used by expand_clz.
2757 The ffs builtin promises to return zero for a zero value and ctz/clz
2758 may have an undefined value in that case. If they do not give us a
2759 convenient value, we have to generate a test and branch. */
2760 static rtx
2761 expand_ffs (enum machine_mode mode, rtx op0, rtx target)
2763 HOST_WIDE_INT val = 0;
2764 bool defined_at_zero = false;
2765 rtx temp, seq;
2767 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2769 start_sequence ();
2771 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2772 if (!temp)
2773 goto fail;
2775 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2777 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2779 start_sequence ();
2780 temp = expand_ctz (mode, op0, 0);
2781 if (!temp)
2782 goto fail;
2784 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2786 defined_at_zero = true;
2787 val = (GET_MODE_PRECISION (mode) - 1) - val;
2790 else
2791 return 0;
2793 if (defined_at_zero && val == -1)
2794 /* No correction needed at zero. */;
2795 else
2797 /* We don't try to do anything clever with the situation found
2798 on some processors (eg Alpha) where ctz(0:mode) ==
2799 bitsize(mode). If someone can think of a way to send N to -1
2800 and leave alone all values in the range 0..N-1 (where N is a
2801 power of two), cheaper than this test-and-branch, please add it.
2803 The test-and-branch is done after the operation itself, in case
2804 the operation sets condition codes that can be recycled for this.
2805 (This is true on i386, for instance.) */
2807 rtx nonzero_label = gen_label_rtx ();
2808 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2809 mode, true, nonzero_label);
2811 convert_move (temp, GEN_INT (-1), false);
2812 emit_label (nonzero_label);
2815 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2816 to produce a value in the range 0..bitsize. */
2817 temp = expand_binop (mode, add_optab, temp, GEN_INT (1),
2818 target, false, OPTAB_DIRECT);
2819 if (!temp)
2820 goto fail;
2822 seq = get_insns ();
2823 end_sequence ();
2825 add_equal_note (seq, temp, FFS, op0, 0);
2826 emit_insn (seq);
2827 return temp;
2829 fail:
2830 end_sequence ();
2831 return 0;
2834 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2835 conditions, VAL may already be a SUBREG against which we cannot generate
2836 a further SUBREG. In this case, we expect forcing the value into a
2837 register will work around the situation. */
2839 static rtx
2840 lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2841 enum machine_mode imode)
2843 rtx ret;
2844 ret = lowpart_subreg (omode, val, imode);
2845 if (ret == NULL)
2847 val = force_reg (imode, val);
2848 ret = lowpart_subreg (omode, val, imode);
2849 gcc_assert (ret != NULL);
2851 return ret;
2854 /* Expand a floating point absolute value or negation operation via a
2855 logical operation on the sign bit. */
2857 static rtx
2858 expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2859 rtx op0, rtx target)
2861 const struct real_format *fmt;
2862 int bitpos, word, nwords, i;
2863 enum machine_mode imode;
2864 double_int mask;
2865 rtx temp, insns;
2867 /* The format has to have a simple sign bit. */
2868 fmt = REAL_MODE_FORMAT (mode);
2869 if (fmt == NULL)
2870 return NULL_RTX;
2872 bitpos = fmt->signbit_rw;
2873 if (bitpos < 0)
2874 return NULL_RTX;
2876 /* Don't create negative zeros if the format doesn't support them. */
2877 if (code == NEG && !fmt->has_signed_zero)
2878 return NULL_RTX;
2880 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2882 imode = int_mode_for_mode (mode);
2883 if (imode == BLKmode)
2884 return NULL_RTX;
2885 word = 0;
2886 nwords = 1;
2888 else
2890 imode = word_mode;
2892 if (FLOAT_WORDS_BIG_ENDIAN)
2893 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2894 else
2895 word = bitpos / BITS_PER_WORD;
2896 bitpos = bitpos % BITS_PER_WORD;
2897 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2900 mask = double_int_zero.set_bit (bitpos);
2901 if (code == ABS)
2902 mask = ~mask;
2904 if (target == 0
2905 || target == op0
2906 || (nwords > 1 && !valid_multiword_target_p (target)))
2907 target = gen_reg_rtx (mode);
2909 if (nwords > 1)
2911 start_sequence ();
2913 for (i = 0; i < nwords; ++i)
2915 rtx targ_piece = operand_subword (target, i, 1, mode);
2916 rtx op0_piece = operand_subword_force (op0, i, mode);
2918 if (i == word)
2920 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2921 op0_piece,
2922 immed_double_int_const (mask, imode),
2923 targ_piece, 1, OPTAB_LIB_WIDEN);
2924 if (temp != targ_piece)
2925 emit_move_insn (targ_piece, temp);
2927 else
2928 emit_move_insn (targ_piece, op0_piece);
2931 insns = get_insns ();
2932 end_sequence ();
2934 emit_insn (insns);
2936 else
2938 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2939 gen_lowpart (imode, op0),
2940 immed_double_int_const (mask, imode),
2941 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2942 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2944 set_dst_reg_note (get_last_insn (), REG_EQUAL,
2945 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
2946 target);
2949 return target;
2952 /* As expand_unop, but will fail rather than attempt the operation in a
2953 different mode or with a libcall. */
2954 static rtx
2955 expand_unop_direct (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2956 int unsignedp)
2958 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2960 struct expand_operand ops[2];
2961 enum insn_code icode = optab_handler (unoptab, mode);
2962 rtx last = get_last_insn ();
2963 rtx pat;
2965 create_output_operand (&ops[0], target, mode);
2966 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2967 pat = maybe_gen_insn (icode, 2, ops);
2968 if (pat)
2970 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2971 && ! add_equal_note (pat, ops[0].value, optab_to_code (unoptab),
2972 ops[1].value, NULL_RTX))
2974 delete_insns_since (last);
2975 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2978 emit_insn (pat);
2980 return ops[0].value;
2983 return 0;
2986 /* Generate code to perform an operation specified by UNOPTAB
2987 on operand OP0, with result having machine-mode MODE.
2989 UNSIGNEDP is for the case where we have to widen the operands
2990 to perform the operation. It says to use zero-extension.
2992 If TARGET is nonzero, the value
2993 is generated there, if it is convenient to do so.
2994 In all cases an rtx is returned for the locus of the value;
2995 this may or may not be TARGET. */
2998 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2999 int unsignedp)
3001 enum mode_class mclass = GET_MODE_CLASS (mode);
3002 enum machine_mode wider_mode;
3003 rtx temp;
3004 rtx libfunc;
3006 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
3007 if (temp)
3008 return temp;
3010 /* It can't be done in this mode. Can we open-code it in a wider mode? */
3012 /* Widening (or narrowing) clz needs special treatment. */
3013 if (unoptab == clz_optab)
3015 temp = widen_leading (mode, op0, target, unoptab);
3016 if (temp)
3017 return temp;
3019 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
3020 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3022 temp = expand_doubleword_clz (mode, op0, target);
3023 if (temp)
3024 return temp;
3027 goto try_libcall;
3030 if (unoptab == clrsb_optab)
3032 temp = widen_leading (mode, op0, target, unoptab);
3033 if (temp)
3034 return temp;
3035 goto try_libcall;
3038 /* Widening (or narrowing) bswap needs special treatment. */
3039 if (unoptab == bswap_optab)
3041 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
3042 or ROTATERT. First try these directly; if this fails, then try the
3043 obvious pair of shifts with allowed widening, as this will probably
3044 be always more efficient than the other fallback methods. */
3045 if (mode == HImode)
3047 rtx last, temp1, temp2;
3049 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
3051 temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target,
3052 unsignedp, OPTAB_DIRECT);
3053 if (temp)
3054 return temp;
3057 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
3059 temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target,
3060 unsignedp, OPTAB_DIRECT);
3061 if (temp)
3062 return temp;
3065 last = get_last_insn ();
3067 temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX,
3068 unsignedp, OPTAB_WIDEN);
3069 temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX,
3070 unsignedp, OPTAB_WIDEN);
3071 if (temp1 && temp2)
3073 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
3074 unsignedp, OPTAB_WIDEN);
3075 if (temp)
3076 return temp;
3079 delete_insns_since (last);
3082 temp = widen_bswap (mode, op0, target);
3083 if (temp)
3084 return temp;
3086 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
3087 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3089 temp = expand_doubleword_bswap (mode, op0, target);
3090 if (temp)
3091 return temp;
3094 goto try_libcall;
3097 if (CLASS_HAS_WIDER_MODES_P (mclass))
3098 for (wider_mode = GET_MODE_WIDER_MODE (mode);
3099 wider_mode != VOIDmode;
3100 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3102 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
3104 rtx xop0 = op0;
3105 rtx last = get_last_insn ();
3107 /* For certain operations, we need not actually extend
3108 the narrow operand, as long as we will truncate the
3109 results to the same narrowness. */
3111 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3112 (unoptab == neg_optab
3113 || unoptab == one_cmpl_optab)
3114 && mclass == MODE_INT);
3116 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3117 unsignedp);
3119 if (temp)
3121 if (mclass != MODE_INT
3122 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
3124 if (target == 0)
3125 target = gen_reg_rtx (mode);
3126 convert_move (target, temp, 0);
3127 return target;
3129 else
3130 return gen_lowpart (mode, temp);
3132 else
3133 delete_insns_since (last);
3137 /* These can be done a word at a time. */
3138 if (unoptab == one_cmpl_optab
3139 && mclass == MODE_INT
3140 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
3141 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3143 int i;
3144 rtx insns;
3146 if (target == 0 || target == op0 || !valid_multiword_target_p (target))
3147 target = gen_reg_rtx (mode);
3149 start_sequence ();
3151 /* Do the actual arithmetic. */
3152 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
3154 rtx target_piece = operand_subword (target, i, 1, mode);
3155 rtx x = expand_unop (word_mode, unoptab,
3156 operand_subword_force (op0, i, mode),
3157 target_piece, unsignedp);
3159 if (target_piece != x)
3160 emit_move_insn (target_piece, x);
3163 insns = get_insns ();
3164 end_sequence ();
3166 emit_insn (insns);
3167 return target;
3170 if (optab_to_code (unoptab) == NEG)
3172 /* Try negating floating point values by flipping the sign bit. */
3173 if (SCALAR_FLOAT_MODE_P (mode))
3175 temp = expand_absneg_bit (NEG, mode, op0, target);
3176 if (temp)
3177 return temp;
3180 /* If there is no negation pattern, and we have no negative zero,
3181 try subtracting from zero. */
3182 if (!HONOR_SIGNED_ZEROS (mode))
3184 temp = expand_binop (mode, (unoptab == negv_optab
3185 ? subv_optab : sub_optab),
3186 CONST0_RTX (mode), op0, target,
3187 unsignedp, OPTAB_DIRECT);
3188 if (temp)
3189 return temp;
3193 /* Try calculating parity (x) as popcount (x) % 2. */
3194 if (unoptab == parity_optab)
3196 temp = expand_parity (mode, op0, target);
3197 if (temp)
3198 return temp;
3201 /* Try implementing ffs (x) in terms of clz (x). */
3202 if (unoptab == ffs_optab)
3204 temp = expand_ffs (mode, op0, target);
3205 if (temp)
3206 return temp;
3209 /* Try implementing ctz (x) in terms of clz (x). */
3210 if (unoptab == ctz_optab)
3212 temp = expand_ctz (mode, op0, target);
3213 if (temp)
3214 return temp;
3217 try_libcall:
3218 /* Now try a library call in this mode. */
3219 libfunc = optab_libfunc (unoptab, mode);
3220 if (libfunc)
3222 rtx insns;
3223 rtx value;
3224 rtx eq_value;
3225 enum machine_mode outmode = mode;
3227 /* All of these functions return small values. Thus we choose to
3228 have them return something that isn't a double-word. */
3229 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3230 || unoptab == clrsb_optab || unoptab == popcount_optab
3231 || unoptab == parity_optab)
3232 outmode
3233 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
3234 optab_libfunc (unoptab, mode)));
3236 start_sequence ();
3238 /* Pass 1 for NO_QUEUE so we don't lose any increments
3239 if the libcall is cse'd or moved. */
3240 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
3241 1, op0, mode);
3242 insns = get_insns ();
3243 end_sequence ();
3245 target = gen_reg_rtx (outmode);
3246 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
3247 if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode))
3248 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
3249 else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
3250 eq_value = simplify_gen_unary (ZERO_EXTEND, outmode, eq_value, mode);
3251 emit_libcall_block_1 (insns, target, value, eq_value,
3252 trapv_unoptab_p (unoptab));
3254 return target;
3257 /* It can't be done in this mode. Can we do it in a wider mode? */
3259 if (CLASS_HAS_WIDER_MODES_P (mclass))
3261 for (wider_mode = GET_MODE_WIDER_MODE (mode);
3262 wider_mode != VOIDmode;
3263 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3265 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
3266 || optab_libfunc (unoptab, wider_mode))
3268 rtx xop0 = op0;
3269 rtx last = get_last_insn ();
3271 /* For certain operations, we need not actually extend
3272 the narrow operand, as long as we will truncate the
3273 results to the same narrowness. */
3274 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3275 (unoptab == neg_optab
3276 || unoptab == one_cmpl_optab
3277 || unoptab == bswap_optab)
3278 && mclass == MODE_INT);
3280 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3281 unsignedp);
3283 /* If we are generating clz using wider mode, adjust the
3284 result. Similarly for clrsb. */
3285 if ((unoptab == clz_optab || unoptab == clrsb_optab)
3286 && temp != 0)
3287 temp = expand_binop (wider_mode, sub_optab, temp,
3288 GEN_INT (GET_MODE_PRECISION (wider_mode)
3289 - GET_MODE_PRECISION (mode)),
3290 target, true, OPTAB_DIRECT);
3292 /* Likewise for bswap. */
3293 if (unoptab == bswap_optab && temp != 0)
3295 gcc_assert (GET_MODE_PRECISION (wider_mode)
3296 == GET_MODE_BITSIZE (wider_mode)
3297 && GET_MODE_PRECISION (mode)
3298 == GET_MODE_BITSIZE (mode));
3300 temp = expand_shift (RSHIFT_EXPR, wider_mode, temp,
3301 GET_MODE_BITSIZE (wider_mode)
3302 - GET_MODE_BITSIZE (mode),
3303 NULL_RTX, true);
3306 if (temp)
3308 if (mclass != MODE_INT)
3310 if (target == 0)
3311 target = gen_reg_rtx (mode);
3312 convert_move (target, temp, 0);
3313 return target;
3315 else
3316 return gen_lowpart (mode, temp);
3318 else
3319 delete_insns_since (last);
3324 /* One final attempt at implementing negation via subtraction,
3325 this time allowing widening of the operand. */
3326 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
3328 rtx temp;
3329 temp = expand_binop (mode,
3330 unoptab == negv_optab ? subv_optab : sub_optab,
3331 CONST0_RTX (mode), op0,
3332 target, unsignedp, OPTAB_LIB_WIDEN);
3333 if (temp)
3334 return temp;
3337 return 0;
3340 /* Emit code to compute the absolute value of OP0, with result to
3341 TARGET if convenient. (TARGET may be 0.) The return value says
3342 where the result actually is to be found.
3344 MODE is the mode of the operand; the mode of the result is
3345 different but can be deduced from MODE.
3350 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
3351 int result_unsignedp)
3353 rtx temp;
3355 if (! flag_trapv)
3356 result_unsignedp = 1;
3358 /* First try to do it with a special abs instruction. */
3359 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3360 op0, target, 0);
3361 if (temp != 0)
3362 return temp;
3364 /* For floating point modes, try clearing the sign bit. */
3365 if (SCALAR_FLOAT_MODE_P (mode))
3367 temp = expand_absneg_bit (ABS, mode, op0, target);
3368 if (temp)
3369 return temp;
3372 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3373 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3374 && !HONOR_SIGNED_ZEROS (mode))
3376 rtx last = get_last_insn ();
3378 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
3379 if (temp != 0)
3380 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3381 OPTAB_WIDEN);
3383 if (temp != 0)
3384 return temp;
3386 delete_insns_since (last);
3389 /* If this machine has expensive jumps, we can do integer absolute
3390 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3391 where W is the width of MODE. */
3393 if (GET_MODE_CLASS (mode) == MODE_INT
3394 && BRANCH_COST (optimize_insn_for_speed_p (),
3395 false) >= 2)
3397 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3398 GET_MODE_PRECISION (mode) - 1,
3399 NULL_RTX, 0);
3401 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3402 OPTAB_LIB_WIDEN);
3403 if (temp != 0)
3404 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3405 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3407 if (temp != 0)
3408 return temp;
3411 return NULL_RTX;
3415 expand_abs (enum machine_mode mode, rtx op0, rtx target,
3416 int result_unsignedp, int safe)
3418 rtx temp, op1;
3420 if (! flag_trapv)
3421 result_unsignedp = 1;
3423 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3424 if (temp != 0)
3425 return temp;
3427 /* If that does not win, use conditional jump and negate. */
3429 /* It is safe to use the target if it is the same
3430 as the source if this is also a pseudo register */
3431 if (op0 == target && REG_P (op0)
3432 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3433 safe = 1;
3435 op1 = gen_label_rtx ();
3436 if (target == 0 || ! safe
3437 || GET_MODE (target) != mode
3438 || (MEM_P (target) && MEM_VOLATILE_P (target))
3439 || (REG_P (target)
3440 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3441 target = gen_reg_rtx (mode);
3443 emit_move_insn (target, op0);
3444 NO_DEFER_POP;
3446 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3447 NULL_RTX, NULL_RTX, op1, -1);
3449 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3450 target, target, 0);
3451 if (op0 != target)
3452 emit_move_insn (target, op0);
3453 emit_label (op1);
3454 OK_DEFER_POP;
3455 return target;
3458 /* Emit code to compute the one's complement absolute value of OP0
3459 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3460 (TARGET may be NULL_RTX.) The return value says where the result
3461 actually is to be found.
3463 MODE is the mode of the operand; the mode of the result is
3464 different but can be deduced from MODE. */
3467 expand_one_cmpl_abs_nojump (enum machine_mode mode, rtx op0, rtx target)
3469 rtx temp;
3471 /* Not applicable for floating point modes. */
3472 if (FLOAT_MODE_P (mode))
3473 return NULL_RTX;
3475 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3476 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3478 rtx last = get_last_insn ();
3480 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3481 if (temp != 0)
3482 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3483 OPTAB_WIDEN);
3485 if (temp != 0)
3486 return temp;
3488 delete_insns_since (last);
3491 /* If this machine has expensive jumps, we can do one's complement
3492 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3494 if (GET_MODE_CLASS (mode) == MODE_INT
3495 && BRANCH_COST (optimize_insn_for_speed_p (),
3496 false) >= 2)
3498 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3499 GET_MODE_PRECISION (mode) - 1,
3500 NULL_RTX, 0);
3502 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3503 OPTAB_LIB_WIDEN);
3505 if (temp != 0)
3506 return temp;
3509 return NULL_RTX;
3512 /* A subroutine of expand_copysign, perform the copysign operation using the
3513 abs and neg primitives advertised to exist on the target. The assumption
3514 is that we have a split register file, and leaving op0 in fp registers,
3515 and not playing with subregs so much, will help the register allocator. */
3517 static rtx
3518 expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3519 int bitpos, bool op0_is_abs)
3521 enum machine_mode imode;
3522 enum insn_code icode;
3523 rtx sign, label;
3525 if (target == op1)
3526 target = NULL_RTX;
3528 /* Check if the back end provides an insn that handles signbit for the
3529 argument's mode. */
3530 icode = optab_handler (signbit_optab, mode);
3531 if (icode != CODE_FOR_nothing)
3533 imode = insn_data[(int) icode].operand[0].mode;
3534 sign = gen_reg_rtx (imode);
3535 emit_unop_insn (icode, sign, op1, UNKNOWN);
3537 else
3539 double_int mask;
3541 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3543 imode = int_mode_for_mode (mode);
3544 if (imode == BLKmode)
3545 return NULL_RTX;
3546 op1 = gen_lowpart (imode, op1);
3548 else
3550 int word;
3552 imode = word_mode;
3553 if (FLOAT_WORDS_BIG_ENDIAN)
3554 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3555 else
3556 word = bitpos / BITS_PER_WORD;
3557 bitpos = bitpos % BITS_PER_WORD;
3558 op1 = operand_subword_force (op1, word, mode);
3561 mask = double_int_zero.set_bit (bitpos);
3563 sign = expand_binop (imode, and_optab, op1,
3564 immed_double_int_const (mask, imode),
3565 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3568 if (!op0_is_abs)
3570 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3571 if (op0 == NULL)
3572 return NULL_RTX;
3573 target = op0;
3575 else
3577 if (target == NULL_RTX)
3578 target = copy_to_reg (op0);
3579 else
3580 emit_move_insn (target, op0);
3583 label = gen_label_rtx ();
3584 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3586 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3587 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3588 else
3589 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3590 if (op0 != target)
3591 emit_move_insn (target, op0);
3593 emit_label (label);
3595 return target;
3599 /* A subroutine of expand_copysign, perform the entire copysign operation
3600 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3601 is true if op0 is known to have its sign bit clear. */
3603 static rtx
3604 expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3605 int bitpos, bool op0_is_abs)
3607 enum machine_mode imode;
3608 double_int mask;
3609 int word, nwords, i;
3610 rtx temp, insns;
3612 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3614 imode = int_mode_for_mode (mode);
3615 if (imode == BLKmode)
3616 return NULL_RTX;
3617 word = 0;
3618 nwords = 1;
3620 else
3622 imode = word_mode;
3624 if (FLOAT_WORDS_BIG_ENDIAN)
3625 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3626 else
3627 word = bitpos / BITS_PER_WORD;
3628 bitpos = bitpos % BITS_PER_WORD;
3629 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3632 mask = double_int_zero.set_bit (bitpos);
3634 if (target == 0
3635 || target == op0
3636 || target == op1
3637 || (nwords > 1 && !valid_multiword_target_p (target)))
3638 target = gen_reg_rtx (mode);
3640 if (nwords > 1)
3642 start_sequence ();
3644 for (i = 0; i < nwords; ++i)
3646 rtx targ_piece = operand_subword (target, i, 1, mode);
3647 rtx op0_piece = operand_subword_force (op0, i, mode);
3649 if (i == word)
3651 if (!op0_is_abs)
3652 op0_piece
3653 = expand_binop (imode, and_optab, op0_piece,
3654 immed_double_int_const (~mask, imode),
3655 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3657 op1 = expand_binop (imode, and_optab,
3658 operand_subword_force (op1, i, mode),
3659 immed_double_int_const (mask, imode),
3660 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3662 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3663 targ_piece, 1, OPTAB_LIB_WIDEN);
3664 if (temp != targ_piece)
3665 emit_move_insn (targ_piece, temp);
3667 else
3668 emit_move_insn (targ_piece, op0_piece);
3671 insns = get_insns ();
3672 end_sequence ();
3674 emit_insn (insns);
3676 else
3678 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3679 immed_double_int_const (mask, imode),
3680 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3682 op0 = gen_lowpart (imode, op0);
3683 if (!op0_is_abs)
3684 op0 = expand_binop (imode, and_optab, op0,
3685 immed_double_int_const (~mask, imode),
3686 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3688 temp = expand_binop (imode, ior_optab, op0, op1,
3689 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3690 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3693 return target;
3696 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3697 scalar floating point mode. Return NULL if we do not know how to
3698 expand the operation inline. */
3701 expand_copysign (rtx op0, rtx op1, rtx target)
3703 enum machine_mode mode = GET_MODE (op0);
3704 const struct real_format *fmt;
3705 bool op0_is_abs;
3706 rtx temp;
3708 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3709 gcc_assert (GET_MODE (op1) == mode);
3711 /* First try to do it with a special instruction. */
3712 temp = expand_binop (mode, copysign_optab, op0, op1,
3713 target, 0, OPTAB_DIRECT);
3714 if (temp)
3715 return temp;
3717 fmt = REAL_MODE_FORMAT (mode);
3718 if (fmt == NULL || !fmt->has_signed_zero)
3719 return NULL_RTX;
3721 op0_is_abs = false;
3722 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3724 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3725 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3726 op0_is_abs = true;
3729 if (fmt->signbit_ro >= 0
3730 && (CONST_DOUBLE_AS_FLOAT_P (op0)
3731 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3732 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3734 temp = expand_copysign_absneg (mode, op0, op1, target,
3735 fmt->signbit_ro, op0_is_abs);
3736 if (temp)
3737 return temp;
3740 if (fmt->signbit_rw < 0)
3741 return NULL_RTX;
3742 return expand_copysign_bit (mode, op0, op1, target,
3743 fmt->signbit_rw, op0_is_abs);
3746 /* Generate an instruction whose insn-code is INSN_CODE,
3747 with two operands: an output TARGET and an input OP0.
3748 TARGET *must* be nonzero, and the output is always stored there.
3749 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3750 the value that is stored into TARGET.
3752 Return false if expansion failed. */
3754 bool
3755 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3756 enum rtx_code code)
3758 struct expand_operand ops[2];
3759 rtx pat;
3761 create_output_operand (&ops[0], target, GET_MODE (target));
3762 create_input_operand (&ops[1], op0, GET_MODE (op0));
3763 pat = maybe_gen_insn (icode, 2, ops);
3764 if (!pat)
3765 return false;
3767 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3768 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX);
3770 emit_insn (pat);
3772 if (ops[0].value != target)
3773 emit_move_insn (target, ops[0].value);
3774 return true;
3776 /* Generate an instruction whose insn-code is INSN_CODE,
3777 with two operands: an output TARGET and an input OP0.
3778 TARGET *must* be nonzero, and the output is always stored there.
3779 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3780 the value that is stored into TARGET. */
3782 void
3783 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3785 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3786 gcc_assert (ok);
3789 struct no_conflict_data
3791 rtx target, first, insn;
3792 bool must_stay;
3795 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3796 the currently examined clobber / store has to stay in the list of
3797 insns that constitute the actual libcall block. */
3798 static void
3799 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3801 struct no_conflict_data *p= (struct no_conflict_data *) p0;
3803 /* If this inns directly contributes to setting the target, it must stay. */
3804 if (reg_overlap_mentioned_p (p->target, dest))
3805 p->must_stay = true;
3806 /* If we haven't committed to keeping any other insns in the list yet,
3807 there is nothing more to check. */
3808 else if (p->insn == p->first)
3809 return;
3810 /* If this insn sets / clobbers a register that feeds one of the insns
3811 already in the list, this insn has to stay too. */
3812 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3813 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3814 || reg_used_between_p (dest, p->first, p->insn)
3815 /* Likewise if this insn depends on a register set by a previous
3816 insn in the list, or if it sets a result (presumably a hard
3817 register) that is set or clobbered by a previous insn.
3818 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3819 SET_DEST perform the former check on the address, and the latter
3820 check on the MEM. */
3821 || (GET_CODE (set) == SET
3822 && (modified_in_p (SET_SRC (set), p->first)
3823 || modified_in_p (SET_DEST (set), p->first)
3824 || modified_between_p (SET_SRC (set), p->first, p->insn)
3825 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3826 p->must_stay = true;
3830 /* Emit code to make a call to a constant function or a library call.
3832 INSNS is a list containing all insns emitted in the call.
3833 These insns leave the result in RESULT. Our block is to copy RESULT
3834 to TARGET, which is logically equivalent to EQUIV.
3836 We first emit any insns that set a pseudo on the assumption that these are
3837 loading constants into registers; doing so allows them to be safely cse'ed
3838 between blocks. Then we emit all the other insns in the block, followed by
3839 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3840 note with an operand of EQUIV. */
3842 static void
3843 emit_libcall_block_1 (rtx insns, rtx target, rtx result, rtx equiv,
3844 bool equiv_may_trap)
3846 rtx final_dest = target;
3847 rtx next, last, insn;
3849 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3850 into a MEM later. Protect the libcall block from this change. */
3851 if (! REG_P (target) || REG_USERVAR_P (target))
3852 target = gen_reg_rtx (GET_MODE (target));
3854 /* If we're using non-call exceptions, a libcall corresponding to an
3855 operation that may trap may also trap. */
3856 /* ??? See the comment in front of make_reg_eh_region_note. */
3857 if (cfun->can_throw_non_call_exceptions
3858 && (equiv_may_trap || may_trap_p (equiv)))
3860 for (insn = insns; insn; insn = NEXT_INSN (insn))
3861 if (CALL_P (insn))
3863 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3864 if (note)
3866 int lp_nr = INTVAL (XEXP (note, 0));
3867 if (lp_nr == 0 || lp_nr == INT_MIN)
3868 remove_note (insn, note);
3872 else
3874 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3875 reg note to indicate that this call cannot throw or execute a nonlocal
3876 goto (unless there is already a REG_EH_REGION note, in which case
3877 we update it). */
3878 for (insn = insns; insn; insn = NEXT_INSN (insn))
3879 if (CALL_P (insn))
3880 make_reg_eh_region_note_nothrow_nononlocal (insn);
3883 /* First emit all insns that set pseudos. Remove them from the list as
3884 we go. Avoid insns that set pseudos which were referenced in previous
3885 insns. These can be generated by move_by_pieces, for example,
3886 to update an address. Similarly, avoid insns that reference things
3887 set in previous insns. */
3889 for (insn = insns; insn; insn = next)
3891 rtx set = single_set (insn);
3893 next = NEXT_INSN (insn);
3895 if (set != 0 && REG_P (SET_DEST (set))
3896 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3898 struct no_conflict_data data;
3900 data.target = const0_rtx;
3901 data.first = insns;
3902 data.insn = insn;
3903 data.must_stay = 0;
3904 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3905 if (! data.must_stay)
3907 if (PREV_INSN (insn))
3908 NEXT_INSN (PREV_INSN (insn)) = next;
3909 else
3910 insns = next;
3912 if (next)
3913 PREV_INSN (next) = PREV_INSN (insn);
3915 add_insn (insn);
3919 /* Some ports use a loop to copy large arguments onto the stack.
3920 Don't move anything outside such a loop. */
3921 if (LABEL_P (insn))
3922 break;
3925 /* Write the remaining insns followed by the final copy. */
3926 for (insn = insns; insn; insn = next)
3928 next = NEXT_INSN (insn);
3930 add_insn (insn);
3933 last = emit_move_insn (target, result);
3934 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
3936 if (final_dest != target)
3937 emit_move_insn (final_dest, target);
3940 void
3941 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3943 emit_libcall_block_1 (insns, target, result, equiv, false);
3946 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3947 PURPOSE describes how this comparison will be used. CODE is the rtx
3948 comparison code we will be using.
3950 ??? Actually, CODE is slightly weaker than that. A target is still
3951 required to implement all of the normal bcc operations, but not
3952 required to implement all (or any) of the unordered bcc operations. */
3955 can_compare_p (enum rtx_code code, enum machine_mode mode,
3956 enum can_compare_purpose purpose)
3958 rtx test;
3959 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
3962 enum insn_code icode;
3964 if (purpose == ccp_jump
3965 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
3966 && insn_operand_matches (icode, 0, test))
3967 return 1;
3968 if (purpose == ccp_store_flag
3969 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
3970 && insn_operand_matches (icode, 1, test))
3971 return 1;
3972 if (purpose == ccp_cmov
3973 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
3974 return 1;
3976 mode = GET_MODE_WIDER_MODE (mode);
3977 PUT_MODE (test, mode);
3979 while (mode != VOIDmode);
3981 return 0;
3984 /* This function is called when we are going to emit a compare instruction that
3985 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3987 *PMODE is the mode of the inputs (in case they are const_int).
3988 *PUNSIGNEDP nonzero says that the operands are unsigned;
3989 this matters if they need to be widened (as given by METHODS).
3991 If they have mode BLKmode, then SIZE specifies the size of both operands.
3993 This function performs all the setup necessary so that the caller only has
3994 to emit a single comparison insn. This setup can involve doing a BLKmode
3995 comparison or emitting a library call to perform the comparison if no insn
3996 is available to handle it.
3997 The values which are passed in through pointers can be modified; the caller
3998 should perform the comparison on the modified values. Constant
3999 comparisons must have already been folded. */
4001 static void
4002 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4003 int unsignedp, enum optab_methods methods,
4004 rtx *ptest, enum machine_mode *pmode)
4006 enum machine_mode mode = *pmode;
4007 rtx libfunc, test;
4008 enum machine_mode cmp_mode;
4009 enum mode_class mclass;
4011 /* The other methods are not needed. */
4012 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
4013 || methods == OPTAB_LIB_WIDEN);
4015 /* If we are optimizing, force expensive constants into a register. */
4016 if (CONSTANT_P (x) && optimize
4017 && (rtx_cost (x, COMPARE, 0, optimize_insn_for_speed_p ())
4018 > COSTS_N_INSNS (1)))
4019 x = force_reg (mode, x);
4021 if (CONSTANT_P (y) && optimize
4022 && (rtx_cost (y, COMPARE, 1, optimize_insn_for_speed_p ())
4023 > COSTS_N_INSNS (1)))
4024 y = force_reg (mode, y);
4026 #ifdef HAVE_cc0
4027 /* Make sure if we have a canonical comparison. The RTL
4028 documentation states that canonical comparisons are required only
4029 for targets which have cc0. */
4030 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
4031 #endif
4033 /* Don't let both operands fail to indicate the mode. */
4034 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
4035 x = force_reg (mode, x);
4036 if (mode == VOIDmode)
4037 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
4039 /* Handle all BLKmode compares. */
4041 if (mode == BLKmode)
4043 enum machine_mode result_mode;
4044 enum insn_code cmp_code;
4045 tree length_type;
4046 rtx libfunc;
4047 rtx result;
4048 rtx opalign
4049 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
4051 gcc_assert (size);
4053 /* Try to use a memory block compare insn - either cmpstr
4054 or cmpmem will do. */
4055 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
4056 cmp_mode != VOIDmode;
4057 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
4059 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
4060 if (cmp_code == CODE_FOR_nothing)
4061 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
4062 if (cmp_code == CODE_FOR_nothing)
4063 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
4064 if (cmp_code == CODE_FOR_nothing)
4065 continue;
4067 /* Must make sure the size fits the insn's mode. */
4068 if ((CONST_INT_P (size)
4069 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
4070 || (GET_MODE_BITSIZE (GET_MODE (size))
4071 > GET_MODE_BITSIZE (cmp_mode)))
4072 continue;
4074 result_mode = insn_data[cmp_code].operand[0].mode;
4075 result = gen_reg_rtx (result_mode);
4076 size = convert_to_mode (cmp_mode, size, 1);
4077 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
4079 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
4080 *pmode = result_mode;
4081 return;
4084 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
4085 goto fail;
4087 /* Otherwise call a library function, memcmp. */
4088 libfunc = memcmp_libfunc;
4089 length_type = sizetype;
4090 result_mode = TYPE_MODE (integer_type_node);
4091 cmp_mode = TYPE_MODE (length_type);
4092 size = convert_to_mode (TYPE_MODE (length_type), size,
4093 TYPE_UNSIGNED (length_type));
4095 result = emit_library_call_value (libfunc, 0, LCT_PURE,
4096 result_mode, 3,
4097 XEXP (x, 0), Pmode,
4098 XEXP (y, 0), Pmode,
4099 size, cmp_mode);
4100 x = result;
4101 y = const0_rtx;
4102 mode = result_mode;
4103 methods = OPTAB_LIB_WIDEN;
4104 unsignedp = false;
4107 /* Don't allow operands to the compare to trap, as that can put the
4108 compare and branch in different basic blocks. */
4109 if (cfun->can_throw_non_call_exceptions)
4111 if (may_trap_p (x))
4112 x = force_reg (mode, x);
4113 if (may_trap_p (y))
4114 y = force_reg (mode, y);
4117 if (GET_MODE_CLASS (mode) == MODE_CC)
4119 gcc_assert (can_compare_p (comparison, CCmode, ccp_jump));
4120 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4121 return;
4124 mclass = GET_MODE_CLASS (mode);
4125 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4126 cmp_mode = mode;
4129 enum insn_code icode;
4130 icode = optab_handler (cbranch_optab, cmp_mode);
4131 if (icode != CODE_FOR_nothing
4132 && insn_operand_matches (icode, 0, test))
4134 rtx last = get_last_insn ();
4135 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
4136 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
4137 if (op0 && op1
4138 && insn_operand_matches (icode, 1, op0)
4139 && insn_operand_matches (icode, 2, op1))
4141 XEXP (test, 0) = op0;
4142 XEXP (test, 1) = op1;
4143 *ptest = test;
4144 *pmode = cmp_mode;
4145 return;
4147 delete_insns_since (last);
4150 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
4151 break;
4152 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode);
4154 while (cmp_mode != VOIDmode);
4156 if (methods != OPTAB_LIB_WIDEN)
4157 goto fail;
4159 if (!SCALAR_FLOAT_MODE_P (mode))
4161 rtx result;
4162 enum machine_mode ret_mode;
4164 /* Handle a libcall just for the mode we are using. */
4165 libfunc = optab_libfunc (cmp_optab, mode);
4166 gcc_assert (libfunc);
4168 /* If we want unsigned, and this mode has a distinct unsigned
4169 comparison routine, use that. */
4170 if (unsignedp)
4172 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
4173 if (ulibfunc)
4174 libfunc = ulibfunc;
4177 ret_mode = targetm.libgcc_cmp_return_mode ();
4178 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4179 ret_mode, 2, x, mode, y, mode);
4181 /* There are two kinds of comparison routines. Biased routines
4182 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4183 of gcc expect that the comparison operation is equivalent
4184 to the modified comparison. For signed comparisons compare the
4185 result against 1 in the biased case, and zero in the unbiased
4186 case. For unsigned comparisons always compare against 1 after
4187 biasing the unbiased result by adding 1. This gives us a way to
4188 represent LTU.
4189 The comparisons in the fixed-point helper library are always
4190 biased. */
4191 x = result;
4192 y = const1_rtx;
4194 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
4196 if (unsignedp)
4197 x = plus_constant (ret_mode, result, 1);
4198 else
4199 y = const0_rtx;
4202 *pmode = word_mode;
4203 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
4204 ptest, pmode);
4206 else
4207 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
4209 return;
4211 fail:
4212 *ptest = NULL_RTX;
4215 /* Before emitting an insn with code ICODE, make sure that X, which is going
4216 to be used for operand OPNUM of the insn, is converted from mode MODE to
4217 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4218 that it is accepted by the operand predicate. Return the new value. */
4221 prepare_operand (enum insn_code icode, rtx x, int opnum, enum machine_mode mode,
4222 enum machine_mode wider_mode, int unsignedp)
4224 if (mode != wider_mode)
4225 x = convert_modes (wider_mode, mode, x, unsignedp);
4227 if (!insn_operand_matches (icode, opnum, x))
4229 if (reload_completed)
4230 return NULL_RTX;
4231 x = copy_to_mode_reg (insn_data[(int) icode].operand[opnum].mode, x);
4234 return x;
4237 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4238 we can do the branch. */
4240 static void
4241 emit_cmp_and_jump_insn_1 (rtx test, enum machine_mode mode, rtx label, int prob)
4243 enum machine_mode optab_mode;
4244 enum mode_class mclass;
4245 enum insn_code icode;
4246 rtx insn;
4248 mclass = GET_MODE_CLASS (mode);
4249 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
4250 icode = optab_handler (cbranch_optab, optab_mode);
4252 gcc_assert (icode != CODE_FOR_nothing);
4253 gcc_assert (insn_operand_matches (icode, 0, test));
4254 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
4255 XEXP (test, 1), label));
4256 if (prob != -1
4257 && profile_status != PROFILE_ABSENT
4258 && insn
4259 && JUMP_P (insn)
4260 && any_condjump_p (insn)
4261 && !find_reg_note (insn, REG_BR_PROB, 0))
4262 add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
4265 /* Generate code to compare X with Y so that the condition codes are
4266 set and to jump to LABEL if the condition is true. If X is a
4267 constant and Y is not a constant, then the comparison is swapped to
4268 ensure that the comparison RTL has the canonical form.
4270 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4271 need to be widened. UNSIGNEDP is also used to select the proper
4272 branch condition code.
4274 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4276 MODE is the mode of the inputs (in case they are const_int).
4278 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4279 It will be potentially converted into an unsigned variant based on
4280 UNSIGNEDP to select a proper jump instruction.
4282 PROB is the probability of jumping to LABEL. */
4284 void
4285 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4286 enum machine_mode mode, int unsignedp, rtx label,
4287 int prob)
4289 rtx op0 = x, op1 = y;
4290 rtx test;
4292 /* Swap operands and condition to ensure canonical RTL. */
4293 if (swap_commutative_operands_p (x, y)
4294 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4296 op0 = y, op1 = x;
4297 comparison = swap_condition (comparison);
4300 /* If OP0 is still a constant, then both X and Y must be constants
4301 or the opposite comparison is not supported. Force X into a register
4302 to create canonical RTL. */
4303 if (CONSTANT_P (op0))
4304 op0 = force_reg (mode, op0);
4306 if (unsignedp)
4307 comparison = unsigned_condition (comparison);
4309 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4310 &test, &mode);
4311 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
4315 /* Emit a library call comparison between floating point X and Y.
4316 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4318 static void
4319 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4320 rtx *ptest, enum machine_mode *pmode)
4322 enum rtx_code swapped = swap_condition (comparison);
4323 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4324 enum machine_mode orig_mode = GET_MODE (x);
4325 enum machine_mode mode, cmp_mode;
4326 rtx true_rtx, false_rtx;
4327 rtx value, target, insns, equiv;
4328 rtx libfunc = 0;
4329 bool reversed_p = false;
4330 cmp_mode = targetm.libgcc_cmp_return_mode ();
4332 for (mode = orig_mode;
4333 mode != VOIDmode;
4334 mode = GET_MODE_WIDER_MODE (mode))
4336 if (code_to_optab (comparison)
4337 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
4338 break;
4340 if (code_to_optab (swapped)
4341 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
4343 rtx tmp;
4344 tmp = x; x = y; y = tmp;
4345 comparison = swapped;
4346 break;
4349 if (code_to_optab (reversed)
4350 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4352 comparison = reversed;
4353 reversed_p = true;
4354 break;
4358 gcc_assert (mode != VOIDmode);
4360 if (mode != orig_mode)
4362 x = convert_to_mode (mode, x, 0);
4363 y = convert_to_mode (mode, y, 0);
4366 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4367 the RTL. The allows the RTL optimizers to delete the libcall if the
4368 condition can be determined at compile-time. */
4369 if (comparison == UNORDERED
4370 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4372 true_rtx = const_true_rtx;
4373 false_rtx = const0_rtx;
4375 else
4377 switch (comparison)
4379 case EQ:
4380 true_rtx = const0_rtx;
4381 false_rtx = const_true_rtx;
4382 break;
4384 case NE:
4385 true_rtx = const_true_rtx;
4386 false_rtx = const0_rtx;
4387 break;
4389 case GT:
4390 true_rtx = const1_rtx;
4391 false_rtx = const0_rtx;
4392 break;
4394 case GE:
4395 true_rtx = const0_rtx;
4396 false_rtx = constm1_rtx;
4397 break;
4399 case LT:
4400 true_rtx = constm1_rtx;
4401 false_rtx = const0_rtx;
4402 break;
4404 case LE:
4405 true_rtx = const0_rtx;
4406 false_rtx = const1_rtx;
4407 break;
4409 default:
4410 gcc_unreachable ();
4414 if (comparison == UNORDERED)
4416 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4417 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4418 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4419 temp, const_true_rtx, equiv);
4421 else
4423 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4424 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4425 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4426 equiv, true_rtx, false_rtx);
4429 start_sequence ();
4430 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4431 cmp_mode, 2, x, mode, y, mode);
4432 insns = get_insns ();
4433 end_sequence ();
4435 target = gen_reg_rtx (cmp_mode);
4436 emit_libcall_block (insns, target, value, equiv);
4438 if (comparison == UNORDERED
4439 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4440 || reversed_p)
4441 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4442 else
4443 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4445 *pmode = cmp_mode;
4448 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4450 void
4451 emit_indirect_jump (rtx loc)
4453 struct expand_operand ops[1];
4455 create_address_operand (&ops[0], loc);
4456 expand_jump_insn (CODE_FOR_indirect_jump, 1, ops);
4457 emit_barrier ();
4460 #ifdef HAVE_conditional_move
4462 /* Emit a conditional move instruction if the machine supports one for that
4463 condition and machine mode.
4465 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4466 the mode to use should they be constants. If it is VOIDmode, they cannot
4467 both be constants.
4469 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4470 should be stored there. MODE is the mode to use should they be constants.
4471 If it is VOIDmode, they cannot both be constants.
4473 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4474 is not supported. */
4477 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4478 enum machine_mode cmode, rtx op2, rtx op3,
4479 enum machine_mode mode, int unsignedp)
4481 rtx tem, comparison, last;
4482 enum insn_code icode;
4483 enum rtx_code reversed;
4485 /* If one operand is constant, make it the second one. Only do this
4486 if the other operand is not constant as well. */
4488 if (swap_commutative_operands_p (op0, op1))
4490 tem = op0;
4491 op0 = op1;
4492 op1 = tem;
4493 code = swap_condition (code);
4496 /* get_condition will prefer to generate LT and GT even if the old
4497 comparison was against zero, so undo that canonicalization here since
4498 comparisons against zero are cheaper. */
4499 if (code == LT && op1 == const1_rtx)
4500 code = LE, op1 = const0_rtx;
4501 else if (code == GT && op1 == constm1_rtx)
4502 code = GE, op1 = const0_rtx;
4504 if (cmode == VOIDmode)
4505 cmode = GET_MODE (op0);
4507 if (swap_commutative_operands_p (op2, op3)
4508 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4509 != UNKNOWN))
4511 tem = op2;
4512 op2 = op3;
4513 op3 = tem;
4514 code = reversed;
4517 if (mode == VOIDmode)
4518 mode = GET_MODE (op2);
4520 icode = direct_optab_handler (movcc_optab, mode);
4522 if (icode == CODE_FOR_nothing)
4523 return 0;
4525 if (!target)
4526 target = gen_reg_rtx (mode);
4528 code = unsignedp ? unsigned_condition (code) : code;
4529 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4531 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4532 return NULL and let the caller figure out how best to deal with this
4533 situation. */
4534 if (!COMPARISON_P (comparison))
4535 return NULL_RTX;
4537 do_pending_stack_adjust ();
4538 last = get_last_insn ();
4539 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4540 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4541 &comparison, &cmode);
4542 if (comparison)
4544 struct expand_operand ops[4];
4546 create_output_operand (&ops[0], target, mode);
4547 create_fixed_operand (&ops[1], comparison);
4548 create_input_operand (&ops[2], op2, mode);
4549 create_input_operand (&ops[3], op3, mode);
4550 if (maybe_expand_insn (icode, 4, ops))
4552 if (ops[0].value != target)
4553 convert_move (target, ops[0].value, false);
4554 return target;
4557 delete_insns_since (last);
4558 return NULL_RTX;
4561 /* Return nonzero if a conditional move of mode MODE is supported.
4563 This function is for combine so it can tell whether an insn that looks
4564 like a conditional move is actually supported by the hardware. If we
4565 guess wrong we lose a bit on optimization, but that's it. */
4566 /* ??? sparc64 supports conditionally moving integers values based on fp
4567 comparisons, and vice versa. How do we handle them? */
4570 can_conditionally_move_p (enum machine_mode mode)
4572 if (direct_optab_handler (movcc_optab, mode) != CODE_FOR_nothing)
4573 return 1;
4575 return 0;
4578 #endif /* HAVE_conditional_move */
4580 /* Emit a conditional addition instruction if the machine supports one for that
4581 condition and machine mode.
4583 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4584 the mode to use should they be constants. If it is VOIDmode, they cannot
4585 both be constants.
4587 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4588 should be stored there. MODE is the mode to use should they be constants.
4589 If it is VOIDmode, they cannot both be constants.
4591 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4592 is not supported. */
4595 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4596 enum machine_mode cmode, rtx op2, rtx op3,
4597 enum machine_mode mode, int unsignedp)
4599 rtx tem, comparison, last;
4600 enum insn_code icode;
4602 /* If one operand is constant, make it the second one. Only do this
4603 if the other operand is not constant as well. */
4605 if (swap_commutative_operands_p (op0, op1))
4607 tem = op0;
4608 op0 = op1;
4609 op1 = tem;
4610 code = swap_condition (code);
4613 /* get_condition will prefer to generate LT and GT even if the old
4614 comparison was against zero, so undo that canonicalization here since
4615 comparisons against zero are cheaper. */
4616 if (code == LT && op1 == const1_rtx)
4617 code = LE, op1 = const0_rtx;
4618 else if (code == GT && op1 == constm1_rtx)
4619 code = GE, op1 = const0_rtx;
4621 if (cmode == VOIDmode)
4622 cmode = GET_MODE (op0);
4624 if (mode == VOIDmode)
4625 mode = GET_MODE (op2);
4627 icode = optab_handler (addcc_optab, mode);
4629 if (icode == CODE_FOR_nothing)
4630 return 0;
4632 if (!target)
4633 target = gen_reg_rtx (mode);
4635 code = unsignedp ? unsigned_condition (code) : code;
4636 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4638 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4639 return NULL and let the caller figure out how best to deal with this
4640 situation. */
4641 if (!COMPARISON_P (comparison))
4642 return NULL_RTX;
4644 do_pending_stack_adjust ();
4645 last = get_last_insn ();
4646 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4647 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4648 &comparison, &cmode);
4649 if (comparison)
4651 struct expand_operand ops[4];
4653 create_output_operand (&ops[0], target, mode);
4654 create_fixed_operand (&ops[1], comparison);
4655 create_input_operand (&ops[2], op2, mode);
4656 create_input_operand (&ops[3], op3, mode);
4657 if (maybe_expand_insn (icode, 4, ops))
4659 if (ops[0].value != target)
4660 convert_move (target, ops[0].value, false);
4661 return target;
4664 delete_insns_since (last);
4665 return NULL_RTX;
4668 /* These functions attempt to generate an insn body, rather than
4669 emitting the insn, but if the gen function already emits them, we
4670 make no attempt to turn them back into naked patterns. */
4672 /* Generate and return an insn body to add Y to X. */
4675 gen_add2_insn (rtx x, rtx y)
4677 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
4679 gcc_assert (insn_operand_matches (icode, 0, x));
4680 gcc_assert (insn_operand_matches (icode, 1, x));
4681 gcc_assert (insn_operand_matches (icode, 2, y));
4683 return GEN_FCN (icode) (x, x, y);
4686 /* Generate and return an insn body to add r1 and c,
4687 storing the result in r0. */
4690 gen_add3_insn (rtx r0, rtx r1, rtx c)
4692 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
4694 if (icode == CODE_FOR_nothing
4695 || !insn_operand_matches (icode, 0, r0)
4696 || !insn_operand_matches (icode, 1, r1)
4697 || !insn_operand_matches (icode, 2, c))
4698 return NULL_RTX;
4700 return GEN_FCN (icode) (r0, r1, c);
4704 have_add2_insn (rtx x, rtx y)
4706 enum insn_code icode;
4708 gcc_assert (GET_MODE (x) != VOIDmode);
4710 icode = optab_handler (add_optab, GET_MODE (x));
4712 if (icode == CODE_FOR_nothing)
4713 return 0;
4715 if (!insn_operand_matches (icode, 0, x)
4716 || !insn_operand_matches (icode, 1, x)
4717 || !insn_operand_matches (icode, 2, y))
4718 return 0;
4720 return 1;
4723 /* Generate and return an insn body to subtract Y from X. */
4726 gen_sub2_insn (rtx x, rtx y)
4728 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
4730 gcc_assert (insn_operand_matches (icode, 0, x));
4731 gcc_assert (insn_operand_matches (icode, 1, x));
4732 gcc_assert (insn_operand_matches (icode, 2, y));
4734 return GEN_FCN (icode) (x, x, y);
4737 /* Generate and return an insn body to subtract r1 and c,
4738 storing the result in r0. */
4741 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4743 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
4745 if (icode == CODE_FOR_nothing
4746 || !insn_operand_matches (icode, 0, r0)
4747 || !insn_operand_matches (icode, 1, r1)
4748 || !insn_operand_matches (icode, 2, c))
4749 return NULL_RTX;
4751 return GEN_FCN (icode) (r0, r1, c);
4755 have_sub2_insn (rtx x, rtx y)
4757 enum insn_code icode;
4759 gcc_assert (GET_MODE (x) != VOIDmode);
4761 icode = optab_handler (sub_optab, GET_MODE (x));
4763 if (icode == CODE_FOR_nothing)
4764 return 0;
4766 if (!insn_operand_matches (icode, 0, x)
4767 || !insn_operand_matches (icode, 1, x)
4768 || !insn_operand_matches (icode, 2, y))
4769 return 0;
4771 return 1;
4774 /* Generate the body of an instruction to copy Y into X.
4775 It may be a list of insns, if one insn isn't enough. */
4778 gen_move_insn (rtx x, rtx y)
4780 rtx seq;
4782 start_sequence ();
4783 emit_move_insn_1 (x, y);
4784 seq = get_insns ();
4785 end_sequence ();
4786 return seq;
4789 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4790 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4791 no such operation exists, CODE_FOR_nothing will be returned. */
4793 enum insn_code
4794 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4795 int unsignedp)
4797 convert_optab tab;
4798 #ifdef HAVE_ptr_extend
4799 if (unsignedp < 0)
4800 return CODE_FOR_ptr_extend;
4801 #endif
4803 tab = unsignedp ? zext_optab : sext_optab;
4804 return convert_optab_handler (tab, to_mode, from_mode);
4807 /* Generate the body of an insn to extend Y (with mode MFROM)
4808 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4811 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4812 enum machine_mode mfrom, int unsignedp)
4814 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4815 return GEN_FCN (icode) (x, y);
4818 /* can_fix_p and can_float_p say whether the target machine
4819 can directly convert a given fixed point type to
4820 a given floating point type, or vice versa.
4821 The returned value is the CODE_FOR_... value to use,
4822 or CODE_FOR_nothing if these modes cannot be directly converted.
4824 *TRUNCP_PTR is set to 1 if it is necessary to output
4825 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4827 static enum insn_code
4828 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4829 int unsignedp, int *truncp_ptr)
4831 convert_optab tab;
4832 enum insn_code icode;
4834 tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4835 icode = convert_optab_handler (tab, fixmode, fltmode);
4836 if (icode != CODE_FOR_nothing)
4838 *truncp_ptr = 0;
4839 return icode;
4842 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4843 for this to work. We need to rework the fix* and ftrunc* patterns
4844 and documentation. */
4845 tab = unsignedp ? ufix_optab : sfix_optab;
4846 icode = convert_optab_handler (tab, fixmode, fltmode);
4847 if (icode != CODE_FOR_nothing
4848 && optab_handler (ftrunc_optab, fltmode) != CODE_FOR_nothing)
4850 *truncp_ptr = 1;
4851 return icode;
4854 *truncp_ptr = 0;
4855 return CODE_FOR_nothing;
4858 enum insn_code
4859 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4860 int unsignedp)
4862 convert_optab tab;
4864 tab = unsignedp ? ufloat_optab : sfloat_optab;
4865 return convert_optab_handler (tab, fltmode, fixmode);
4868 /* Function supportable_convert_operation
4870 Check whether an operation represented by the code CODE is a
4871 convert operation that is supported by the target platform in
4872 vector form (i.e., when operating on arguments of type VECTYPE_IN
4873 producing a result of type VECTYPE_OUT).
4875 Convert operations we currently support directly are FIX_TRUNC and FLOAT.
4876 This function checks if these operations are supported
4877 by the target platform either directly (via vector tree-codes), or via
4878 target builtins.
4880 Output:
4881 - CODE1 is code of vector operation to be used when
4882 vectorizing the operation, if available.
4883 - DECL is decl of target builtin functions to be used
4884 when vectorizing the operation, if available. In this case,
4885 CODE1 is CALL_EXPR. */
4887 bool
4888 supportable_convert_operation (enum tree_code code,
4889 tree vectype_out, tree vectype_in,
4890 tree *decl, enum tree_code *code1)
4892 enum machine_mode m1,m2;
4893 int truncp;
4895 m1 = TYPE_MODE (vectype_out);
4896 m2 = TYPE_MODE (vectype_in);
4898 /* First check if we can done conversion directly. */
4899 if ((code == FIX_TRUNC_EXPR
4900 && can_fix_p (m1,m2,TYPE_UNSIGNED (vectype_out), &truncp)
4901 != CODE_FOR_nothing)
4902 || (code == FLOAT_EXPR
4903 && can_float_p (m1,m2,TYPE_UNSIGNED (vectype_in))
4904 != CODE_FOR_nothing))
4906 *code1 = code;
4907 return true;
4910 /* Now check for builtin. */
4911 if (targetm.vectorize.builtin_conversion
4912 && targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in))
4914 *code1 = CALL_EXPR;
4915 *decl = targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in);
4916 return true;
4918 return false;
4922 /* Generate code to convert FROM to floating point
4923 and store in TO. FROM must be fixed point and not VOIDmode.
4924 UNSIGNEDP nonzero means regard FROM as unsigned.
4925 Normally this is done by correcting the final value
4926 if it is negative. */
4928 void
4929 expand_float (rtx to, rtx from, int unsignedp)
4931 enum insn_code icode;
4932 rtx target = to;
4933 enum machine_mode fmode, imode;
4934 bool can_do_signed = false;
4936 /* Crash now, because we won't be able to decide which mode to use. */
4937 gcc_assert (GET_MODE (from) != VOIDmode);
4939 /* Look for an insn to do the conversion. Do it in the specified
4940 modes if possible; otherwise convert either input, output or both to
4941 wider mode. If the integer mode is wider than the mode of FROM,
4942 we can do the conversion signed even if the input is unsigned. */
4944 for (fmode = GET_MODE (to); fmode != VOIDmode;
4945 fmode = GET_MODE_WIDER_MODE (fmode))
4946 for (imode = GET_MODE (from); imode != VOIDmode;
4947 imode = GET_MODE_WIDER_MODE (imode))
4949 int doing_unsigned = unsignedp;
4951 if (fmode != GET_MODE (to)
4952 && significand_size (fmode) < GET_MODE_PRECISION (GET_MODE (from)))
4953 continue;
4955 icode = can_float_p (fmode, imode, unsignedp);
4956 if (icode == CODE_FOR_nothing && unsignedp)
4958 enum insn_code scode = can_float_p (fmode, imode, 0);
4959 if (scode != CODE_FOR_nothing)
4960 can_do_signed = true;
4961 if (imode != GET_MODE (from))
4962 icode = scode, doing_unsigned = 0;
4965 if (icode != CODE_FOR_nothing)
4967 if (imode != GET_MODE (from))
4968 from = convert_to_mode (imode, from, unsignedp);
4970 if (fmode != GET_MODE (to))
4971 target = gen_reg_rtx (fmode);
4973 emit_unop_insn (icode, target, from,
4974 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4976 if (target != to)
4977 convert_move (to, target, 0);
4978 return;
4982 /* Unsigned integer, and no way to convert directly. Convert as signed,
4983 then unconditionally adjust the result. */
4984 if (unsignedp && can_do_signed)
4986 rtx label = gen_label_rtx ();
4987 rtx temp;
4988 REAL_VALUE_TYPE offset;
4990 /* Look for a usable floating mode FMODE wider than the source and at
4991 least as wide as the target. Using FMODE will avoid rounding woes
4992 with unsigned values greater than the signed maximum value. */
4994 for (fmode = GET_MODE (to); fmode != VOIDmode;
4995 fmode = GET_MODE_WIDER_MODE (fmode))
4996 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4997 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4998 break;
5000 if (fmode == VOIDmode)
5002 /* There is no such mode. Pretend the target is wide enough. */
5003 fmode = GET_MODE (to);
5005 /* Avoid double-rounding when TO is narrower than FROM. */
5006 if ((significand_size (fmode) + 1)
5007 < GET_MODE_PRECISION (GET_MODE (from)))
5009 rtx temp1;
5010 rtx neglabel = gen_label_rtx ();
5012 /* Don't use TARGET if it isn't a register, is a hard register,
5013 or is the wrong mode. */
5014 if (!REG_P (target)
5015 || REGNO (target) < FIRST_PSEUDO_REGISTER
5016 || GET_MODE (target) != fmode)
5017 target = gen_reg_rtx (fmode);
5019 imode = GET_MODE (from);
5020 do_pending_stack_adjust ();
5022 /* Test whether the sign bit is set. */
5023 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
5024 0, neglabel);
5026 /* The sign bit is not set. Convert as signed. */
5027 expand_float (target, from, 0);
5028 emit_jump_insn (gen_jump (label));
5029 emit_barrier ();
5031 /* The sign bit is set.
5032 Convert to a usable (positive signed) value by shifting right
5033 one bit, while remembering if a nonzero bit was shifted
5034 out; i.e., compute (from & 1) | (from >> 1). */
5036 emit_label (neglabel);
5037 temp = expand_binop (imode, and_optab, from, const1_rtx,
5038 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5039 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
5040 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
5041 OPTAB_LIB_WIDEN);
5042 expand_float (target, temp, 0);
5044 /* Multiply by 2 to undo the shift above. */
5045 temp = expand_binop (fmode, add_optab, target, target,
5046 target, 0, OPTAB_LIB_WIDEN);
5047 if (temp != target)
5048 emit_move_insn (target, temp);
5050 do_pending_stack_adjust ();
5051 emit_label (label);
5052 goto done;
5056 /* If we are about to do some arithmetic to correct for an
5057 unsigned operand, do it in a pseudo-register. */
5059 if (GET_MODE (to) != fmode
5060 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
5061 target = gen_reg_rtx (fmode);
5063 /* Convert as signed integer to floating. */
5064 expand_float (target, from, 0);
5066 /* If FROM is negative (and therefore TO is negative),
5067 correct its value by 2**bitwidth. */
5069 do_pending_stack_adjust ();
5070 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
5071 0, label);
5074 real_2expN (&offset, GET_MODE_PRECISION (GET_MODE (from)), fmode);
5075 temp = expand_binop (fmode, add_optab, target,
5076 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
5077 target, 0, OPTAB_LIB_WIDEN);
5078 if (temp != target)
5079 emit_move_insn (target, temp);
5081 do_pending_stack_adjust ();
5082 emit_label (label);
5083 goto done;
5086 /* No hardware instruction available; call a library routine. */
5088 rtx libfunc;
5089 rtx insns;
5090 rtx value;
5091 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
5093 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
5094 from = convert_to_mode (SImode, from, unsignedp);
5096 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5097 gcc_assert (libfunc);
5099 start_sequence ();
5101 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5102 GET_MODE (to), 1, from,
5103 GET_MODE (from));
5104 insns = get_insns ();
5105 end_sequence ();
5107 emit_libcall_block (insns, target, value,
5108 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
5109 GET_MODE (to), from));
5112 done:
5114 /* Copy result to requested destination
5115 if we have been computing in a temp location. */
5117 if (target != to)
5119 if (GET_MODE (target) == GET_MODE (to))
5120 emit_move_insn (to, target);
5121 else
5122 convert_move (to, target, 0);
5126 /* Generate code to convert FROM to fixed point and store in TO. FROM
5127 must be floating point. */
5129 void
5130 expand_fix (rtx to, rtx from, int unsignedp)
5132 enum insn_code icode;
5133 rtx target = to;
5134 enum machine_mode fmode, imode;
5135 int must_trunc = 0;
5137 /* We first try to find a pair of modes, one real and one integer, at
5138 least as wide as FROM and TO, respectively, in which we can open-code
5139 this conversion. If the integer mode is wider than the mode of TO,
5140 we can do the conversion either signed or unsigned. */
5142 for (fmode = GET_MODE (from); fmode != VOIDmode;
5143 fmode = GET_MODE_WIDER_MODE (fmode))
5144 for (imode = GET_MODE (to); imode != VOIDmode;
5145 imode = GET_MODE_WIDER_MODE (imode))
5147 int doing_unsigned = unsignedp;
5149 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5150 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5151 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5153 if (icode != CODE_FOR_nothing)
5155 rtx last = get_last_insn ();
5156 if (fmode != GET_MODE (from))
5157 from = convert_to_mode (fmode, from, 0);
5159 if (must_trunc)
5161 rtx temp = gen_reg_rtx (GET_MODE (from));
5162 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
5163 temp, 0);
5166 if (imode != GET_MODE (to))
5167 target = gen_reg_rtx (imode);
5169 if (maybe_emit_unop_insn (icode, target, from,
5170 doing_unsigned ? UNSIGNED_FIX : FIX))
5172 if (target != to)
5173 convert_move (to, target, unsignedp);
5174 return;
5176 delete_insns_since (last);
5180 /* For an unsigned conversion, there is one more way to do it.
5181 If we have a signed conversion, we generate code that compares
5182 the real value to the largest representable positive number. If if
5183 is smaller, the conversion is done normally. Otherwise, subtract
5184 one plus the highest signed number, convert, and add it back.
5186 We only need to check all real modes, since we know we didn't find
5187 anything with a wider integer mode.
5189 This code used to extend FP value into mode wider than the destination.
5190 This is needed for decimal float modes which cannot accurately
5191 represent one plus the highest signed number of the same size, but
5192 not for binary modes. Consider, for instance conversion from SFmode
5193 into DImode.
5195 The hot path through the code is dealing with inputs smaller than 2^63
5196 and doing just the conversion, so there is no bits to lose.
5198 In the other path we know the value is positive in the range 2^63..2^64-1
5199 inclusive. (as for other input overflow happens and result is undefined)
5200 So we know that the most important bit set in mantissa corresponds to
5201 2^63. The subtraction of 2^63 should not generate any rounding as it
5202 simply clears out that bit. The rest is trivial. */
5204 if (unsignedp && GET_MODE_PRECISION (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
5205 for (fmode = GET_MODE (from); fmode != VOIDmode;
5206 fmode = GET_MODE_WIDER_MODE (fmode))
5207 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
5208 && (!DECIMAL_FLOAT_MODE_P (fmode)
5209 || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (GET_MODE (to))))
5211 int bitsize;
5212 REAL_VALUE_TYPE offset;
5213 rtx limit, lab1, lab2, insn;
5215 bitsize = GET_MODE_PRECISION (GET_MODE (to));
5216 real_2expN (&offset, bitsize - 1, fmode);
5217 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
5218 lab1 = gen_label_rtx ();
5219 lab2 = gen_label_rtx ();
5221 if (fmode != GET_MODE (from))
5222 from = convert_to_mode (fmode, from, 0);
5224 /* See if we need to do the subtraction. */
5225 do_pending_stack_adjust ();
5226 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
5227 0, lab1);
5229 /* If not, do the signed "fix" and branch around fixup code. */
5230 expand_fix (to, from, 0);
5231 emit_jump_insn (gen_jump (lab2));
5232 emit_barrier ();
5234 /* Otherwise, subtract 2**(N-1), convert to signed number,
5235 then add 2**(N-1). Do the addition using XOR since this
5236 will often generate better code. */
5237 emit_label (lab1);
5238 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5239 NULL_RTX, 0, OPTAB_LIB_WIDEN);
5240 expand_fix (to, target, 0);
5241 target = expand_binop (GET_MODE (to), xor_optab, to,
5242 gen_int_mode
5243 ((HOST_WIDE_INT) 1 << (bitsize - 1),
5244 GET_MODE (to)),
5245 to, 1, OPTAB_LIB_WIDEN);
5247 if (target != to)
5248 emit_move_insn (to, target);
5250 emit_label (lab2);
5252 if (optab_handler (mov_optab, GET_MODE (to)) != CODE_FOR_nothing)
5254 /* Make a place for a REG_NOTE and add it. */
5255 insn = emit_move_insn (to, to);
5256 set_dst_reg_note (insn, REG_EQUAL,
5257 gen_rtx_fmt_e (UNSIGNED_FIX, GET_MODE (to),
5258 copy_rtx (from)),
5259 to);
5262 return;
5265 /* We can't do it with an insn, so use a library call. But first ensure
5266 that the mode of TO is at least as wide as SImode, since those are the
5267 only library calls we know about. */
5269 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
5271 target = gen_reg_rtx (SImode);
5273 expand_fix (target, from, unsignedp);
5275 else
5277 rtx insns;
5278 rtx value;
5279 rtx libfunc;
5281 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5282 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5283 gcc_assert (libfunc);
5285 start_sequence ();
5287 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5288 GET_MODE (to), 1, from,
5289 GET_MODE (from));
5290 insns = get_insns ();
5291 end_sequence ();
5293 emit_libcall_block (insns, target, value,
5294 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5295 GET_MODE (to), from));
5298 if (target != to)
5300 if (GET_MODE (to) == GET_MODE (target))
5301 emit_move_insn (to, target);
5302 else
5303 convert_move (to, target, 0);
5307 /* Generate code to convert FROM or TO a fixed-point.
5308 If UINTP is true, either TO or FROM is an unsigned integer.
5309 If SATP is true, we need to saturate the result. */
5311 void
5312 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5314 enum machine_mode to_mode = GET_MODE (to);
5315 enum machine_mode from_mode = GET_MODE (from);
5316 convert_optab tab;
5317 enum rtx_code this_code;
5318 enum insn_code code;
5319 rtx insns, value;
5320 rtx libfunc;
5322 if (to_mode == from_mode)
5324 emit_move_insn (to, from);
5325 return;
5328 if (uintp)
5330 tab = satp ? satfractuns_optab : fractuns_optab;
5331 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5333 else
5335 tab = satp ? satfract_optab : fract_optab;
5336 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5338 code = convert_optab_handler (tab, to_mode, from_mode);
5339 if (code != CODE_FOR_nothing)
5341 emit_unop_insn (code, to, from, this_code);
5342 return;
5345 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5346 gcc_assert (libfunc);
5348 start_sequence ();
5349 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5350 1, from, from_mode);
5351 insns = get_insns ();
5352 end_sequence ();
5354 emit_libcall_block (insns, to, value,
5355 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
5358 /* Generate code to convert FROM to fixed point and store in TO. FROM
5359 must be floating point, TO must be signed. Use the conversion optab
5360 TAB to do the conversion. */
5362 bool
5363 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5365 enum insn_code icode;
5366 rtx target = to;
5367 enum machine_mode fmode, imode;
5369 /* We first try to find a pair of modes, one real and one integer, at
5370 least as wide as FROM and TO, respectively, in which we can open-code
5371 this conversion. If the integer mode is wider than the mode of TO,
5372 we can do the conversion either signed or unsigned. */
5374 for (fmode = GET_MODE (from); fmode != VOIDmode;
5375 fmode = GET_MODE_WIDER_MODE (fmode))
5376 for (imode = GET_MODE (to); imode != VOIDmode;
5377 imode = GET_MODE_WIDER_MODE (imode))
5379 icode = convert_optab_handler (tab, imode, fmode);
5380 if (icode != CODE_FOR_nothing)
5382 rtx last = get_last_insn ();
5383 if (fmode != GET_MODE (from))
5384 from = convert_to_mode (fmode, from, 0);
5386 if (imode != GET_MODE (to))
5387 target = gen_reg_rtx (imode);
5389 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5391 delete_insns_since (last);
5392 continue;
5394 if (target != to)
5395 convert_move (to, target, 0);
5396 return true;
5400 return false;
5403 /* Report whether we have an instruction to perform the operation
5404 specified by CODE on operands of mode MODE. */
5406 have_insn_for (enum rtx_code code, enum machine_mode mode)
5408 return (code_to_optab (code)
5409 && (optab_handler (code_to_optab (code), mode)
5410 != CODE_FOR_nothing));
5413 /* Initialize the libfunc fields of an entire group of entries in some
5414 optab. Each entry is set equal to a string consisting of a leading
5415 pair of underscores followed by a generic operation name followed by
5416 a mode name (downshifted to lowercase) followed by a single character
5417 representing the number of operands for the given operation (which is
5418 usually one of the characters '2', '3', or '4').
5420 OPTABLE is the table in which libfunc fields are to be initialized.
5421 OPNAME is the generic (string) name of the operation.
5422 SUFFIX is the character which specifies the number of operands for
5423 the given generic operation.
5424 MODE is the mode to generate for.
5427 static void
5428 gen_libfunc (optab optable, const char *opname, int suffix,
5429 enum machine_mode mode)
5431 unsigned opname_len = strlen (opname);
5432 const char *mname = GET_MODE_NAME (mode);
5433 unsigned mname_len = strlen (mname);
5434 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5435 int len = prefix_len + opname_len + mname_len + 1 + 1;
5436 char *libfunc_name = XALLOCAVEC (char, len);
5437 char *p;
5438 const char *q;
5440 p = libfunc_name;
5441 *p++ = '_';
5442 *p++ = '_';
5443 if (targetm.libfunc_gnu_prefix)
5445 *p++ = 'g';
5446 *p++ = 'n';
5447 *p++ = 'u';
5448 *p++ = '_';
5450 for (q = opname; *q; )
5451 *p++ = *q++;
5452 for (q = mname; *q; q++)
5453 *p++ = TOLOWER (*q);
5454 *p++ = suffix;
5455 *p = '\0';
5457 set_optab_libfunc (optable, mode,
5458 ggc_alloc_string (libfunc_name, p - libfunc_name));
5461 /* Like gen_libfunc, but verify that integer operation is involved. */
5463 void
5464 gen_int_libfunc (optab optable, const char *opname, char suffix,
5465 enum machine_mode mode)
5467 int maxsize = 2 * BITS_PER_WORD;
5469 if (GET_MODE_CLASS (mode) != MODE_INT)
5470 return;
5471 if (maxsize < LONG_LONG_TYPE_SIZE)
5472 maxsize = LONG_LONG_TYPE_SIZE;
5473 if (GET_MODE_CLASS (mode) != MODE_INT
5474 || mode < word_mode || GET_MODE_BITSIZE (mode) > maxsize)
5475 return;
5476 gen_libfunc (optable, opname, suffix, mode);
5479 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */
5481 void
5482 gen_fp_libfunc (optab optable, const char *opname, char suffix,
5483 enum machine_mode mode)
5485 char *dec_opname;
5487 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
5488 gen_libfunc (optable, opname, suffix, mode);
5489 if (DECIMAL_FLOAT_MODE_P (mode))
5491 dec_opname = XALLOCAVEC (char, sizeof (DECIMAL_PREFIX) + strlen (opname));
5492 /* For BID support, change the name to have either a bid_ or dpd_ prefix
5493 depending on the low level floating format used. */
5494 memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
5495 strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
5496 gen_libfunc (optable, dec_opname, suffix, mode);
5500 /* Like gen_libfunc, but verify that fixed-point operation is involved. */
5502 void
5503 gen_fixed_libfunc (optab optable, const char *opname, char suffix,
5504 enum machine_mode mode)
5506 if (!ALL_FIXED_POINT_MODE_P (mode))
5507 return;
5508 gen_libfunc (optable, opname, suffix, mode);
5511 /* Like gen_libfunc, but verify that signed fixed-point operation is
5512 involved. */
5514 void
5515 gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
5516 enum machine_mode mode)
5518 if (!SIGNED_FIXED_POINT_MODE_P (mode))
5519 return;
5520 gen_libfunc (optable, opname, suffix, mode);
5523 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
5524 involved. */
5526 void
5527 gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
5528 enum machine_mode mode)
5530 if (!UNSIGNED_FIXED_POINT_MODE_P (mode))
5531 return;
5532 gen_libfunc (optable, opname, suffix, mode);
5535 /* Like gen_libfunc, but verify that FP or INT operation is involved. */
5537 void
5538 gen_int_fp_libfunc (optab optable, const char *name, char suffix,
5539 enum machine_mode mode)
5541 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5542 gen_fp_libfunc (optable, name, suffix, mode);
5543 if (INTEGRAL_MODE_P (mode))
5544 gen_int_libfunc (optable, name, suffix, mode);
5547 /* Like gen_libfunc, but verify that FP or INT operation is involved
5548 and add 'v' suffix for integer operation. */
5550 void
5551 gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
5552 enum machine_mode mode)
5554 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5555 gen_fp_libfunc (optable, name, suffix, mode);
5556 if (GET_MODE_CLASS (mode) == MODE_INT)
5558 int len = strlen (name);
5559 char *v_name = XALLOCAVEC (char, len + 2);
5560 strcpy (v_name, name);
5561 v_name[len] = 'v';
5562 v_name[len + 1] = 0;
5563 gen_int_libfunc (optable, v_name, suffix, mode);
5567 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
5568 involved. */
5570 void
5571 gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
5572 enum machine_mode mode)
5574 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5575 gen_fp_libfunc (optable, name, suffix, mode);
5576 if (INTEGRAL_MODE_P (mode))
5577 gen_int_libfunc (optable, name, suffix, mode);
5578 if (ALL_FIXED_POINT_MODE_P (mode))
5579 gen_fixed_libfunc (optable, name, suffix, mode);
5582 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
5583 involved. */
5585 void
5586 gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5587 enum machine_mode mode)
5589 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5590 gen_fp_libfunc (optable, name, suffix, mode);
5591 if (INTEGRAL_MODE_P (mode))
5592 gen_int_libfunc (optable, name, suffix, mode);
5593 if (SIGNED_FIXED_POINT_MODE_P (mode))
5594 gen_signed_fixed_libfunc (optable, name, suffix, mode);
5597 /* Like gen_libfunc, but verify that INT or FIXED operation is
5598 involved. */
5600 void
5601 gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
5602 enum machine_mode mode)
5604 if (INTEGRAL_MODE_P (mode))
5605 gen_int_libfunc (optable, name, suffix, mode);
5606 if (ALL_FIXED_POINT_MODE_P (mode))
5607 gen_fixed_libfunc (optable, name, suffix, mode);
5610 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
5611 involved. */
5613 void
5614 gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5615 enum machine_mode mode)
5617 if (INTEGRAL_MODE_P (mode))
5618 gen_int_libfunc (optable, name, suffix, mode);
5619 if (SIGNED_FIXED_POINT_MODE_P (mode))
5620 gen_signed_fixed_libfunc (optable, name, suffix, mode);
5623 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
5624 involved. */
5626 void
5627 gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
5628 enum machine_mode mode)
5630 if (INTEGRAL_MODE_P (mode))
5631 gen_int_libfunc (optable, name, suffix, mode);
5632 if (UNSIGNED_FIXED_POINT_MODE_P (mode))
5633 gen_unsigned_fixed_libfunc (optable, name, suffix, mode);
5636 /* Initialize the libfunc fields of an entire group of entries of an
5637 inter-mode-class conversion optab. The string formation rules are
5638 similar to the ones for init_libfuncs, above, but instead of having
5639 a mode name and an operand count these functions have two mode names
5640 and no operand count. */
5642 void
5643 gen_interclass_conv_libfunc (convert_optab tab,
5644 const char *opname,
5645 enum machine_mode tmode,
5646 enum machine_mode fmode)
5648 size_t opname_len = strlen (opname);
5649 size_t mname_len = 0;
5651 const char *fname, *tname;
5652 const char *q;
5653 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5654 char *libfunc_name, *suffix;
5655 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5656 char *p;
5658 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5659 depends on which underlying decimal floating point format is used. */
5660 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5662 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5664 nondec_name = XALLOCAVEC (char, prefix_len + opname_len + mname_len + 1 + 1);
5665 nondec_name[0] = '_';
5666 nondec_name[1] = '_';
5667 if (targetm.libfunc_gnu_prefix)
5669 nondec_name[2] = 'g';
5670 nondec_name[3] = 'n';
5671 nondec_name[4] = 'u';
5672 nondec_name[5] = '_';
5675 memcpy (&nondec_name[prefix_len], opname, opname_len);
5676 nondec_suffix = nondec_name + opname_len + prefix_len;
5678 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
5679 dec_name[0] = '_';
5680 dec_name[1] = '_';
5681 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5682 memcpy (&dec_name[2+dec_len], opname, opname_len);
5683 dec_suffix = dec_name + dec_len + opname_len + 2;
5685 fname = GET_MODE_NAME (fmode);
5686 tname = GET_MODE_NAME (tmode);
5688 if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5690 libfunc_name = dec_name;
5691 suffix = dec_suffix;
5693 else
5695 libfunc_name = nondec_name;
5696 suffix = nondec_suffix;
5699 p = suffix;
5700 for (q = fname; *q; p++, q++)
5701 *p = TOLOWER (*q);
5702 for (q = tname; *q; p++, q++)
5703 *p = TOLOWER (*q);
5705 *p = '\0';
5707 set_conv_libfunc (tab, tmode, fmode,
5708 ggc_alloc_string (libfunc_name, p - libfunc_name));
5711 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5712 int->fp conversion. */
5714 void
5715 gen_int_to_fp_conv_libfunc (convert_optab tab,
5716 const char *opname,
5717 enum machine_mode tmode,
5718 enum machine_mode fmode)
5720 if (GET_MODE_CLASS (fmode) != MODE_INT)
5721 return;
5722 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5723 return;
5724 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5727 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
5728 naming scheme. */
5730 void
5731 gen_ufloat_conv_libfunc (convert_optab tab,
5732 const char *opname ATTRIBUTE_UNUSED,
5733 enum machine_mode tmode,
5734 enum machine_mode fmode)
5736 if (DECIMAL_FLOAT_MODE_P (tmode))
5737 gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode);
5738 else
5739 gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode);
5742 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5743 fp->int conversion. */
5745 void
5746 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
5747 const char *opname,
5748 enum machine_mode tmode,
5749 enum machine_mode fmode)
5751 if (GET_MODE_CLASS (fmode) != MODE_INT)
5752 return;
5753 if (GET_MODE_CLASS (tmode) != MODE_FLOAT)
5754 return;
5755 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5758 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5759 fp->int conversion with no decimal floating point involved. */
5761 void
5762 gen_fp_to_int_conv_libfunc (convert_optab tab,
5763 const char *opname,
5764 enum machine_mode tmode,
5765 enum machine_mode fmode)
5767 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5768 return;
5769 if (GET_MODE_CLASS (tmode) != MODE_INT)
5770 return;
5771 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5774 /* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
5775 The string formation rules are
5776 similar to the ones for init_libfunc, above. */
5778 void
5779 gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
5780 enum machine_mode tmode, enum machine_mode fmode)
5782 size_t opname_len = strlen (opname);
5783 size_t mname_len = 0;
5785 const char *fname, *tname;
5786 const char *q;
5787 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5788 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5789 char *libfunc_name, *suffix;
5790 char *p;
5792 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5793 depends on which underlying decimal floating point format is used. */
5794 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5796 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5798 nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
5799 nondec_name[0] = '_';
5800 nondec_name[1] = '_';
5801 if (targetm.libfunc_gnu_prefix)
5803 nondec_name[2] = 'g';
5804 nondec_name[3] = 'n';
5805 nondec_name[4] = 'u';
5806 nondec_name[5] = '_';
5808 memcpy (&nondec_name[prefix_len], opname, opname_len);
5809 nondec_suffix = nondec_name + opname_len + prefix_len;
5811 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
5812 dec_name[0] = '_';
5813 dec_name[1] = '_';
5814 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5815 memcpy (&dec_name[2 + dec_len], opname, opname_len);
5816 dec_suffix = dec_name + dec_len + opname_len + 2;
5818 fname = GET_MODE_NAME (fmode);
5819 tname = GET_MODE_NAME (tmode);
5821 if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5823 libfunc_name = dec_name;
5824 suffix = dec_suffix;
5826 else
5828 libfunc_name = nondec_name;
5829 suffix = nondec_suffix;
5832 p = suffix;
5833 for (q = fname; *q; p++, q++)
5834 *p = TOLOWER (*q);
5835 for (q = tname; *q; p++, q++)
5836 *p = TOLOWER (*q);
5838 *p++ = '2';
5839 *p = '\0';
5841 set_conv_libfunc (tab, tmode, fmode,
5842 ggc_alloc_string (libfunc_name, p - libfunc_name));
5845 /* Pick proper libcall for trunc_optab. We need to chose if we do
5846 truncation or extension and interclass or intraclass. */
5848 void
5849 gen_trunc_conv_libfunc (convert_optab tab,
5850 const char *opname,
5851 enum machine_mode tmode,
5852 enum machine_mode fmode)
5854 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5855 return;
5856 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5857 return;
5858 if (tmode == fmode)
5859 return;
5861 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
5862 || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
5863 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5865 if (GET_MODE_PRECISION (fmode) <= GET_MODE_PRECISION (tmode))
5866 return;
5868 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
5869 && GET_MODE_CLASS (fmode) == MODE_FLOAT)
5870 || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
5871 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5874 /* Pick proper libcall for extend_optab. We need to chose if we do
5875 truncation or extension and interclass or intraclass. */
5877 void
5878 gen_extend_conv_libfunc (convert_optab tab,
5879 const char *opname ATTRIBUTE_UNUSED,
5880 enum machine_mode tmode,
5881 enum machine_mode fmode)
5883 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5884 return;
5885 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5886 return;
5887 if (tmode == fmode)
5888 return;
5890 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
5891 || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
5892 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5894 if (GET_MODE_PRECISION (fmode) > GET_MODE_PRECISION (tmode))
5895 return;
5897 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
5898 && GET_MODE_CLASS (fmode) == MODE_FLOAT)
5899 || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
5900 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5903 /* Pick proper libcall for fract_optab. We need to chose if we do
5904 interclass or intraclass. */
5906 void
5907 gen_fract_conv_libfunc (convert_optab tab,
5908 const char *opname,
5909 enum machine_mode tmode,
5910 enum machine_mode fmode)
5912 if (tmode == fmode)
5913 return;
5914 if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode)))
5915 return;
5917 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
5918 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5919 else
5920 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5923 /* Pick proper libcall for fractuns_optab. */
5925 void
5926 gen_fractuns_conv_libfunc (convert_optab tab,
5927 const char *opname,
5928 enum machine_mode tmode,
5929 enum machine_mode fmode)
5931 if (tmode == fmode)
5932 return;
5933 /* One mode must be a fixed-point mode, and the other must be an integer
5934 mode. */
5935 if (!((ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT)
5936 || (ALL_FIXED_POINT_MODE_P (fmode)
5937 && GET_MODE_CLASS (tmode) == MODE_INT)))
5938 return;
5940 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5943 /* Pick proper libcall for satfract_optab. We need to chose if we do
5944 interclass or intraclass. */
5946 void
5947 gen_satfract_conv_libfunc (convert_optab tab,
5948 const char *opname,
5949 enum machine_mode tmode,
5950 enum machine_mode fmode)
5952 if (tmode == fmode)
5953 return;
5954 /* TMODE must be a fixed-point mode. */
5955 if (!ALL_FIXED_POINT_MODE_P (tmode))
5956 return;
5958 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
5959 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5960 else
5961 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5964 /* Pick proper libcall for satfractuns_optab. */
5966 void
5967 gen_satfractuns_conv_libfunc (convert_optab tab,
5968 const char *opname,
5969 enum machine_mode tmode,
5970 enum machine_mode fmode)
5972 if (tmode == fmode)
5973 return;
5974 /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
5975 if (!(ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT))
5976 return;
5978 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5981 /* A table of previously-created libfuncs, hashed by name. */
5982 static GTY ((param_is (union tree_node))) htab_t libfunc_decls;
5984 /* Hashtable callbacks for libfunc_decls. */
5986 static hashval_t
5987 libfunc_decl_hash (const void *entry)
5989 return IDENTIFIER_HASH_VALUE (DECL_NAME ((const_tree) entry));
5992 static int
5993 libfunc_decl_eq (const void *entry1, const void *entry2)
5995 return DECL_NAME ((const_tree) entry1) == (const_tree) entry2;
5998 /* Build a decl for a libfunc named NAME. */
6000 tree
6001 build_libfunc_function (const char *name)
6003 tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
6004 get_identifier (name),
6005 build_function_type (integer_type_node, NULL_TREE));
6006 /* ??? We don't have any type information except for this is
6007 a function. Pretend this is "int foo()". */
6008 DECL_ARTIFICIAL (decl) = 1;
6009 DECL_EXTERNAL (decl) = 1;
6010 TREE_PUBLIC (decl) = 1;
6011 gcc_assert (DECL_ASSEMBLER_NAME (decl));
6013 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
6014 are the flags assigned by targetm.encode_section_info. */
6015 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
6017 return decl;
6021 init_one_libfunc (const char *name)
6023 tree id, decl;
6024 void **slot;
6025 hashval_t hash;
6027 if (libfunc_decls == NULL)
6028 libfunc_decls = htab_create_ggc (37, libfunc_decl_hash,
6029 libfunc_decl_eq, NULL);
6031 /* See if we have already created a libfunc decl for this function. */
6032 id = get_identifier (name);
6033 hash = IDENTIFIER_HASH_VALUE (id);
6034 slot = htab_find_slot_with_hash (libfunc_decls, id, hash, INSERT);
6035 decl = (tree) *slot;
6036 if (decl == NULL)
6038 /* Create a new decl, so that it can be passed to
6039 targetm.encode_section_info. */
6040 decl = build_libfunc_function (name);
6041 *slot = decl;
6043 return XEXP (DECL_RTL (decl), 0);
6046 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */
6049 set_user_assembler_libfunc (const char *name, const char *asmspec)
6051 tree id, decl;
6052 void **slot;
6053 hashval_t hash;
6055 id = get_identifier (name);
6056 hash = IDENTIFIER_HASH_VALUE (id);
6057 slot = htab_find_slot_with_hash (libfunc_decls, id, hash, NO_INSERT);
6058 gcc_assert (slot);
6059 decl = (tree) *slot;
6060 set_user_assembler_name (decl, asmspec);
6061 return XEXP (DECL_RTL (decl), 0);
6064 /* Call this to reset the function entry for one optab (OPTABLE) in mode
6065 MODE to NAME, which should be either 0 or a string constant. */
6066 void
6067 set_optab_libfunc (optab op, enum machine_mode mode, const char *name)
6069 rtx val;
6070 struct libfunc_entry e;
6071 struct libfunc_entry **slot;
6073 e.op = op;
6074 e.mode1 = mode;
6075 e.mode2 = VOIDmode;
6077 if (name)
6078 val = init_one_libfunc (name);
6079 else
6080 val = 0;
6081 slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
6082 if (*slot == NULL)
6083 *slot = ggc_alloc_libfunc_entry ();
6084 (*slot)->op = op;
6085 (*slot)->mode1 = mode;
6086 (*slot)->mode2 = VOIDmode;
6087 (*slot)->libfunc = val;
6090 /* Call this to reset the function entry for one conversion optab
6091 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
6092 either 0 or a string constant. */
6093 void
6094 set_conv_libfunc (convert_optab optab, enum machine_mode tmode,
6095 enum machine_mode fmode, const char *name)
6097 rtx val;
6098 struct libfunc_entry e;
6099 struct libfunc_entry **slot;
6101 e.op = optab;
6102 e.mode1 = tmode;
6103 e.mode2 = fmode;
6105 if (name)
6106 val = init_one_libfunc (name);
6107 else
6108 val = 0;
6109 slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
6110 if (*slot == NULL)
6111 *slot = ggc_alloc_libfunc_entry ();
6112 (*slot)->op = optab;
6113 (*slot)->mode1 = tmode;
6114 (*slot)->mode2 = fmode;
6115 (*slot)->libfunc = val;
6118 /* Call this to initialize the contents of the optabs
6119 appropriately for the current target machine. */
6121 void
6122 init_optabs (void)
6124 if (libfunc_hash)
6125 htab_empty (libfunc_hash);
6126 else
6127 libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
6129 /* Fill in the optabs with the insns we support. */
6130 init_all_optabs ();
6132 /* The ffs function operates on `int'. Fall back on it if we do not
6133 have a libgcc2 function for that width. */
6134 if (INT_TYPE_SIZE < BITS_PER_WORD)
6135 set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, MODE_INT, 0),
6136 "ffs");
6138 /* Explicitly initialize the bswap libfuncs since we need them to be
6139 valid for things other than word_mode. */
6140 if (targetm.libfunc_gnu_prefix)
6142 set_optab_libfunc (bswap_optab, SImode, "__gnu_bswapsi2");
6143 set_optab_libfunc (bswap_optab, DImode, "__gnu_bswapdi2");
6145 else
6147 set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
6148 set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
6151 /* Use cabs for double complex abs, since systems generally have cabs.
6152 Don't define any libcall for float complex, so that cabs will be used. */
6153 if (complex_double_type_node)
6154 set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node),
6155 "cabs");
6157 abort_libfunc = init_one_libfunc ("abort");
6158 memcpy_libfunc = init_one_libfunc ("memcpy");
6159 memmove_libfunc = init_one_libfunc ("memmove");
6160 memcmp_libfunc = init_one_libfunc ("memcmp");
6161 memset_libfunc = init_one_libfunc ("memset");
6162 setbits_libfunc = init_one_libfunc ("__setbits");
6164 #ifndef DONT_USE_BUILTIN_SETJMP
6165 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
6166 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
6167 #else
6168 setjmp_libfunc = init_one_libfunc ("setjmp");
6169 longjmp_libfunc = init_one_libfunc ("longjmp");
6170 #endif
6171 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
6172 unwind_sjlj_unregister_libfunc
6173 = init_one_libfunc ("_Unwind_SjLj_Unregister");
6175 /* For function entry/exit instrumentation. */
6176 profile_function_entry_libfunc
6177 = init_one_libfunc ("__cyg_profile_func_enter");
6178 profile_function_exit_libfunc
6179 = init_one_libfunc ("__cyg_profile_func_exit");
6181 gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
6183 /* Allow the target to add more libcalls or rename some, etc. */
6184 targetm.init_libfuncs ();
6187 /* A helper function for init_sync_libfuncs. Using the basename BASE,
6188 install libfuncs into TAB for BASE_N for 1 <= N <= MAX. */
6190 static void
6191 init_sync_libfuncs_1 (optab tab, const char *base, int max)
6193 enum machine_mode mode;
6194 char buf[64];
6195 size_t len = strlen (base);
6196 int i;
6198 gcc_assert (max <= 8);
6199 gcc_assert (len + 3 < sizeof (buf));
6201 memcpy (buf, base, len);
6202 buf[len] = '_';
6203 buf[len + 1] = '0';
6204 buf[len + 2] = '\0';
6206 mode = QImode;
6207 for (i = 1; i <= max; i *= 2)
6209 buf[len + 1] = '0' + i;
6210 set_optab_libfunc (tab, mode, buf);
6211 mode = GET_MODE_2XWIDER_MODE (mode);
6215 void
6216 init_sync_libfuncs (int max)
6218 if (!flag_sync_libcalls)
6219 return;
6221 init_sync_libfuncs_1 (sync_compare_and_swap_optab,
6222 "__sync_val_compare_and_swap", max);
6223 init_sync_libfuncs_1 (sync_lock_test_and_set_optab,
6224 "__sync_lock_test_and_set", max);
6226 init_sync_libfuncs_1 (sync_old_add_optab, "__sync_fetch_and_add", max);
6227 init_sync_libfuncs_1 (sync_old_sub_optab, "__sync_fetch_and_sub", max);
6228 init_sync_libfuncs_1 (sync_old_ior_optab, "__sync_fetch_and_or", max);
6229 init_sync_libfuncs_1 (sync_old_and_optab, "__sync_fetch_and_and", max);
6230 init_sync_libfuncs_1 (sync_old_xor_optab, "__sync_fetch_and_xor", max);
6231 init_sync_libfuncs_1 (sync_old_nand_optab, "__sync_fetch_and_nand", max);
6233 init_sync_libfuncs_1 (sync_new_add_optab, "__sync_add_and_fetch", max);
6234 init_sync_libfuncs_1 (sync_new_sub_optab, "__sync_sub_and_fetch", max);
6235 init_sync_libfuncs_1 (sync_new_ior_optab, "__sync_or_and_fetch", max);
6236 init_sync_libfuncs_1 (sync_new_and_optab, "__sync_and_and_fetch", max);
6237 init_sync_libfuncs_1 (sync_new_xor_optab, "__sync_xor_and_fetch", max);
6238 init_sync_libfuncs_1 (sync_new_nand_optab, "__sync_nand_and_fetch", max);
6241 /* Print information about the current contents of the optabs on
6242 STDERR. */
6244 DEBUG_FUNCTION void
6245 debug_optab_libfuncs (void)
6247 int i, j, k;
6249 /* Dump the arithmetic optabs. */
6250 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
6251 for (j = 0; j < NUM_MACHINE_MODES; ++j)
6253 rtx l = optab_libfunc ((optab) i, (enum machine_mode) j);
6254 if (l)
6256 gcc_assert (GET_CODE (l) == SYMBOL_REF);
6257 fprintf (stderr, "%s\t%s:\t%s\n",
6258 GET_RTX_NAME (optab_to_code ((optab) i)),
6259 GET_MODE_NAME (j),
6260 XSTR (l, 0));
6264 /* Dump the conversion optabs. */
6265 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
6266 for (j = 0; j < NUM_MACHINE_MODES; ++j)
6267 for (k = 0; k < NUM_MACHINE_MODES; ++k)
6269 rtx l = convert_optab_libfunc ((optab) i, (enum machine_mode) j,
6270 (enum machine_mode) k);
6271 if (l)
6273 gcc_assert (GET_CODE (l) == SYMBOL_REF);
6274 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
6275 GET_RTX_NAME (optab_to_code ((optab) i)),
6276 GET_MODE_NAME (j),
6277 GET_MODE_NAME (k),
6278 XSTR (l, 0));
6284 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6285 CODE. Return 0 on failure. */
6288 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
6290 enum machine_mode mode = GET_MODE (op1);
6291 enum insn_code icode;
6292 rtx insn;
6293 rtx trap_rtx;
6295 if (mode == VOIDmode)
6296 return 0;
6298 icode = optab_handler (ctrap_optab, mode);
6299 if (icode == CODE_FOR_nothing)
6300 return 0;
6302 /* Some targets only accept a zero trap code. */
6303 if (!insn_operand_matches (icode, 3, tcode))
6304 return 0;
6306 do_pending_stack_adjust ();
6307 start_sequence ();
6308 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
6309 &trap_rtx, &mode);
6310 if (!trap_rtx)
6311 insn = NULL_RTX;
6312 else
6313 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
6314 tcode);
6316 /* If that failed, then give up. */
6317 if (insn == 0)
6319 end_sequence ();
6320 return 0;
6323 emit_insn (insn);
6324 insn = get_insns ();
6325 end_sequence ();
6326 return insn;
6329 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6330 or unsigned operation code. */
6332 static enum rtx_code
6333 get_rtx_code (enum tree_code tcode, bool unsignedp)
6335 enum rtx_code code;
6336 switch (tcode)
6338 case EQ_EXPR:
6339 code = EQ;
6340 break;
6341 case NE_EXPR:
6342 code = NE;
6343 break;
6344 case LT_EXPR:
6345 code = unsignedp ? LTU : LT;
6346 break;
6347 case LE_EXPR:
6348 code = unsignedp ? LEU : LE;
6349 break;
6350 case GT_EXPR:
6351 code = unsignedp ? GTU : GT;
6352 break;
6353 case GE_EXPR:
6354 code = unsignedp ? GEU : GE;
6355 break;
6357 case UNORDERED_EXPR:
6358 code = UNORDERED;
6359 break;
6360 case ORDERED_EXPR:
6361 code = ORDERED;
6362 break;
6363 case UNLT_EXPR:
6364 code = UNLT;
6365 break;
6366 case UNLE_EXPR:
6367 code = UNLE;
6368 break;
6369 case UNGT_EXPR:
6370 code = UNGT;
6371 break;
6372 case UNGE_EXPR:
6373 code = UNGE;
6374 break;
6375 case UNEQ_EXPR:
6376 code = UNEQ;
6377 break;
6378 case LTGT_EXPR:
6379 code = LTGT;
6380 break;
6382 default:
6383 gcc_unreachable ();
6385 return code;
6388 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6389 unsigned operators. Do not generate compare instruction. */
6391 static rtx
6392 vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
6393 bool unsignedp, enum insn_code icode)
6395 struct expand_operand ops[2];
6396 rtx rtx_op0, rtx_op1;
6397 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
6399 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
6401 /* Expand operands. */
6402 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
6403 EXPAND_STACK_PARM);
6404 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
6405 EXPAND_STACK_PARM);
6407 create_input_operand (&ops[0], rtx_op0, GET_MODE (rtx_op0));
6408 create_input_operand (&ops[1], rtx_op1, GET_MODE (rtx_op1));
6409 if (!maybe_legitimize_operands (icode, 4, 2, ops))
6410 gcc_unreachable ();
6411 return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
6414 /* Return true if VEC_PERM_EXPR can be expanded using SIMD extensions
6415 of the CPU. SEL may be NULL, which stands for an unknown constant. */
6417 bool
6418 can_vec_perm_p (enum machine_mode mode, bool variable,
6419 const unsigned char *sel)
6421 enum machine_mode qimode;
6423 /* If the target doesn't implement a vector mode for the vector type,
6424 then no operations are supported. */
6425 if (!VECTOR_MODE_P (mode))
6426 return false;
6428 if (!variable)
6430 if (direct_optab_handler (vec_perm_const_optab, mode) != CODE_FOR_nothing
6431 && (sel == NULL
6432 || targetm.vectorize.vec_perm_const_ok == NULL
6433 || targetm.vectorize.vec_perm_const_ok (mode, sel)))
6434 return true;
6437 if (direct_optab_handler (vec_perm_optab, mode) != CODE_FOR_nothing)
6438 return true;
6440 /* We allow fallback to a QI vector mode, and adjust the mask. */
6441 if (GET_MODE_INNER (mode) == QImode)
6442 return false;
6443 qimode = mode_for_vector (QImode, GET_MODE_SIZE (mode));
6444 if (!VECTOR_MODE_P (qimode))
6445 return false;
6447 /* ??? For completeness, we ought to check the QImode version of
6448 vec_perm_const_optab. But all users of this implicit lowering
6449 feature implement the variable vec_perm_optab. */
6450 if (direct_optab_handler (vec_perm_optab, qimode) == CODE_FOR_nothing)
6451 return false;
6453 /* In order to support the lowering of variable permutations,
6454 we need to support shifts and adds. */
6455 if (variable)
6457 if (GET_MODE_UNIT_SIZE (mode) > 2
6458 && optab_handler (ashl_optab, mode) == CODE_FOR_nothing
6459 && optab_handler (vashl_optab, mode) == CODE_FOR_nothing)
6460 return false;
6461 if (optab_handler (add_optab, qimode) == CODE_FOR_nothing)
6462 return false;
6465 return true;
6468 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
6470 static rtx
6471 expand_vec_perm_1 (enum insn_code icode, rtx target,
6472 rtx v0, rtx v1, rtx sel)
6474 enum machine_mode tmode = GET_MODE (target);
6475 enum machine_mode smode = GET_MODE (sel);
6476 struct expand_operand ops[4];
6478 create_output_operand (&ops[0], target, tmode);
6479 create_input_operand (&ops[3], sel, smode);
6481 /* Make an effort to preserve v0 == v1. The target expander is able to
6482 rely on this to determine if we're permuting a single input operand. */
6483 if (rtx_equal_p (v0, v1))
6485 if (!insn_operand_matches (icode, 1, v0))
6486 v0 = force_reg (tmode, v0);
6487 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
6488 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
6490 create_fixed_operand (&ops[1], v0);
6491 create_fixed_operand (&ops[2], v0);
6493 else
6495 create_input_operand (&ops[1], v0, tmode);
6496 create_input_operand (&ops[2], v1, tmode);
6499 if (maybe_expand_insn (icode, 4, ops))
6500 return ops[0].value;
6501 return NULL_RTX;
6504 /* Generate instructions for vec_perm optab given its mode
6505 and three operands. */
6508 expand_vec_perm (enum machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
6510 enum insn_code icode;
6511 enum machine_mode qimode;
6512 unsigned int i, w, e, u;
6513 rtx tmp, sel_qi = NULL;
6514 rtvec vec;
6516 if (!target || GET_MODE (target) != mode)
6517 target = gen_reg_rtx (mode);
6519 w = GET_MODE_SIZE (mode);
6520 e = GET_MODE_NUNITS (mode);
6521 u = GET_MODE_UNIT_SIZE (mode);
6523 /* Set QIMODE to a different vector mode with byte elements.
6524 If no such mode, or if MODE already has byte elements, use VOIDmode. */
6525 qimode = VOIDmode;
6526 if (GET_MODE_INNER (mode) != QImode)
6528 qimode = mode_for_vector (QImode, w);
6529 if (!VECTOR_MODE_P (qimode))
6530 qimode = VOIDmode;
6533 /* If the input is a constant, expand it specially. */
6534 gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT);
6535 if (GET_CODE (sel) == CONST_VECTOR)
6537 icode = direct_optab_handler (vec_perm_const_optab, mode);
6538 if (icode != CODE_FOR_nothing)
6540 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
6541 if (tmp)
6542 return tmp;
6545 /* Fall back to a constant byte-based permutation. */
6546 if (qimode != VOIDmode)
6548 vec = rtvec_alloc (w);
6549 for (i = 0; i < e; ++i)
6551 unsigned int j, this_e;
6553 this_e = INTVAL (CONST_VECTOR_ELT (sel, i));
6554 this_e &= 2 * e - 1;
6555 this_e *= u;
6557 for (j = 0; j < u; ++j)
6558 RTVEC_ELT (vec, i * u + j) = GEN_INT (this_e + j);
6560 sel_qi = gen_rtx_CONST_VECTOR (qimode, vec);
6562 icode = direct_optab_handler (vec_perm_const_optab, qimode);
6563 if (icode != CODE_FOR_nothing)
6565 tmp = expand_vec_perm_1 (icode, gen_lowpart (qimode, target),
6566 gen_lowpart (qimode, v0),
6567 gen_lowpart (qimode, v1), sel_qi);
6568 if (tmp)
6569 return gen_lowpart (mode, tmp);
6574 /* Otherwise expand as a fully variable permuation. */
6575 icode = direct_optab_handler (vec_perm_optab, mode);
6576 if (icode != CODE_FOR_nothing)
6578 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
6579 if (tmp)
6580 return tmp;
6583 /* As a special case to aid several targets, lower the element-based
6584 permutation to a byte-based permutation and try again. */
6585 if (qimode == VOIDmode)
6586 return NULL_RTX;
6587 icode = direct_optab_handler (vec_perm_optab, qimode);
6588 if (icode == CODE_FOR_nothing)
6589 return NULL_RTX;
6591 if (sel_qi == NULL)
6593 /* Multiply each element by its byte size. */
6594 enum machine_mode selmode = GET_MODE (sel);
6595 if (u == 2)
6596 sel = expand_simple_binop (selmode, PLUS, sel, sel,
6597 sel, 0, OPTAB_DIRECT);
6598 else
6599 sel = expand_simple_binop (selmode, ASHIFT, sel,
6600 GEN_INT (exact_log2 (u)),
6601 sel, 0, OPTAB_DIRECT);
6602 gcc_assert (sel != NULL);
6604 /* Broadcast the low byte each element into each of its bytes. */
6605 vec = rtvec_alloc (w);
6606 for (i = 0; i < w; ++i)
6608 int this_e = i / u * u;
6609 if (BYTES_BIG_ENDIAN)
6610 this_e += u - 1;
6611 RTVEC_ELT (vec, i) = GEN_INT (this_e);
6613 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
6614 sel = gen_lowpart (qimode, sel);
6615 sel = expand_vec_perm (qimode, sel, sel, tmp, NULL);
6616 gcc_assert (sel != NULL);
6618 /* Add the byte offset to each byte element. */
6619 /* Note that the definition of the indicies here is memory ordering,
6620 so there should be no difference between big and little endian. */
6621 vec = rtvec_alloc (w);
6622 for (i = 0; i < w; ++i)
6623 RTVEC_ELT (vec, i) = GEN_INT (i % u);
6624 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
6625 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
6626 sel, 0, OPTAB_DIRECT);
6627 gcc_assert (sel_qi != NULL);
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 tmp = gen_lowpart (mode, tmp);
6635 return tmp;
6638 /* Return insn code for a conditional operator with a comparison in
6639 mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE. */
6641 static inline enum insn_code
6642 get_vcond_icode (enum machine_mode vmode, enum machine_mode cmode, bool uns)
6644 enum insn_code icode = CODE_FOR_nothing;
6645 if (uns)
6646 icode = convert_optab_handler (vcondu_optab, vmode, cmode);
6647 else
6648 icode = convert_optab_handler (vcond_optab, vmode, cmode);
6649 return icode;
6652 /* Return TRUE iff, appropriate vector insns are available
6653 for vector cond expr with vector type VALUE_TYPE and a comparison
6654 with operand vector types in CMP_OP_TYPE. */
6656 bool
6657 expand_vec_cond_expr_p (tree value_type, tree cmp_op_type)
6659 enum machine_mode value_mode = TYPE_MODE (value_type);
6660 enum machine_mode cmp_op_mode = TYPE_MODE (cmp_op_type);
6661 if (GET_MODE_SIZE (value_mode) != GET_MODE_SIZE (cmp_op_mode)
6662 || GET_MODE_NUNITS (value_mode) != GET_MODE_NUNITS (cmp_op_mode)
6663 || get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type),
6664 TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing)
6665 return false;
6666 return true;
6669 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
6670 three operands. */
6673 expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
6674 rtx target)
6676 struct expand_operand ops[6];
6677 enum insn_code icode;
6678 rtx comparison, rtx_op1, rtx_op2;
6679 enum machine_mode mode = TYPE_MODE (vec_cond_type);
6680 enum machine_mode cmp_op_mode;
6681 bool unsignedp;
6682 tree op0a, op0b;
6683 enum tree_code tcode;
6685 if (COMPARISON_CLASS_P (op0))
6687 op0a = TREE_OPERAND (op0, 0);
6688 op0b = TREE_OPERAND (op0, 1);
6689 tcode = TREE_CODE (op0);
6691 else
6693 /* Fake op0 < 0. */
6694 gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (op0)));
6695 op0a = op0;
6696 op0b = build_zero_cst (TREE_TYPE (op0));
6697 tcode = LT_EXPR;
6699 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
6700 cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
6703 gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
6704 && GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
6706 icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
6707 if (icode == CODE_FOR_nothing)
6708 return 0;
6710 comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode);
6711 rtx_op1 = expand_normal (op1);
6712 rtx_op2 = expand_normal (op2);
6714 create_output_operand (&ops[0], target, mode);
6715 create_input_operand (&ops[1], rtx_op1, mode);
6716 create_input_operand (&ops[2], rtx_op2, mode);
6717 create_fixed_operand (&ops[3], comparison);
6718 create_fixed_operand (&ops[4], XEXP (comparison, 0));
6719 create_fixed_operand (&ops[5], XEXP (comparison, 1));
6720 expand_insn (icode, 6, ops);
6721 return ops[0].value;
6724 /* Return non-zero if a highpart multiply is supported of can be synthisized.
6725 For the benefit of expand_mult_highpart, the return value is 1 for direct,
6726 2 for even/odd widening, and 3 for hi/lo widening. */
6729 can_mult_highpart_p (enum machine_mode mode, bool uns_p)
6731 optab op;
6732 unsigned char *sel;
6733 unsigned i, nunits;
6735 op = uns_p ? umul_highpart_optab : smul_highpart_optab;
6736 if (optab_handler (op, mode) != CODE_FOR_nothing)
6737 return 1;
6739 /* If the mode is an integral vector, synth from widening operations. */
6740 if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
6741 return 0;
6743 nunits = GET_MODE_NUNITS (mode);
6744 sel = XALLOCAVEC (unsigned char, nunits);
6746 op = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
6747 if (optab_handler (op, mode) != CODE_FOR_nothing)
6749 op = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
6750 if (optab_handler (op, mode) != CODE_FOR_nothing)
6752 for (i = 0; i < nunits; ++i)
6753 sel[i] = !BYTES_BIG_ENDIAN + (i & ~1) + ((i & 1) ? nunits : 0);
6754 if (can_vec_perm_p (mode, false, sel))
6755 return 2;
6759 op = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
6760 if (optab_handler (op, mode) != CODE_FOR_nothing)
6762 op = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
6763 if (optab_handler (op, mode) != CODE_FOR_nothing)
6765 for (i = 0; i < nunits; ++i)
6766 sel[i] = 2 * i + (BYTES_BIG_ENDIAN ? 0 : 1);
6767 if (can_vec_perm_p (mode, false, sel))
6768 return 3;
6772 return 0;
6775 /* Expand a highpart multiply. */
6778 expand_mult_highpart (enum machine_mode mode, rtx op0, rtx op1,
6779 rtx target, bool uns_p)
6781 struct expand_operand eops[3];
6782 enum insn_code icode;
6783 int method, i, nunits;
6784 enum machine_mode wmode;
6785 rtx m1, m2, perm;
6786 optab tab1, tab2;
6787 rtvec v;
6789 method = can_mult_highpart_p (mode, uns_p);
6790 switch (method)
6792 case 0:
6793 return NULL_RTX;
6794 case 1:
6795 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
6796 return expand_binop (mode, tab1, op0, op1, target, uns_p,
6797 OPTAB_LIB_WIDEN);
6798 case 2:
6799 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
6800 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
6801 break;
6802 case 3:
6803 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
6804 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
6805 if (BYTES_BIG_ENDIAN)
6807 optab t = tab1;
6808 tab1 = tab2;
6809 tab2 = t;
6811 break;
6812 default:
6813 gcc_unreachable ();
6816 icode = optab_handler (tab1, mode);
6817 nunits = GET_MODE_NUNITS (mode);
6818 wmode = insn_data[icode].operand[0].mode;
6819 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode) == nunits);
6820 gcc_checking_assert (GET_MODE_SIZE (wmode) == GET_MODE_SIZE (mode));
6822 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
6823 create_input_operand (&eops[1], op0, mode);
6824 create_input_operand (&eops[2], op1, mode);
6825 expand_insn (icode, 3, eops);
6826 m1 = gen_lowpart (mode, eops[0].value);
6828 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
6829 create_input_operand (&eops[1], op0, mode);
6830 create_input_operand (&eops[2], op1, mode);
6831 expand_insn (optab_handler (tab2, mode), 3, eops);
6832 m2 = gen_lowpart (mode, eops[0].value);
6834 v = rtvec_alloc (nunits);
6835 if (method == 2)
6837 for (i = 0; i < nunits; ++i)
6838 RTVEC_ELT (v, i) = GEN_INT (!BYTES_BIG_ENDIAN + (i & ~1)
6839 + ((i & 1) ? nunits : 0));
6841 else
6843 for (i = 0; i < nunits; ++i)
6844 RTVEC_ELT (v, i) = GEN_INT (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
6846 perm = gen_rtx_CONST_VECTOR (mode, v);
6848 return expand_vec_perm (mode, m1, m2, perm, target);
6851 /* Return true if there is a compare_and_swap pattern. */
6853 bool
6854 can_compare_and_swap_p (enum machine_mode mode, bool allow_libcall)
6856 enum insn_code icode;
6858 /* Check for __atomic_compare_and_swap. */
6859 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
6860 if (icode != CODE_FOR_nothing)
6861 return true;
6863 /* Check for __sync_compare_and_swap. */
6864 icode = optab_handler (sync_compare_and_swap_optab, mode);
6865 if (icode != CODE_FOR_nothing)
6866 return true;
6867 if (allow_libcall && optab_libfunc (sync_compare_and_swap_optab, mode))
6868 return true;
6870 /* No inline compare and swap. */
6871 return false;
6874 /* Return true if an atomic exchange can be performed. */
6876 bool
6877 can_atomic_exchange_p (enum machine_mode mode, bool allow_libcall)
6879 enum insn_code icode;
6881 /* Check for __atomic_exchange. */
6882 icode = direct_optab_handler (atomic_exchange_optab, mode);
6883 if (icode != CODE_FOR_nothing)
6884 return true;
6886 /* Don't check __sync_test_and_set, as on some platforms that
6887 has reduced functionality. Targets that really do support
6888 a proper exchange should simply be updated to the __atomics. */
6890 return can_compare_and_swap_p (mode, allow_libcall);
6894 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
6895 pattern. */
6897 static void
6898 find_cc_set (rtx x, const_rtx pat, void *data)
6900 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
6901 && GET_CODE (pat) == SET)
6903 rtx *p_cc_reg = (rtx *) data;
6904 gcc_assert (!*p_cc_reg);
6905 *p_cc_reg = x;
6909 /* This is a helper function for the other atomic operations. This function
6910 emits a loop that contains SEQ that iterates until a compare-and-swap
6911 operation at the end succeeds. MEM is the memory to be modified. SEQ is
6912 a set of instructions that takes a value from OLD_REG as an input and
6913 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
6914 set to the current contents of MEM. After SEQ, a compare-and-swap will
6915 attempt to update MEM with NEW_REG. The function returns true when the
6916 loop was generated successfully. */
6918 static bool
6919 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
6921 enum machine_mode mode = GET_MODE (mem);
6922 rtx label, cmp_reg, success, oldval;
6924 /* The loop we want to generate looks like
6926 cmp_reg = mem;
6927 label:
6928 old_reg = cmp_reg;
6929 seq;
6930 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
6931 if (success)
6932 goto label;
6934 Note that we only do the plain load from memory once. Subsequent
6935 iterations use the value loaded by the compare-and-swap pattern. */
6937 label = gen_label_rtx ();
6938 cmp_reg = gen_reg_rtx (mode);
6940 emit_move_insn (cmp_reg, mem);
6941 emit_label (label);
6942 emit_move_insn (old_reg, cmp_reg);
6943 if (seq)
6944 emit_insn (seq);
6946 success = NULL_RTX;
6947 oldval = cmp_reg;
6948 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
6949 new_reg, false, MEMMODEL_SEQ_CST,
6950 MEMMODEL_RELAXED))
6951 return false;
6953 if (oldval != cmp_reg)
6954 emit_move_insn (cmp_reg, oldval);
6956 /* Mark this jump predicted not taken. */
6957 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
6958 GET_MODE (success), 1, label, 0);
6959 return true;
6963 /* This function tries to emit an atomic_exchange intruction. VAL is written
6964 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
6965 using TARGET if possible. */
6967 static rtx
6968 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6970 enum machine_mode mode = GET_MODE (mem);
6971 enum insn_code icode;
6973 /* If the target supports the exchange directly, great. */
6974 icode = direct_optab_handler (atomic_exchange_optab, mode);
6975 if (icode != CODE_FOR_nothing)
6977 struct expand_operand ops[4];
6979 create_output_operand (&ops[0], target, mode);
6980 create_fixed_operand (&ops[1], mem);
6981 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6982 create_convert_operand_to (&ops[2], val, mode, true);
6983 create_integer_operand (&ops[3], model);
6984 if (maybe_expand_insn (icode, 4, ops))
6985 return ops[0].value;
6988 return NULL_RTX;
6991 /* This function tries to implement an atomic exchange operation using
6992 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
6993 The previous contents of *MEM are returned, using TARGET if possible.
6994 Since this instructionn is an acquire barrier only, stronger memory
6995 models may require additional barriers to be emitted. */
6997 static rtx
6998 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
6999 enum memmodel model)
7001 enum machine_mode mode = GET_MODE (mem);
7002 enum insn_code icode;
7003 rtx last_insn = get_last_insn ();
7005 icode = optab_handler (sync_lock_test_and_set_optab, mode);
7007 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
7008 exists, and the memory model is stronger than acquire, add a release
7009 barrier before the instruction. */
7011 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST
7012 || (model & MEMMODEL_MASK) == MEMMODEL_RELEASE
7013 || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
7014 expand_mem_thread_fence (model);
7016 if (icode != CODE_FOR_nothing)
7018 struct expand_operand ops[3];
7019 create_output_operand (&ops[0], target, mode);
7020 create_fixed_operand (&ops[1], mem);
7021 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7022 create_convert_operand_to (&ops[2], val, mode, true);
7023 if (maybe_expand_insn (icode, 3, ops))
7024 return ops[0].value;
7027 /* If an external test-and-set libcall is provided, use that instead of
7028 any external compare-and-swap that we might get from the compare-and-
7029 swap-loop expansion later. */
7030 if (!can_compare_and_swap_p (mode, false))
7032 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
7033 if (libfunc != NULL)
7035 rtx addr;
7037 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7038 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
7039 mode, 2, addr, ptr_mode,
7040 val, mode);
7044 /* If the test_and_set can't be emitted, eliminate any barrier that might
7045 have been emitted. */
7046 delete_insns_since (last_insn);
7047 return NULL_RTX;
7050 /* This function tries to implement an atomic exchange operation using a
7051 compare_and_swap loop. VAL is written to *MEM. The previous contents of
7052 *MEM are returned, using TARGET if possible. No memory model is required
7053 since a compare_and_swap loop is seq-cst. */
7055 static rtx
7056 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
7058 enum machine_mode mode = GET_MODE (mem);
7060 if (can_compare_and_swap_p (mode, true))
7062 if (!target || !register_operand (target, mode))
7063 target = gen_reg_rtx (mode);
7064 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7065 val = convert_modes (mode, GET_MODE (val), val, 1);
7066 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
7067 return target;
7070 return NULL_RTX;
7073 /* This function tries to implement an atomic test-and-set operation
7074 using the atomic_test_and_set instruction pattern. A boolean value
7075 is returned from the operation, using TARGET if possible. */
7077 #ifndef HAVE_atomic_test_and_set
7078 #define HAVE_atomic_test_and_set 0
7079 #define CODE_FOR_atomic_test_and_set CODE_FOR_nothing
7080 #endif
7082 static rtx
7083 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
7085 enum machine_mode pat_bool_mode;
7086 struct expand_operand ops[3];
7088 if (!HAVE_atomic_test_and_set)
7089 return NULL_RTX;
7091 /* While we always get QImode from __atomic_test_and_set, we get
7092 other memory modes from __sync_lock_test_and_set. Note that we
7093 use no endian adjustment here. This matches the 4.6 behavior
7094 in the Sparc backend. */
7095 gcc_checking_assert
7096 (insn_data[CODE_FOR_atomic_test_and_set].operand[1].mode == QImode);
7097 if (GET_MODE (mem) != QImode)
7098 mem = adjust_address_nv (mem, QImode, 0);
7100 pat_bool_mode = insn_data[CODE_FOR_atomic_test_and_set].operand[0].mode;
7101 create_output_operand (&ops[0], target, pat_bool_mode);
7102 create_fixed_operand (&ops[1], mem);
7103 create_integer_operand (&ops[2], model);
7105 if (maybe_expand_insn (CODE_FOR_atomic_test_and_set, 3, ops))
7106 return ops[0].value;
7107 return NULL_RTX;
7110 /* This function expands the legacy _sync_lock test_and_set operation which is
7111 generally an atomic exchange. Some limited targets only allow the
7112 constant 1 to be stored. This is an ACQUIRE operation.
7114 TARGET is an optional place to stick the return value.
7115 MEM is where VAL is stored. */
7118 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
7120 rtx ret;
7122 /* Try an atomic_exchange first. */
7123 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_ACQUIRE);
7124 if (ret)
7125 return ret;
7127 ret = maybe_emit_sync_lock_test_and_set (target, mem, val, MEMMODEL_ACQUIRE);
7128 if (ret)
7129 return ret;
7131 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
7132 if (ret)
7133 return ret;
7135 /* If there are no other options, try atomic_test_and_set if the value
7136 being stored is 1. */
7137 if (val == const1_rtx)
7138 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_ACQUIRE);
7140 return ret;
7143 /* This function expands the atomic test_and_set operation:
7144 atomically store a boolean TRUE into MEM and return the previous value.
7146 MEMMODEL is the memory model variant to use.
7147 TARGET is an optional place to stick the return value. */
7150 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
7152 enum machine_mode mode = GET_MODE (mem);
7153 rtx ret, trueval, subtarget;
7155 ret = maybe_emit_atomic_test_and_set (target, mem, model);
7156 if (ret)
7157 return ret;
7159 /* Be binary compatible with non-default settings of trueval, and different
7160 cpu revisions. E.g. one revision may have atomic-test-and-set, but
7161 another only has atomic-exchange. */
7162 if (targetm.atomic_test_and_set_trueval == 1)
7164 trueval = const1_rtx;
7165 subtarget = target ? target : gen_reg_rtx (mode);
7167 else
7169 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
7170 subtarget = gen_reg_rtx (mode);
7173 /* Try the atomic-exchange optab... */
7174 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
7176 /* ... then an atomic-compare-and-swap loop ... */
7177 if (!ret)
7178 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
7180 /* ... before trying the vaguely defined legacy lock_test_and_set. */
7181 if (!ret)
7182 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
7184 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
7185 things with the value 1. Thus we try again without trueval. */
7186 if (!ret && targetm.atomic_test_and_set_trueval != 1)
7187 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
7189 /* Failing all else, assume a single threaded environment and simply
7190 perform the operation. */
7191 if (!ret)
7193 emit_move_insn (subtarget, mem);
7194 emit_move_insn (mem, trueval);
7195 ret = subtarget;
7198 /* Recall that have to return a boolean value; rectify if trueval
7199 is not exactly one. */
7200 if (targetm.atomic_test_and_set_trueval != 1)
7201 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
7203 return ret;
7206 /* This function expands the atomic exchange operation:
7207 atomically store VAL in MEM and return the previous value in MEM.
7209 MEMMODEL is the memory model variant to use.
7210 TARGET is an optional place to stick the return value. */
7213 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
7215 rtx ret;
7217 ret = maybe_emit_atomic_exchange (target, mem, val, model);
7219 /* Next try a compare-and-swap loop for the exchange. */
7220 if (!ret)
7221 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
7223 return ret;
7226 /* This function expands the atomic compare exchange operation:
7228 *PTARGET_BOOL is an optional place to store the boolean success/failure.
7229 *PTARGET_OVAL is an optional place to store the old value from memory.
7230 Both target parameters may be NULL to indicate that we do not care about
7231 that return value. Both target parameters are updated on success to
7232 the actual location of the corresponding result.
7234 MEMMODEL is the memory model variant to use.
7236 The return value of the function is true for success. */
7238 bool
7239 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
7240 rtx mem, rtx expected, rtx desired,
7241 bool is_weak, enum memmodel succ_model,
7242 enum memmodel fail_model)
7244 enum machine_mode mode = GET_MODE (mem);
7245 struct expand_operand ops[8];
7246 enum insn_code icode;
7247 rtx target_oval, target_bool = NULL_RTX;
7248 rtx libfunc;
7250 /* Load expected into a register for the compare and swap. */
7251 if (MEM_P (expected))
7252 expected = copy_to_reg (expected);
7254 /* Make sure we always have some place to put the return oldval.
7255 Further, make sure that place is distinct from the input expected,
7256 just in case we need that path down below. */
7257 if (ptarget_oval == NULL
7258 || (target_oval = *ptarget_oval) == NULL
7259 || reg_overlap_mentioned_p (expected, target_oval))
7260 target_oval = gen_reg_rtx (mode);
7262 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
7263 if (icode != CODE_FOR_nothing)
7265 enum machine_mode bool_mode = insn_data[icode].operand[0].mode;
7267 /* Make sure we always have a place for the bool operand. */
7268 if (ptarget_bool == NULL
7269 || (target_bool = *ptarget_bool) == NULL
7270 || GET_MODE (target_bool) != bool_mode)
7271 target_bool = gen_reg_rtx (bool_mode);
7273 /* Emit the compare_and_swap. */
7274 create_output_operand (&ops[0], target_bool, bool_mode);
7275 create_output_operand (&ops[1], target_oval, mode);
7276 create_fixed_operand (&ops[2], mem);
7277 create_convert_operand_to (&ops[3], expected, mode, true);
7278 create_convert_operand_to (&ops[4], desired, mode, true);
7279 create_integer_operand (&ops[5], is_weak);
7280 create_integer_operand (&ops[6], succ_model);
7281 create_integer_operand (&ops[7], fail_model);
7282 expand_insn (icode, 8, ops);
7284 /* Return success/failure. */
7285 target_bool = ops[0].value;
7286 target_oval = ops[1].value;
7287 goto success;
7290 /* Otherwise fall back to the original __sync_val_compare_and_swap
7291 which is always seq-cst. */
7292 icode = optab_handler (sync_compare_and_swap_optab, mode);
7293 if (icode != CODE_FOR_nothing)
7295 rtx cc_reg;
7297 create_output_operand (&ops[0], target_oval, mode);
7298 create_fixed_operand (&ops[1], mem);
7299 create_convert_operand_to (&ops[2], expected, mode, true);
7300 create_convert_operand_to (&ops[3], desired, mode, true);
7301 if (!maybe_expand_insn (icode, 4, ops))
7302 return false;
7304 target_oval = ops[0].value;
7306 /* If the caller isn't interested in the boolean return value,
7307 skip the computation of it. */
7308 if (ptarget_bool == NULL)
7309 goto success;
7311 /* Otherwise, work out if the compare-and-swap succeeded. */
7312 cc_reg = NULL_RTX;
7313 if (have_insn_for (COMPARE, CCmode))
7314 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
7315 if (cc_reg)
7317 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
7318 const0_rtx, VOIDmode, 0, 1);
7319 goto success;
7321 goto success_bool_from_val;
7324 /* Also check for library support for __sync_val_compare_and_swap. */
7325 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
7326 if (libfunc != NULL)
7328 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7329 target_oval = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
7330 mode, 3, addr, ptr_mode,
7331 expected, mode, desired, mode);
7333 /* Compute the boolean return value only if requested. */
7334 if (ptarget_bool)
7335 goto success_bool_from_val;
7336 else
7337 goto success;
7340 /* Failure. */
7341 return false;
7343 success_bool_from_val:
7344 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
7345 expected, VOIDmode, 1, 1);
7346 success:
7347 /* Make sure that the oval output winds up where the caller asked. */
7348 if (ptarget_oval)
7349 *ptarget_oval = target_oval;
7350 if (ptarget_bool)
7351 *ptarget_bool = target_bool;
7352 return true;
7355 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
7357 static void
7358 expand_asm_memory_barrier (void)
7360 rtx asm_op, clob;
7362 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, empty_string, empty_string, 0,
7363 rtvec_alloc (0), rtvec_alloc (0),
7364 rtvec_alloc (0), UNKNOWN_LOCATION);
7365 MEM_VOLATILE_P (asm_op) = 1;
7367 clob = gen_rtx_SCRATCH (VOIDmode);
7368 clob = gen_rtx_MEM (BLKmode, clob);
7369 clob = gen_rtx_CLOBBER (VOIDmode, clob);
7371 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
7374 /* This routine will either emit the mem_thread_fence pattern or issue a
7375 sync_synchronize to generate a fence for memory model MEMMODEL. */
7377 #ifndef HAVE_mem_thread_fence
7378 # define HAVE_mem_thread_fence 0
7379 # define gen_mem_thread_fence(x) (gcc_unreachable (), NULL_RTX)
7380 #endif
7381 #ifndef HAVE_memory_barrier
7382 # define HAVE_memory_barrier 0
7383 # define gen_memory_barrier() (gcc_unreachable (), NULL_RTX)
7384 #endif
7386 void
7387 expand_mem_thread_fence (enum memmodel model)
7389 if (HAVE_mem_thread_fence)
7390 emit_insn (gen_mem_thread_fence (GEN_INT (model)));
7391 else if ((model & MEMMODEL_MASK) != MEMMODEL_RELAXED)
7393 if (HAVE_memory_barrier)
7394 emit_insn (gen_memory_barrier ());
7395 else if (synchronize_libfunc != NULL_RTX)
7396 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
7397 else
7398 expand_asm_memory_barrier ();
7402 /* This routine will either emit the mem_signal_fence pattern or issue a
7403 sync_synchronize to generate a fence for memory model MEMMODEL. */
7405 #ifndef HAVE_mem_signal_fence
7406 # define HAVE_mem_signal_fence 0
7407 # define gen_mem_signal_fence(x) (gcc_unreachable (), NULL_RTX)
7408 #endif
7410 void
7411 expand_mem_signal_fence (enum memmodel model)
7413 if (HAVE_mem_signal_fence)
7414 emit_insn (gen_mem_signal_fence (GEN_INT (model)));
7415 else if ((model & MEMMODEL_MASK) != MEMMODEL_RELAXED)
7417 /* By default targets are coherent between a thread and the signal
7418 handler running on the same thread. Thus this really becomes a
7419 compiler barrier, in that stores must not be sunk past
7420 (or raised above) a given point. */
7421 expand_asm_memory_barrier ();
7425 /* This function expands the atomic load operation:
7426 return the atomically loaded value in MEM.
7428 MEMMODEL is the memory model variant to use.
7429 TARGET is an option place to stick the return value. */
7432 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
7434 enum machine_mode mode = GET_MODE (mem);
7435 enum insn_code icode;
7437 /* If the target supports the load directly, great. */
7438 icode = direct_optab_handler (atomic_load_optab, mode);
7439 if (icode != CODE_FOR_nothing)
7441 struct expand_operand ops[3];
7443 create_output_operand (&ops[0], target, mode);
7444 create_fixed_operand (&ops[1], mem);
7445 create_integer_operand (&ops[2], model);
7446 if (maybe_expand_insn (icode, 3, ops))
7447 return ops[0].value;
7450 /* If the size of the object is greater than word size on this target,
7451 then we assume that a load will not be atomic. */
7452 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
7454 /* Issue val = compare_and_swap (mem, 0, 0).
7455 This may cause the occasional harmless store of 0 when the value is
7456 already 0, but it seems to be OK according to the standards guys. */
7457 if (expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
7458 const0_rtx, false, model, model))
7459 return target;
7460 else
7461 /* Otherwise there is no atomic load, leave the library call. */
7462 return NULL_RTX;
7465 /* Otherwise assume loads are atomic, and emit the proper barriers. */
7466 if (!target || target == const0_rtx)
7467 target = gen_reg_rtx (mode);
7469 /* For SEQ_CST, emit a barrier before the load. */
7470 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST)
7471 expand_mem_thread_fence (model);
7473 emit_move_insn (target, mem);
7475 /* Emit the appropriate barrier after the load. */
7476 expand_mem_thread_fence (model);
7478 return target;
7481 /* This function expands the atomic store operation:
7482 Atomically store VAL in MEM.
7483 MEMMODEL is the memory model variant to use.
7484 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
7485 function returns const0_rtx if a pattern was emitted. */
7488 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
7490 enum machine_mode mode = GET_MODE (mem);
7491 enum insn_code icode;
7492 struct expand_operand ops[3];
7494 /* If the target supports the store directly, great. */
7495 icode = direct_optab_handler (atomic_store_optab, mode);
7496 if (icode != CODE_FOR_nothing)
7498 create_fixed_operand (&ops[0], mem);
7499 create_input_operand (&ops[1], val, mode);
7500 create_integer_operand (&ops[2], model);
7501 if (maybe_expand_insn (icode, 3, ops))
7502 return const0_rtx;
7505 /* If using __sync_lock_release is a viable alternative, try it. */
7506 if (use_release)
7508 icode = direct_optab_handler (sync_lock_release_optab, mode);
7509 if (icode != CODE_FOR_nothing)
7511 create_fixed_operand (&ops[0], mem);
7512 create_input_operand (&ops[1], const0_rtx, mode);
7513 if (maybe_expand_insn (icode, 2, ops))
7515 /* lock_release is only a release barrier. */
7516 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST)
7517 expand_mem_thread_fence (model);
7518 return const0_rtx;
7523 /* If the size of the object is greater than word size on this target,
7524 a default store will not be atomic, Try a mem_exchange and throw away
7525 the result. If that doesn't work, don't do anything. */
7526 if (GET_MODE_PRECISION(mode) > BITS_PER_WORD)
7528 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
7529 if (!target)
7530 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val);
7531 if (target)
7532 return const0_rtx;
7533 else
7534 return NULL_RTX;
7537 /* Otherwise assume stores are atomic, and emit the proper barriers. */
7538 expand_mem_thread_fence (model);
7540 emit_move_insn (mem, val);
7542 /* For SEQ_CST, also emit a barrier after the store. */
7543 if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST)
7544 expand_mem_thread_fence (model);
7546 return const0_rtx;
7550 /* Structure containing the pointers and values required to process the
7551 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
7553 struct atomic_op_functions
7555 direct_optab mem_fetch_before;
7556 direct_optab mem_fetch_after;
7557 direct_optab mem_no_result;
7558 optab fetch_before;
7559 optab fetch_after;
7560 direct_optab no_result;
7561 enum rtx_code reverse_code;
7565 /* Fill in structure pointed to by OP with the various optab entries for an
7566 operation of type CODE. */
7568 static void
7569 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
7571 gcc_assert (op!= NULL);
7573 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
7574 in the source code during compilation, and the optab entries are not
7575 computable until runtime. Fill in the values at runtime. */
7576 switch (code)
7578 case PLUS:
7579 op->mem_fetch_before = atomic_fetch_add_optab;
7580 op->mem_fetch_after = atomic_add_fetch_optab;
7581 op->mem_no_result = atomic_add_optab;
7582 op->fetch_before = sync_old_add_optab;
7583 op->fetch_after = sync_new_add_optab;
7584 op->no_result = sync_add_optab;
7585 op->reverse_code = MINUS;
7586 break;
7587 case MINUS:
7588 op->mem_fetch_before = atomic_fetch_sub_optab;
7589 op->mem_fetch_after = atomic_sub_fetch_optab;
7590 op->mem_no_result = atomic_sub_optab;
7591 op->fetch_before = sync_old_sub_optab;
7592 op->fetch_after = sync_new_sub_optab;
7593 op->no_result = sync_sub_optab;
7594 op->reverse_code = PLUS;
7595 break;
7596 case XOR:
7597 op->mem_fetch_before = atomic_fetch_xor_optab;
7598 op->mem_fetch_after = atomic_xor_fetch_optab;
7599 op->mem_no_result = atomic_xor_optab;
7600 op->fetch_before = sync_old_xor_optab;
7601 op->fetch_after = sync_new_xor_optab;
7602 op->no_result = sync_xor_optab;
7603 op->reverse_code = XOR;
7604 break;
7605 case AND:
7606 op->mem_fetch_before = atomic_fetch_and_optab;
7607 op->mem_fetch_after = atomic_and_fetch_optab;
7608 op->mem_no_result = atomic_and_optab;
7609 op->fetch_before = sync_old_and_optab;
7610 op->fetch_after = sync_new_and_optab;
7611 op->no_result = sync_and_optab;
7612 op->reverse_code = UNKNOWN;
7613 break;
7614 case IOR:
7615 op->mem_fetch_before = atomic_fetch_or_optab;
7616 op->mem_fetch_after = atomic_or_fetch_optab;
7617 op->mem_no_result = atomic_or_optab;
7618 op->fetch_before = sync_old_ior_optab;
7619 op->fetch_after = sync_new_ior_optab;
7620 op->no_result = sync_ior_optab;
7621 op->reverse_code = UNKNOWN;
7622 break;
7623 case NOT:
7624 op->mem_fetch_before = atomic_fetch_nand_optab;
7625 op->mem_fetch_after = atomic_nand_fetch_optab;
7626 op->mem_no_result = atomic_nand_optab;
7627 op->fetch_before = sync_old_nand_optab;
7628 op->fetch_after = sync_new_nand_optab;
7629 op->no_result = sync_nand_optab;
7630 op->reverse_code = UNKNOWN;
7631 break;
7632 default:
7633 gcc_unreachable ();
7637 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
7638 using memory order MODEL. If AFTER is true the operation needs to return
7639 the value of *MEM after the operation, otherwise the previous value.
7640 TARGET is an optional place to place the result. The result is unused if
7641 it is const0_rtx.
7642 Return the result if there is a better sequence, otherwise NULL_RTX. */
7644 static rtx
7645 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
7646 enum memmodel model, bool after)
7648 /* If the value is prefetched, or not used, it may be possible to replace
7649 the sequence with a native exchange operation. */
7650 if (!after || target == const0_rtx)
7652 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
7653 if (code == AND && val == const0_rtx)
7655 if (target == const0_rtx)
7656 target = gen_reg_rtx (GET_MODE (mem));
7657 return maybe_emit_atomic_exchange (target, mem, val, model);
7660 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
7661 if (code == IOR && val == constm1_rtx)
7663 if (target == const0_rtx)
7664 target = gen_reg_rtx (GET_MODE (mem));
7665 return maybe_emit_atomic_exchange (target, mem, val, model);
7669 return NULL_RTX;
7672 /* Try to emit an instruction for a specific operation varaition.
7673 OPTAB contains the OP functions.
7674 TARGET is an optional place to return the result. const0_rtx means unused.
7675 MEM is the memory location to operate on.
7676 VAL is the value to use in the operation.
7677 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
7678 MODEL is the memory model, if used.
7679 AFTER is true if the returned result is the value after the operation. */
7681 static rtx
7682 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
7683 rtx val, bool use_memmodel, enum memmodel model, bool after)
7685 enum machine_mode mode = GET_MODE (mem);
7686 struct expand_operand ops[4];
7687 enum insn_code icode;
7688 int op_counter = 0;
7689 int num_ops;
7691 /* Check to see if there is a result returned. */
7692 if (target == const0_rtx)
7694 if (use_memmodel)
7696 icode = direct_optab_handler (optab->mem_no_result, mode);
7697 create_integer_operand (&ops[2], model);
7698 num_ops = 3;
7700 else
7702 icode = direct_optab_handler (optab->no_result, mode);
7703 num_ops = 2;
7706 /* Otherwise, we need to generate a result. */
7707 else
7709 if (use_memmodel)
7711 icode = direct_optab_handler (after ? optab->mem_fetch_after
7712 : optab->mem_fetch_before, mode);
7713 create_integer_operand (&ops[3], model);
7714 num_ops = 4;
7716 else
7718 icode = optab_handler (after ? optab->fetch_after
7719 : optab->fetch_before, mode);
7720 num_ops = 3;
7722 create_output_operand (&ops[op_counter++], target, mode);
7724 if (icode == CODE_FOR_nothing)
7725 return NULL_RTX;
7727 create_fixed_operand (&ops[op_counter++], mem);
7728 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7729 create_convert_operand_to (&ops[op_counter++], val, mode, true);
7731 if (maybe_expand_insn (icode, num_ops, ops))
7732 return (target == const0_rtx ? const0_rtx : ops[0].value);
7734 return NULL_RTX;
7738 /* This function expands an atomic fetch_OP or OP_fetch operation:
7739 TARGET is an option place to stick the return value. const0_rtx indicates
7740 the result is unused.
7741 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7742 CODE is the operation being performed (OP)
7743 MEMMODEL is the memory model variant to use.
7744 AFTER is true to return the result of the operation (OP_fetch).
7745 AFTER is false to return the value before the operation (fetch_OP).
7747 This function will *only* generate instructions if there is a direct
7748 optab. No compare and swap loops or libcalls will be generated. */
7750 static rtx
7751 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
7752 enum rtx_code code, enum memmodel model,
7753 bool after)
7755 enum machine_mode mode = GET_MODE (mem);
7756 struct atomic_op_functions optab;
7757 rtx result;
7758 bool unused_result = (target == const0_rtx);
7760 get_atomic_op_for_code (&optab, code);
7762 /* Check to see if there are any better instructions. */
7763 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
7764 if (result)
7765 return result;
7767 /* Check for the case where the result isn't used and try those patterns. */
7768 if (unused_result)
7770 /* Try the memory model variant first. */
7771 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
7772 if (result)
7773 return result;
7775 /* Next try the old style withuot a memory model. */
7776 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
7777 if (result)
7778 return result;
7780 /* There is no no-result pattern, so try patterns with a result. */
7781 target = NULL_RTX;
7784 /* Try the __atomic version. */
7785 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
7786 if (result)
7787 return result;
7789 /* Try the older __sync version. */
7790 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
7791 if (result)
7792 return result;
7794 /* If the fetch value can be calculated from the other variation of fetch,
7795 try that operation. */
7796 if (after || unused_result || optab.reverse_code != UNKNOWN)
7798 /* Try the __atomic version, then the older __sync version. */
7799 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
7800 if (!result)
7801 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
7803 if (result)
7805 /* If the result isn't used, no need to do compensation code. */
7806 if (unused_result)
7807 return result;
7809 /* Issue compensation code. Fetch_after == fetch_before OP val.
7810 Fetch_before == after REVERSE_OP val. */
7811 if (!after)
7812 code = optab.reverse_code;
7813 if (code == NOT)
7815 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
7816 true, OPTAB_LIB_WIDEN);
7817 result = expand_simple_unop (mode, NOT, result, target, true);
7819 else
7820 result = expand_simple_binop (mode, code, result, val, target,
7821 true, OPTAB_LIB_WIDEN);
7822 return result;
7826 /* No direct opcode can be generated. */
7827 return NULL_RTX;
7832 /* This function expands an atomic fetch_OP or OP_fetch operation:
7833 TARGET is an option place to stick the return value. const0_rtx indicates
7834 the result is unused.
7835 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7836 CODE is the operation being performed (OP)
7837 MEMMODEL is the memory model variant to use.
7838 AFTER is true to return the result of the operation (OP_fetch).
7839 AFTER is false to return the value before the operation (fetch_OP). */
7841 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
7842 enum memmodel model, bool after)
7844 enum machine_mode mode = GET_MODE (mem);
7845 rtx result;
7846 bool unused_result = (target == const0_rtx);
7848 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
7849 after);
7851 if (result)
7852 return result;
7854 /* Add/sub can be implemented by doing the reverse operation with -(val). */
7855 if (code == PLUS || code == MINUS)
7857 rtx tmp;
7858 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
7860 start_sequence ();
7861 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
7862 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
7863 model, after);
7864 if (result)
7866 /* PLUS worked so emit the insns and return. */
7867 tmp = get_insns ();
7868 end_sequence ();
7869 emit_insn (tmp);
7870 return result;
7873 /* PLUS did not work, so throw away the negation code and continue. */
7874 end_sequence ();
7877 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
7878 if (!can_compare_and_swap_p (mode, false))
7880 rtx libfunc;
7881 bool fixup = false;
7882 enum rtx_code orig_code = code;
7883 struct atomic_op_functions optab;
7885 get_atomic_op_for_code (&optab, code);
7886 libfunc = optab_libfunc (after ? optab.fetch_after
7887 : optab.fetch_before, mode);
7888 if (libfunc == NULL
7889 && (after || unused_result || optab.reverse_code != UNKNOWN))
7891 fixup = true;
7892 if (!after)
7893 code = optab.reverse_code;
7894 libfunc = optab_libfunc (after ? optab.fetch_before
7895 : optab.fetch_after, mode);
7897 if (libfunc != NULL)
7899 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7900 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
7901 2, addr, ptr_mode, val, mode);
7903 if (!unused_result && fixup)
7904 result = expand_simple_binop (mode, code, result, val, target,
7905 true, OPTAB_LIB_WIDEN);
7906 return result;
7909 /* We need the original code for any further attempts. */
7910 code = orig_code;
7913 /* If nothing else has succeeded, default to a compare and swap loop. */
7914 if (can_compare_and_swap_p (mode, true))
7916 rtx insn;
7917 rtx t0 = gen_reg_rtx (mode), t1;
7919 start_sequence ();
7921 /* If the result is used, get a register for it. */
7922 if (!unused_result)
7924 if (!target || !register_operand (target, mode))
7925 target = gen_reg_rtx (mode);
7926 /* If fetch_before, copy the value now. */
7927 if (!after)
7928 emit_move_insn (target, t0);
7930 else
7931 target = const0_rtx;
7933 t1 = t0;
7934 if (code == NOT)
7936 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
7937 true, OPTAB_LIB_WIDEN);
7938 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
7940 else
7941 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
7942 OPTAB_LIB_WIDEN);
7944 /* For after, copy the value now. */
7945 if (!unused_result && after)
7946 emit_move_insn (target, t1);
7947 insn = get_insns ();
7948 end_sequence ();
7950 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7951 return target;
7954 return NULL_RTX;
7957 /* Return true if OPERAND is suitable for operand number OPNO of
7958 instruction ICODE. */
7960 bool
7961 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
7963 return (!insn_data[(int) icode].operand[opno].predicate
7964 || (insn_data[(int) icode].operand[opno].predicate
7965 (operand, insn_data[(int) icode].operand[opno].mode)));
7968 /* TARGET is a target of a multiword operation that we are going to
7969 implement as a series of word-mode operations. Return true if
7970 TARGET is suitable for this purpose. */
7972 bool
7973 valid_multiword_target_p (rtx target)
7975 enum machine_mode mode;
7976 int i;
7978 mode = GET_MODE (target);
7979 for (i = 0; i < GET_MODE_SIZE (mode); i += UNITS_PER_WORD)
7980 if (!validate_subreg (word_mode, mode, target, i))
7981 return false;
7982 return true;
7985 /* Like maybe_legitimize_operand, but do not change the code of the
7986 current rtx value. */
7988 static bool
7989 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
7990 struct expand_operand *op)
7992 /* See if the operand matches in its current form. */
7993 if (insn_operand_matches (icode, opno, op->value))
7994 return true;
7996 /* If the operand is a memory whose address has no side effects,
7997 try forcing the address into a non-virtual pseudo register.
7998 The check for side effects is important because copy_to_mode_reg
7999 cannot handle things like auto-modified addresses. */
8000 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
8002 rtx addr, mem;
8004 mem = op->value;
8005 addr = XEXP (mem, 0);
8006 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
8007 && !side_effects_p (addr))
8009 rtx last;
8010 enum machine_mode mode;
8012 last = get_last_insn ();
8013 mode = get_address_mode (mem);
8014 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
8015 if (insn_operand_matches (icode, opno, mem))
8017 op->value = mem;
8018 return true;
8020 delete_insns_since (last);
8024 return false;
8027 /* Try to make OP match operand OPNO of instruction ICODE. Return true
8028 on success, storing the new operand value back in OP. */
8030 static bool
8031 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
8032 struct expand_operand *op)
8034 enum machine_mode mode, imode;
8035 bool old_volatile_ok, result;
8037 mode = op->mode;
8038 switch (op->type)
8040 case EXPAND_FIXED:
8041 old_volatile_ok = volatile_ok;
8042 volatile_ok = true;
8043 result = maybe_legitimize_operand_same_code (icode, opno, op);
8044 volatile_ok = old_volatile_ok;
8045 return result;
8047 case EXPAND_OUTPUT:
8048 gcc_assert (mode != VOIDmode);
8049 if (op->value
8050 && op->value != const0_rtx
8051 && GET_MODE (op->value) == mode
8052 && maybe_legitimize_operand_same_code (icode, opno, op))
8053 return true;
8055 op->value = gen_reg_rtx (mode);
8056 break;
8058 case EXPAND_INPUT:
8059 input:
8060 gcc_assert (mode != VOIDmode);
8061 gcc_assert (GET_MODE (op->value) == VOIDmode
8062 || GET_MODE (op->value) == mode);
8063 if (maybe_legitimize_operand_same_code (icode, opno, op))
8064 return true;
8066 op->value = copy_to_mode_reg (mode, op->value);
8067 break;
8069 case EXPAND_CONVERT_TO:
8070 gcc_assert (mode != VOIDmode);
8071 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
8072 goto input;
8074 case EXPAND_CONVERT_FROM:
8075 if (GET_MODE (op->value) != VOIDmode)
8076 mode = GET_MODE (op->value);
8077 else
8078 /* The caller must tell us what mode this value has. */
8079 gcc_assert (mode != VOIDmode);
8081 imode = insn_data[(int) icode].operand[opno].mode;
8082 if (imode != VOIDmode && imode != mode)
8084 op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
8085 mode = imode;
8087 goto input;
8089 case EXPAND_ADDRESS:
8090 gcc_assert (mode != VOIDmode);
8091 op->value = convert_memory_address (mode, op->value);
8092 goto input;
8094 case EXPAND_INTEGER:
8095 mode = insn_data[(int) icode].operand[opno].mode;
8096 if (mode != VOIDmode && const_int_operand (op->value, mode))
8097 goto input;
8098 break;
8100 return insn_operand_matches (icode, opno, op->value);
8103 /* Make OP describe an input operand that should have the same value
8104 as VALUE, after any mode conversion that the target might request.
8105 TYPE is the type of VALUE. */
8107 void
8108 create_convert_operand_from_type (struct expand_operand *op,
8109 rtx value, tree type)
8111 create_convert_operand_from (op, value, TYPE_MODE (type),
8112 TYPE_UNSIGNED (type));
8115 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
8116 of instruction ICODE. Return true on success, leaving the new operand
8117 values in the OPS themselves. Emit no code on failure. */
8119 bool
8120 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
8121 unsigned int nops, struct expand_operand *ops)
8123 rtx last;
8124 unsigned int i;
8126 last = get_last_insn ();
8127 for (i = 0; i < nops; i++)
8128 if (!maybe_legitimize_operand (icode, opno + i, &ops[i]))
8130 delete_insns_since (last);
8131 return false;
8133 return true;
8136 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
8137 as its operands. Return the instruction pattern on success,
8138 and emit any necessary set-up code. Return null and emit no
8139 code on failure. */
8142 maybe_gen_insn (enum insn_code icode, unsigned int nops,
8143 struct expand_operand *ops)
8145 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
8146 if (!maybe_legitimize_operands (icode, 0, nops, ops))
8147 return NULL_RTX;
8149 switch (nops)
8151 case 1:
8152 return GEN_FCN (icode) (ops[0].value);
8153 case 2:
8154 return GEN_FCN (icode) (ops[0].value, ops[1].value);
8155 case 3:
8156 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
8157 case 4:
8158 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8159 ops[3].value);
8160 case 5:
8161 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8162 ops[3].value, ops[4].value);
8163 case 6:
8164 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8165 ops[3].value, ops[4].value, ops[5].value);
8166 case 7:
8167 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8168 ops[3].value, ops[4].value, ops[5].value,
8169 ops[6].value);
8170 case 8:
8171 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
8172 ops[3].value, ops[4].value, ops[5].value,
8173 ops[6].value, ops[7].value);
8175 gcc_unreachable ();
8178 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
8179 as its operands. Return true on success and emit no code on failure. */
8181 bool
8182 maybe_expand_insn (enum insn_code icode, unsigned int nops,
8183 struct expand_operand *ops)
8185 rtx pat = maybe_gen_insn (icode, nops, ops);
8186 if (pat)
8188 emit_insn (pat);
8189 return true;
8191 return false;
8194 /* Like maybe_expand_insn, but for jumps. */
8196 bool
8197 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
8198 struct expand_operand *ops)
8200 rtx pat = maybe_gen_insn (icode, nops, ops);
8201 if (pat)
8203 emit_jump_insn (pat);
8204 return true;
8206 return false;
8209 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
8210 as its operands. */
8212 void
8213 expand_insn (enum insn_code icode, unsigned int nops,
8214 struct expand_operand *ops)
8216 if (!maybe_expand_insn (icode, nops, ops))
8217 gcc_unreachable ();
8220 /* Like expand_insn, but for jumps. */
8222 void
8223 expand_jump_insn (enum insn_code icode, unsigned int nops,
8224 struct expand_operand *ops)
8226 if (!maybe_expand_jump_insn (icode, nops, ops))
8227 gcc_unreachable ();
8230 /* Reduce conditional compilation elsewhere. */
8231 #ifndef HAVE_insv
8232 #define HAVE_insv 0
8233 #define CODE_FOR_insv CODE_FOR_nothing
8234 #endif
8235 #ifndef HAVE_extv
8236 #define HAVE_extv 0
8237 #define CODE_FOR_extv CODE_FOR_nothing
8238 #endif
8239 #ifndef HAVE_extzv
8240 #define HAVE_extzv 0
8241 #define CODE_FOR_extzv CODE_FOR_nothing
8242 #endif
8244 /* Enumerates the possible types of structure operand to an
8245 extraction_insn. */
8246 enum extraction_type { ET_unaligned_mem, ET_reg };
8248 /* Check whether insv, extv or extzv pattern ICODE can be used for an
8249 insertion or extraction of type TYPE on a structure of mode MODE.
8250 Return true if so and fill in *INSN accordingly. STRUCT_OP is the
8251 operand number of the structure (the first sign_extract or zero_extract
8252 operand) and FIELD_OP is the operand number of the field (the other
8253 side of the set from the sign_extract or zero_extract). */
8255 static bool
8256 get_traditional_extraction_insn (extraction_insn *insn,
8257 enum extraction_type type,
8258 enum machine_mode mode,
8259 enum insn_code icode,
8260 int struct_op, int field_op)
8262 const struct insn_data_d *data = &insn_data[icode];
8264 enum machine_mode struct_mode = data->operand[struct_op].mode;
8265 if (struct_mode == VOIDmode)
8266 struct_mode = word_mode;
8267 if (mode != struct_mode)
8268 return false;
8270 enum machine_mode field_mode = data->operand[field_op].mode;
8271 if (field_mode == VOIDmode)
8272 field_mode = word_mode;
8274 enum machine_mode pos_mode = data->operand[struct_op + 2].mode;
8275 if (pos_mode == VOIDmode)
8276 pos_mode = word_mode;
8278 insn->icode = icode;
8279 insn->field_mode = field_mode;
8280 insn->struct_mode = (type == ET_unaligned_mem ? byte_mode : struct_mode);
8281 insn->pos_mode = pos_mode;
8282 return true;
8285 /* Return true if an optab exists to perform an insertion or extraction
8286 of type TYPE in mode MODE. Describe the instruction in *INSN if so.
8288 REG_OPTAB is the optab to use for register structures and
8289 MISALIGN_OPTAB is the optab to use for misaligned memory structures.
8290 POS_OP is the operand number of the bit position. */
8292 static bool
8293 get_optab_extraction_insn (struct extraction_insn *insn,
8294 enum extraction_type type,
8295 enum machine_mode mode, direct_optab reg_optab,
8296 direct_optab misalign_optab, int pos_op)
8298 direct_optab optab = (type == ET_unaligned_mem ? misalign_optab : reg_optab);
8299 enum insn_code icode = direct_optab_handler (optab, mode);
8300 if (icode == CODE_FOR_nothing)
8301 return false;
8303 const struct insn_data_d *data = &insn_data[icode];
8305 insn->icode = icode;
8306 insn->field_mode = mode;
8307 insn->struct_mode = (type == ET_unaligned_mem ? BLKmode : mode);
8308 insn->pos_mode = data->operand[pos_op].mode;
8309 if (insn->pos_mode == VOIDmode)
8310 insn->pos_mode = word_mode;
8311 return true;
8314 /* Return true if an instruction exists to perform an insertion or
8315 extraction (PATTERN says which) of type TYPE in mode MODE.
8316 Describe the instruction in *INSN if so. */
8318 static bool
8319 get_extraction_insn (extraction_insn *insn,
8320 enum extraction_pattern pattern,
8321 enum extraction_type type,
8322 enum machine_mode mode)
8324 switch (pattern)
8326 case EP_insv:
8327 if (HAVE_insv
8328 && get_traditional_extraction_insn (insn, type, mode,
8329 CODE_FOR_insv, 0, 3))
8330 return true;
8331 return get_optab_extraction_insn (insn, type, mode, insv_optab,
8332 insvmisalign_optab, 2);
8334 case EP_extv:
8335 if (HAVE_extv
8336 && get_traditional_extraction_insn (insn, type, mode,
8337 CODE_FOR_extv, 1, 0))
8338 return true;
8339 return get_optab_extraction_insn (insn, type, mode, extv_optab,
8340 extvmisalign_optab, 3);
8342 case EP_extzv:
8343 if (HAVE_extzv
8344 && get_traditional_extraction_insn (insn, type, mode,
8345 CODE_FOR_extzv, 1, 0))
8346 return true;
8347 return get_optab_extraction_insn (insn, type, mode, extzv_optab,
8348 extzvmisalign_optab, 3);
8350 default:
8351 gcc_unreachable ();
8355 /* Return true if an instruction exists to access a field of mode
8356 FIELDMODE in a structure that has STRUCT_BITS significant bits.
8357 Describe the "best" such instruction in *INSN if so. PATTERN and
8358 TYPE describe the type of insertion or extraction we want to perform.
8360 For an insertion, the number of significant structure bits includes
8361 all bits of the target. For an extraction, it need only include the
8362 most significant bit of the field. Larger widths are acceptable
8363 in both cases. */
8365 static bool
8366 get_best_extraction_insn (extraction_insn *insn,
8367 enum extraction_pattern pattern,
8368 enum extraction_type type,
8369 unsigned HOST_WIDE_INT struct_bits,
8370 enum machine_mode field_mode)
8372 enum machine_mode mode = smallest_mode_for_size (struct_bits, MODE_INT);
8373 while (mode != VOIDmode)
8375 if (get_extraction_insn (insn, pattern, type, mode))
8377 while (mode != VOIDmode
8378 && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (field_mode)
8379 && !TRULY_NOOP_TRUNCATION_MODES_P (insn->field_mode,
8380 field_mode))
8382 get_extraction_insn (insn, pattern, type, mode);
8383 mode = GET_MODE_WIDER_MODE (mode);
8385 return true;
8387 mode = GET_MODE_WIDER_MODE (mode);
8389 return false;
8392 /* Return true if an instruction exists to access a field of mode
8393 FIELDMODE in a register structure that has STRUCT_BITS significant bits.
8394 Describe the "best" such instruction in *INSN if so. PATTERN describes
8395 the type of insertion or extraction we want to perform.
8397 For an insertion, the number of significant structure bits includes
8398 all bits of the target. For an extraction, it need only include the
8399 most significant bit of the field. Larger widths are acceptable
8400 in both cases. */
8402 bool
8403 get_best_reg_extraction_insn (extraction_insn *insn,
8404 enum extraction_pattern pattern,
8405 unsigned HOST_WIDE_INT struct_bits,
8406 enum machine_mode field_mode)
8408 return get_best_extraction_insn (insn, pattern, ET_reg, struct_bits,
8409 field_mode);
8412 /* Return true if an instruction exists to access a field of BITSIZE
8413 bits starting BITNUM bits into a memory structure. Describe the
8414 "best" such instruction in *INSN if so. PATTERN describes the type
8415 of insertion or extraction we want to perform and FIELDMODE is the
8416 natural mode of the extracted field.
8418 The instructions considered here only access bytes that overlap
8419 the bitfield; they do not touch any surrounding bytes. */
8421 bool
8422 get_best_mem_extraction_insn (extraction_insn *insn,
8423 enum extraction_pattern pattern,
8424 HOST_WIDE_INT bitsize, HOST_WIDE_INT bitnum,
8425 enum machine_mode field_mode)
8427 unsigned HOST_WIDE_INT struct_bits = (bitnum % BITS_PER_UNIT
8428 + bitsize
8429 + BITS_PER_UNIT - 1);
8430 struct_bits -= struct_bits % BITS_PER_UNIT;
8431 return get_best_extraction_insn (insn, pattern, ET_unaligned_mem,
8432 struct_bits, field_mode);
8435 #include "gt-optabs.h"