2011-08-19 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / optabs.c
bloba70119abfdcc61f0b4905b65579c61eebeef88fe
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 2011 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "diagnostic-core.h"
29 /* Include insn-config.h before expr.h so that HAVE_conditional_move
30 is properly defined. */
31 #include "insn-config.h"
32 #include "rtl.h"
33 #include "tree.h"
34 #include "tm_p.h"
35 #include "flags.h"
36 #include "function.h"
37 #include "except.h"
38 #include "expr.h"
39 #include "optabs.h"
40 #include "libfuncs.h"
41 #include "recog.h"
42 #include "reload.h"
43 #include "ggc.h"
44 #include "basic-block.h"
45 #include "target.h"
47 struct target_optabs default_target_optabs;
48 struct target_libfuncs default_target_libfuncs;
49 #if SWITCHABLE_TARGET
50 struct target_optabs *this_target_optabs = &default_target_optabs;
51 struct target_libfuncs *this_target_libfuncs = &default_target_libfuncs;
52 #endif
54 #define libfunc_hash \
55 (this_target_libfuncs->x_libfunc_hash)
57 /* Contains the optab used for each rtx code. */
58 optab code_to_optab[NUM_RTX_CODE + 1];
60 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
61 enum machine_mode *);
62 static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
64 /* Debug facility for use in GDB. */
65 void debug_optab_libfuncs (void);
67 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
68 #if ENABLE_DECIMAL_BID_FORMAT
69 #define DECIMAL_PREFIX "bid_"
70 #else
71 #define DECIMAL_PREFIX "dpd_"
72 #endif
74 /* Used for libfunc_hash. */
76 static hashval_t
77 hash_libfunc (const void *p)
79 const struct libfunc_entry *const e = (const struct libfunc_entry *) p;
81 return (((int) e->mode1 + (int) e->mode2 * NUM_MACHINE_MODES)
82 ^ e->optab);
85 /* Used for libfunc_hash. */
87 static int
88 eq_libfunc (const void *p, const void *q)
90 const struct libfunc_entry *const e1 = (const struct libfunc_entry *) p;
91 const struct libfunc_entry *const e2 = (const struct libfunc_entry *) q;
93 return (e1->optab == e2->optab
94 && e1->mode1 == e2->mode1
95 && e1->mode2 == e2->mode2);
98 /* Return libfunc corresponding operation defined by OPTAB converting
99 from MODE2 to MODE1. Trigger lazy initialization if needed, return NULL
100 if no libfunc is available. */
102 convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
103 enum machine_mode mode2)
105 struct libfunc_entry e;
106 struct libfunc_entry **slot;
108 e.optab = (size_t) (optab - &convert_optab_table[0]);
109 e.mode1 = mode1;
110 e.mode2 = mode2;
111 slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
112 if (!slot)
114 if (optab->libcall_gen)
116 optab->libcall_gen (optab, optab->libcall_basename, mode1, mode2);
117 slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
118 if (slot)
119 return (*slot)->libfunc;
120 else
121 return NULL;
123 return NULL;
125 return (*slot)->libfunc;
128 /* Return libfunc corresponding operation defined by OPTAB in MODE.
129 Trigger lazy initialization if needed, return NULL if no libfunc is
130 available. */
132 optab_libfunc (optab optab, enum machine_mode mode)
134 struct libfunc_entry e;
135 struct libfunc_entry **slot;
137 e.optab = (size_t) (optab - &optab_table[0]);
138 e.mode1 = mode;
139 e.mode2 = VOIDmode;
140 slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
141 if (!slot)
143 if (optab->libcall_gen)
145 optab->libcall_gen (optab, optab->libcall_basename,
146 optab->libcall_suffix, mode);
147 slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash,
148 &e, NO_INSERT);
149 if (slot)
150 return (*slot)->libfunc;
151 else
152 return NULL;
154 return NULL;
156 return (*slot)->libfunc;
160 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
161 the result of operation CODE applied to OP0 (and OP1 if it is a binary
162 operation).
164 If the last insn does not set TARGET, don't do anything, but return 1.
166 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
167 don't add the REG_EQUAL note but return 0. Our caller can then try
168 again, ensuring that TARGET is not one of the operands. */
170 static int
171 add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
173 rtx last_insn, insn, set;
174 rtx note;
176 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
178 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
179 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
180 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
181 && GET_RTX_CLASS (code) != RTX_COMPARE
182 && GET_RTX_CLASS (code) != RTX_UNARY)
183 return 1;
185 if (GET_CODE (target) == ZERO_EXTRACT)
186 return 1;
188 for (last_insn = insns;
189 NEXT_INSN (last_insn) != NULL_RTX;
190 last_insn = NEXT_INSN (last_insn))
193 set = single_set (last_insn);
194 if (set == NULL_RTX)
195 return 1;
197 if (! rtx_equal_p (SET_DEST (set), target)
198 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
199 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
200 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
201 return 1;
203 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
204 besides the last insn. */
205 if (reg_overlap_mentioned_p (target, op0)
206 || (op1 && reg_overlap_mentioned_p (target, op1)))
208 insn = PREV_INSN (last_insn);
209 while (insn != NULL_RTX)
211 if (reg_set_p (target, insn))
212 return 0;
214 insn = PREV_INSN (insn);
218 if (GET_RTX_CLASS (code) == RTX_UNARY)
219 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
220 else
221 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
223 set_unique_reg_note (last_insn, REG_EQUAL, note);
225 return 1;
228 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
229 for a widening operation would be. In most cases this would be OP0, but if
230 that's a constant it'll be VOIDmode, which isn't useful. */
232 static enum machine_mode
233 widened_mode (enum machine_mode to_mode, rtx op0, rtx op1)
235 enum machine_mode m0 = GET_MODE (op0);
236 enum machine_mode m1 = GET_MODE (op1);
237 enum machine_mode result;
239 if (m0 == VOIDmode && m1 == VOIDmode)
240 return to_mode;
241 else if (m0 == VOIDmode || GET_MODE_SIZE (m0) < GET_MODE_SIZE (m1))
242 result = m1;
243 else
244 result = m0;
246 if (GET_MODE_SIZE (result) > GET_MODE_SIZE (to_mode))
247 return to_mode;
249 return result;
252 /* Find a widening optab even if it doesn't widen as much as we want.
253 E.g. if from_mode is HImode, and to_mode is DImode, and there is no
254 direct HI->SI insn, then return SI->DI, if that exists.
255 If PERMIT_NON_WIDENING is non-zero then this can be used with
256 non-widening optabs also. */
258 enum insn_code
259 find_widening_optab_handler_and_mode (optab op, enum machine_mode to_mode,
260 enum machine_mode from_mode,
261 int permit_non_widening,
262 enum machine_mode *found_mode)
264 for (; (permit_non_widening || from_mode != to_mode)
265 && GET_MODE_SIZE (from_mode) <= GET_MODE_SIZE (to_mode)
266 && from_mode != VOIDmode;
267 from_mode = GET_MODE_WIDER_MODE (from_mode))
269 enum insn_code handler = widening_optab_handler (op, to_mode,
270 from_mode);
272 if (handler != CODE_FOR_nothing)
274 if (found_mode)
275 *found_mode = from_mode;
276 return handler;
280 return CODE_FOR_nothing;
283 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
284 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
285 not actually do a sign-extend or zero-extend, but can leave the
286 higher-order bits of the result rtx undefined, for example, in the case
287 of logical operations, but not right shifts. */
289 static rtx
290 widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
291 int unsignedp, int no_extend)
293 rtx result;
295 /* If we don't have to extend and this is a constant, return it. */
296 if (no_extend && GET_MODE (op) == VOIDmode)
297 return op;
299 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
300 extend since it will be more efficient to do so unless the signedness of
301 a promoted object differs from our extension. */
302 if (! no_extend
303 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
304 && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
305 return convert_modes (mode, oldmode, op, unsignedp);
307 /* If MODE is no wider than a single word, we return a paradoxical
308 SUBREG. */
309 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
310 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
312 /* Otherwise, get an object of MODE, clobber it, and set the low-order
313 part to OP. */
315 result = gen_reg_rtx (mode);
316 emit_clobber (result);
317 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
318 return result;
321 /* Return the optab used for computing the operation given by the tree code,
322 CODE and the tree EXP. This function is not always usable (for example, it
323 cannot give complete results for multiplication or division) but probably
324 ought to be relied on more widely throughout the expander. */
325 optab
326 optab_for_tree_code (enum tree_code code, const_tree type,
327 enum optab_subtype subtype)
329 bool trapv;
330 switch (code)
332 case BIT_AND_EXPR:
333 return and_optab;
335 case BIT_IOR_EXPR:
336 return ior_optab;
338 case BIT_NOT_EXPR:
339 return one_cmpl_optab;
341 case BIT_XOR_EXPR:
342 return xor_optab;
344 case TRUNC_MOD_EXPR:
345 case CEIL_MOD_EXPR:
346 case FLOOR_MOD_EXPR:
347 case ROUND_MOD_EXPR:
348 return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
350 case RDIV_EXPR:
351 case TRUNC_DIV_EXPR:
352 case CEIL_DIV_EXPR:
353 case FLOOR_DIV_EXPR:
354 case ROUND_DIV_EXPR:
355 case EXACT_DIV_EXPR:
356 if (TYPE_SATURATING(type))
357 return TYPE_UNSIGNED(type) ? usdiv_optab : ssdiv_optab;
358 return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
360 case LSHIFT_EXPR:
361 if (TREE_CODE (type) == VECTOR_TYPE)
363 if (subtype == optab_vector)
364 return TYPE_SATURATING (type) ? NULL : vashl_optab;
366 gcc_assert (subtype == optab_scalar);
368 if (TYPE_SATURATING(type))
369 return TYPE_UNSIGNED(type) ? usashl_optab : ssashl_optab;
370 return ashl_optab;
372 case RSHIFT_EXPR:
373 if (TREE_CODE (type) == VECTOR_TYPE)
375 if (subtype == optab_vector)
376 return TYPE_UNSIGNED (type) ? vlshr_optab : vashr_optab;
378 gcc_assert (subtype == optab_scalar);
380 return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
382 case LROTATE_EXPR:
383 if (TREE_CODE (type) == VECTOR_TYPE)
385 if (subtype == optab_vector)
386 return vrotl_optab;
388 gcc_assert (subtype == optab_scalar);
390 return rotl_optab;
392 case RROTATE_EXPR:
393 if (TREE_CODE (type) == VECTOR_TYPE)
395 if (subtype == optab_vector)
396 return vrotr_optab;
398 gcc_assert (subtype == optab_scalar);
400 return rotr_optab;
402 case MAX_EXPR:
403 return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
405 case MIN_EXPR:
406 return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
408 case REALIGN_LOAD_EXPR:
409 return vec_realign_load_optab;
411 case WIDEN_SUM_EXPR:
412 return TYPE_UNSIGNED (type) ? usum_widen_optab : ssum_widen_optab;
414 case DOT_PROD_EXPR:
415 return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
417 case WIDEN_MULT_PLUS_EXPR:
418 return (TYPE_UNSIGNED (type)
419 ? (TYPE_SATURATING (type)
420 ? usmadd_widen_optab : umadd_widen_optab)
421 : (TYPE_SATURATING (type)
422 ? ssmadd_widen_optab : smadd_widen_optab));
424 case WIDEN_MULT_MINUS_EXPR:
425 return (TYPE_UNSIGNED (type)
426 ? (TYPE_SATURATING (type)
427 ? usmsub_widen_optab : umsub_widen_optab)
428 : (TYPE_SATURATING (type)
429 ? ssmsub_widen_optab : smsub_widen_optab));
431 case FMA_EXPR:
432 return fma_optab;
434 case REDUC_MAX_EXPR:
435 return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab;
437 case REDUC_MIN_EXPR:
438 return TYPE_UNSIGNED (type) ? reduc_umin_optab : reduc_smin_optab;
440 case REDUC_PLUS_EXPR:
441 return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
443 case VEC_LSHIFT_EXPR:
444 return vec_shl_optab;
446 case VEC_RSHIFT_EXPR:
447 return vec_shr_optab;
449 case VEC_WIDEN_MULT_HI_EXPR:
450 return TYPE_UNSIGNED (type) ?
451 vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
453 case VEC_WIDEN_MULT_LO_EXPR:
454 return TYPE_UNSIGNED (type) ?
455 vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
457 case VEC_UNPACK_HI_EXPR:
458 return TYPE_UNSIGNED (type) ?
459 vec_unpacku_hi_optab : vec_unpacks_hi_optab;
461 case VEC_UNPACK_LO_EXPR:
462 return TYPE_UNSIGNED (type) ?
463 vec_unpacku_lo_optab : vec_unpacks_lo_optab;
465 case VEC_UNPACK_FLOAT_HI_EXPR:
466 /* The signedness is determined from input operand. */
467 return TYPE_UNSIGNED (type) ?
468 vec_unpacku_float_hi_optab : vec_unpacks_float_hi_optab;
470 case VEC_UNPACK_FLOAT_LO_EXPR:
471 /* The signedness is determined from input operand. */
472 return TYPE_UNSIGNED (type) ?
473 vec_unpacku_float_lo_optab : vec_unpacks_float_lo_optab;
475 case VEC_PACK_TRUNC_EXPR:
476 return vec_pack_trunc_optab;
478 case VEC_PACK_SAT_EXPR:
479 return TYPE_UNSIGNED (type) ? vec_pack_usat_optab : vec_pack_ssat_optab;
481 case VEC_PACK_FIX_TRUNC_EXPR:
482 /* The signedness is determined from output operand. */
483 return TYPE_UNSIGNED (type) ?
484 vec_pack_ufix_trunc_optab : vec_pack_sfix_trunc_optab;
486 default:
487 break;
490 trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
491 switch (code)
493 case POINTER_PLUS_EXPR:
494 case PLUS_EXPR:
495 if (TYPE_SATURATING(type))
496 return TYPE_UNSIGNED(type) ? usadd_optab : ssadd_optab;
497 return trapv ? addv_optab : add_optab;
499 case MINUS_EXPR:
500 if (TYPE_SATURATING(type))
501 return TYPE_UNSIGNED(type) ? ussub_optab : sssub_optab;
502 return trapv ? subv_optab : sub_optab;
504 case MULT_EXPR:
505 if (TYPE_SATURATING(type))
506 return TYPE_UNSIGNED(type) ? usmul_optab : ssmul_optab;
507 return trapv ? smulv_optab : smul_optab;
509 case NEGATE_EXPR:
510 if (TYPE_SATURATING(type))
511 return TYPE_UNSIGNED(type) ? usneg_optab : ssneg_optab;
512 return trapv ? negv_optab : neg_optab;
514 case ABS_EXPR:
515 return trapv ? absv_optab : abs_optab;
517 case VEC_EXTRACT_EVEN_EXPR:
518 return vec_extract_even_optab;
520 case VEC_EXTRACT_ODD_EXPR:
521 return vec_extract_odd_optab;
523 case VEC_INTERLEAVE_HIGH_EXPR:
524 return vec_interleave_high_optab;
526 case VEC_INTERLEAVE_LOW_EXPR:
527 return vec_interleave_low_optab;
529 default:
530 return NULL;
535 /* Expand vector widening operations.
537 There are two different classes of operations handled here:
538 1) Operations whose result is wider than all the arguments to the operation.
539 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
540 In this case OP0 and optionally OP1 would be initialized,
541 but WIDE_OP wouldn't (not relevant for this case).
542 2) Operations whose result is of the same size as the last argument to the
543 operation, but wider than all the other arguments to the operation.
544 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
545 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
547 E.g, when called to expand the following operations, this is how
548 the arguments will be initialized:
549 nops OP0 OP1 WIDE_OP
550 widening-sum 2 oprnd0 - oprnd1
551 widening-dot-product 3 oprnd0 oprnd1 oprnd2
552 widening-mult 2 oprnd0 oprnd1 -
553 type-promotion (vec-unpack) 1 oprnd0 - - */
556 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
557 rtx target, int unsignedp)
559 struct expand_operand eops[4];
560 tree oprnd0, oprnd1, oprnd2;
561 enum machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
562 optab widen_pattern_optab;
563 enum insn_code icode;
564 int nops = TREE_CODE_LENGTH (ops->code);
565 int op;
567 oprnd0 = ops->op0;
568 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
569 widen_pattern_optab =
570 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
571 if (ops->code == WIDEN_MULT_PLUS_EXPR
572 || ops->code == WIDEN_MULT_MINUS_EXPR)
573 icode = find_widening_optab_handler (widen_pattern_optab,
574 TYPE_MODE (TREE_TYPE (ops->op2)),
575 tmode0, 0);
576 else
577 icode = optab_handler (widen_pattern_optab, tmode0);
578 gcc_assert (icode != CODE_FOR_nothing);
580 if (nops >= 2)
582 oprnd1 = ops->op1;
583 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
586 /* The last operand is of a wider mode than the rest of the operands. */
587 if (nops == 2)
588 wmode = tmode1;
589 else if (nops == 3)
591 gcc_assert (tmode1 == tmode0);
592 gcc_assert (op1);
593 oprnd2 = ops->op2;
594 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
597 op = 0;
598 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
599 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
600 if (op1)
601 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
602 if (wide_op)
603 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
604 expand_insn (icode, op, eops);
605 return eops[0].value;
608 /* Generate code to perform an operation specified by TERNARY_OPTAB
609 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
611 UNSIGNEDP is for the case where we have to widen the operands
612 to perform the operation. It says to use zero-extension.
614 If TARGET is nonzero, the value
615 is generated there, if it is convenient to do so.
616 In all cases an rtx is returned for the locus of the value;
617 this may or may not be TARGET. */
620 expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
621 rtx op1, rtx op2, rtx target, int unsignedp)
623 struct expand_operand ops[4];
624 enum insn_code icode = optab_handler (ternary_optab, mode);
626 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
628 create_output_operand (&ops[0], target, mode);
629 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
630 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
631 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
632 expand_insn (icode, 4, ops);
633 return ops[0].value;
637 /* Like expand_binop, but return a constant rtx if the result can be
638 calculated at compile time. The arguments and return value are
639 otherwise the same as for expand_binop. */
641 static rtx
642 simplify_expand_binop (enum machine_mode mode, optab binoptab,
643 rtx op0, rtx op1, rtx target, int unsignedp,
644 enum optab_methods methods)
646 if (CONSTANT_P (op0) && CONSTANT_P (op1))
648 rtx x = simplify_binary_operation (binoptab->code, mode, op0, op1);
650 if (x)
651 return x;
654 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
657 /* Like simplify_expand_binop, but always put the result in TARGET.
658 Return true if the expansion succeeded. */
660 bool
661 force_expand_binop (enum machine_mode mode, optab binoptab,
662 rtx op0, rtx op1, rtx target, int unsignedp,
663 enum optab_methods methods)
665 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
666 target, unsignedp, methods);
667 if (x == 0)
668 return false;
669 if (x != target)
670 emit_move_insn (target, x);
671 return true;
674 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */
677 expand_vec_shift_expr (sepops ops, rtx target)
679 struct expand_operand eops[3];
680 enum insn_code icode;
681 rtx rtx_op1, rtx_op2;
682 enum machine_mode mode = TYPE_MODE (ops->type);
683 tree vec_oprnd = ops->op0;
684 tree shift_oprnd = ops->op1;
685 optab shift_optab;
687 switch (ops->code)
689 case VEC_RSHIFT_EXPR:
690 shift_optab = vec_shr_optab;
691 break;
692 case VEC_LSHIFT_EXPR:
693 shift_optab = vec_shl_optab;
694 break;
695 default:
696 gcc_unreachable ();
699 icode = optab_handler (shift_optab, mode);
700 gcc_assert (icode != CODE_FOR_nothing);
702 rtx_op1 = expand_normal (vec_oprnd);
703 rtx_op2 = expand_normal (shift_oprnd);
705 create_output_operand (&eops[0], target, mode);
706 create_input_operand (&eops[1], rtx_op1, GET_MODE (rtx_op1));
707 create_convert_operand_from_type (&eops[2], rtx_op2, TREE_TYPE (shift_oprnd));
708 expand_insn (icode, 3, eops);
710 return eops[0].value;
713 /* This subroutine of expand_doubleword_shift handles the cases in which
714 the effective shift value is >= BITS_PER_WORD. The arguments and return
715 value are the same as for the parent routine, except that SUPERWORD_OP1
716 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
717 INTO_TARGET may be null if the caller has decided to calculate it. */
719 static bool
720 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
721 rtx outof_target, rtx into_target,
722 int unsignedp, enum optab_methods methods)
724 if (into_target != 0)
725 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
726 into_target, unsignedp, methods))
727 return false;
729 if (outof_target != 0)
731 /* For a signed right shift, we must fill OUTOF_TARGET with copies
732 of the sign bit, otherwise we must fill it with zeros. */
733 if (binoptab != ashr_optab)
734 emit_move_insn (outof_target, CONST0_RTX (word_mode));
735 else
736 if (!force_expand_binop (word_mode, binoptab,
737 outof_input, GEN_INT (BITS_PER_WORD - 1),
738 outof_target, unsignedp, methods))
739 return false;
741 return true;
744 /* This subroutine of expand_doubleword_shift handles the cases in which
745 the effective shift value is < BITS_PER_WORD. The arguments and return
746 value are the same as for the parent routine. */
748 static bool
749 expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
750 rtx outof_input, rtx into_input, rtx op1,
751 rtx outof_target, rtx into_target,
752 int unsignedp, enum optab_methods methods,
753 unsigned HOST_WIDE_INT shift_mask)
755 optab reverse_unsigned_shift, unsigned_shift;
756 rtx tmp, carries;
758 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
759 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
761 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
762 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
763 the opposite direction to BINOPTAB. */
764 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
766 carries = outof_input;
767 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
768 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
769 0, true, methods);
771 else
773 /* We must avoid shifting by BITS_PER_WORD bits since that is either
774 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
775 has unknown behavior. Do a single shift first, then shift by the
776 remainder. It's OK to use ~OP1 as the remainder if shift counts
777 are truncated to the mode size. */
778 carries = expand_binop (word_mode, reverse_unsigned_shift,
779 outof_input, const1_rtx, 0, unsignedp, methods);
780 if (shift_mask == BITS_PER_WORD - 1)
782 tmp = immed_double_const (-1, -1, op1_mode);
783 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
784 0, true, methods);
786 else
788 tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
789 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
790 0, true, methods);
793 if (tmp == 0 || carries == 0)
794 return false;
795 carries = expand_binop (word_mode, reverse_unsigned_shift,
796 carries, tmp, 0, unsignedp, methods);
797 if (carries == 0)
798 return false;
800 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
801 so the result can go directly into INTO_TARGET if convenient. */
802 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
803 into_target, unsignedp, methods);
804 if (tmp == 0)
805 return false;
807 /* Now OR in the bits carried over from OUTOF_INPUT. */
808 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
809 into_target, unsignedp, methods))
810 return false;
812 /* Use a standard word_mode shift for the out-of half. */
813 if (outof_target != 0)
814 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
815 outof_target, unsignedp, methods))
816 return false;
818 return true;
822 #ifdef HAVE_conditional_move
823 /* Try implementing expand_doubleword_shift using conditional moves.
824 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
825 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
826 are the shift counts to use in the former and latter case. All other
827 arguments are the same as the parent routine. */
829 static bool
830 expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
831 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
832 rtx outof_input, rtx into_input,
833 rtx subword_op1, rtx superword_op1,
834 rtx outof_target, rtx into_target,
835 int unsignedp, enum optab_methods methods,
836 unsigned HOST_WIDE_INT shift_mask)
838 rtx outof_superword, into_superword;
840 /* Put the superword version of the output into OUTOF_SUPERWORD and
841 INTO_SUPERWORD. */
842 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
843 if (outof_target != 0 && subword_op1 == superword_op1)
845 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
846 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
847 into_superword = outof_target;
848 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
849 outof_superword, 0, unsignedp, methods))
850 return false;
852 else
854 into_superword = gen_reg_rtx (word_mode);
855 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
856 outof_superword, into_superword,
857 unsignedp, methods))
858 return false;
861 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
862 if (!expand_subword_shift (op1_mode, binoptab,
863 outof_input, into_input, subword_op1,
864 outof_target, into_target,
865 unsignedp, methods, shift_mask))
866 return false;
868 /* Select between them. Do the INTO half first because INTO_SUPERWORD
869 might be the current value of OUTOF_TARGET. */
870 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
871 into_target, into_superword, word_mode, false))
872 return false;
874 if (outof_target != 0)
875 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
876 outof_target, outof_superword,
877 word_mode, false))
878 return false;
880 return true;
882 #endif
884 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
885 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
886 input operand; the shift moves bits in the direction OUTOF_INPUT->
887 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
888 of the target. OP1 is the shift count and OP1_MODE is its mode.
889 If OP1 is constant, it will have been truncated as appropriate
890 and is known to be nonzero.
892 If SHIFT_MASK is zero, the result of word shifts is undefined when the
893 shift count is outside the range [0, BITS_PER_WORD). This routine must
894 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
896 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
897 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
898 fill with zeros or sign bits as appropriate.
900 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
901 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
902 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
903 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
904 are undefined.
906 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
907 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
908 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
909 function wants to calculate it itself.
911 Return true if the shift could be successfully synthesized. */
913 static bool
914 expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
915 rtx outof_input, rtx into_input, rtx op1,
916 rtx outof_target, rtx into_target,
917 int unsignedp, enum optab_methods methods,
918 unsigned HOST_WIDE_INT shift_mask)
920 rtx superword_op1, tmp, cmp1, cmp2;
921 rtx subword_label, done_label;
922 enum rtx_code cmp_code;
924 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
925 fill the result with sign or zero bits as appropriate. If so, the value
926 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
927 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
928 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
930 This isn't worthwhile for constant shifts since the optimizers will
931 cope better with in-range shift counts. */
932 if (shift_mask >= BITS_PER_WORD
933 && outof_target != 0
934 && !CONSTANT_P (op1))
936 if (!expand_doubleword_shift (op1_mode, binoptab,
937 outof_input, into_input, op1,
938 0, into_target,
939 unsignedp, methods, shift_mask))
940 return false;
941 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
942 outof_target, unsignedp, methods))
943 return false;
944 return true;
947 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
948 is true when the effective shift value is less than BITS_PER_WORD.
949 Set SUPERWORD_OP1 to the shift count that should be used to shift
950 OUTOF_INPUT into INTO_TARGET when the condition is false. */
951 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
952 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
954 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
955 is a subword shift count. */
956 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
957 0, true, methods);
958 cmp2 = CONST0_RTX (op1_mode);
959 cmp_code = EQ;
960 superword_op1 = op1;
962 else
964 /* Set CMP1 to OP1 - BITS_PER_WORD. */
965 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
966 0, true, methods);
967 cmp2 = CONST0_RTX (op1_mode);
968 cmp_code = LT;
969 superword_op1 = cmp1;
971 if (cmp1 == 0)
972 return false;
974 /* If we can compute the condition at compile time, pick the
975 appropriate subroutine. */
976 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
977 if (tmp != 0 && CONST_INT_P (tmp))
979 if (tmp == const0_rtx)
980 return expand_superword_shift (binoptab, outof_input, superword_op1,
981 outof_target, into_target,
982 unsignedp, methods);
983 else
984 return expand_subword_shift (op1_mode, binoptab,
985 outof_input, into_input, op1,
986 outof_target, into_target,
987 unsignedp, methods, shift_mask);
990 #ifdef HAVE_conditional_move
991 /* Try using conditional moves to generate straight-line code. */
993 rtx start = get_last_insn ();
994 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
995 cmp_code, cmp1, cmp2,
996 outof_input, into_input,
997 op1, superword_op1,
998 outof_target, into_target,
999 unsignedp, methods, shift_mask))
1000 return true;
1001 delete_insns_since (start);
1003 #endif
1005 /* As a last resort, use branches to select the correct alternative. */
1006 subword_label = gen_label_rtx ();
1007 done_label = gen_label_rtx ();
1009 NO_DEFER_POP;
1010 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
1011 0, 0, subword_label, -1);
1012 OK_DEFER_POP;
1014 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
1015 outof_target, into_target,
1016 unsignedp, methods))
1017 return false;
1019 emit_jump_insn (gen_jump (done_label));
1020 emit_barrier ();
1021 emit_label (subword_label);
1023 if (!expand_subword_shift (op1_mode, binoptab,
1024 outof_input, into_input, op1,
1025 outof_target, into_target,
1026 unsignedp, methods, shift_mask))
1027 return false;
1029 emit_label (done_label);
1030 return true;
1033 /* Subroutine of expand_binop. Perform a double word multiplication of
1034 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1035 as the target's word_mode. This function return NULL_RTX if anything
1036 goes wrong, in which case it may have already emitted instructions
1037 which need to be deleted.
1039 If we want to multiply two two-word values and have normal and widening
1040 multiplies of single-word values, we can do this with three smaller
1041 multiplications.
1043 The multiplication proceeds as follows:
1044 _______________________
1045 [__op0_high_|__op0_low__]
1046 _______________________
1047 * [__op1_high_|__op1_low__]
1048 _______________________________________________
1049 _______________________
1050 (1) [__op0_low__*__op1_low__]
1051 _______________________
1052 (2a) [__op0_low__*__op1_high_]
1053 _______________________
1054 (2b) [__op0_high_*__op1_low__]
1055 _______________________
1056 (3) [__op0_high_*__op1_high_]
1059 This gives a 4-word result. Since we are only interested in the
1060 lower 2 words, partial result (3) and the upper words of (2a) and
1061 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1062 calculated using non-widening multiplication.
1064 (1), however, needs to be calculated with an unsigned widening
1065 multiplication. If this operation is not directly supported we
1066 try using a signed widening multiplication and adjust the result.
1067 This adjustment works as follows:
1069 If both operands are positive then no adjustment is needed.
1071 If the operands have different signs, for example op0_low < 0 and
1072 op1_low >= 0, the instruction treats the most significant bit of
1073 op0_low as a sign bit instead of a bit with significance
1074 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1075 with 2**BITS_PER_WORD - op0_low, and two's complements the
1076 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1077 the result.
1079 Similarly, if both operands are negative, we need to add
1080 (op0_low + op1_low) * 2**BITS_PER_WORD.
1082 We use a trick to adjust quickly. We logically shift op0_low right
1083 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1084 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1085 logical shift exists, we do an arithmetic right shift and subtract
1086 the 0 or -1. */
1088 static rtx
1089 expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
1090 bool umulp, enum optab_methods methods)
1092 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1093 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1094 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
1095 rtx product, adjust, product_high, temp;
1097 rtx op0_high = operand_subword_force (op0, high, mode);
1098 rtx op0_low = operand_subword_force (op0, low, mode);
1099 rtx op1_high = operand_subword_force (op1, high, mode);
1100 rtx op1_low = operand_subword_force (op1, low, mode);
1102 /* If we're using an unsigned multiply to directly compute the product
1103 of the low-order words of the operands and perform any required
1104 adjustments of the operands, we begin by trying two more multiplications
1105 and then computing the appropriate sum.
1107 We have checked above that the required addition is provided.
1108 Full-word addition will normally always succeed, especially if
1109 it is provided at all, so we don't worry about its failure. The
1110 multiplication may well fail, however, so we do handle that. */
1112 if (!umulp)
1114 /* ??? This could be done with emit_store_flag where available. */
1115 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1116 NULL_RTX, 1, methods);
1117 if (temp)
1118 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
1119 NULL_RTX, 0, OPTAB_DIRECT);
1120 else
1122 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1123 NULL_RTX, 0, methods);
1124 if (!temp)
1125 return NULL_RTX;
1126 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
1127 NULL_RTX, 0, OPTAB_DIRECT);
1130 if (!op0_high)
1131 return NULL_RTX;
1134 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
1135 NULL_RTX, 0, OPTAB_DIRECT);
1136 if (!adjust)
1137 return NULL_RTX;
1139 /* OP0_HIGH should now be dead. */
1141 if (!umulp)
1143 /* ??? This could be done with emit_store_flag where available. */
1144 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1145 NULL_RTX, 1, methods);
1146 if (temp)
1147 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
1148 NULL_RTX, 0, OPTAB_DIRECT);
1149 else
1151 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1152 NULL_RTX, 0, methods);
1153 if (!temp)
1154 return NULL_RTX;
1155 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
1156 NULL_RTX, 0, OPTAB_DIRECT);
1159 if (!op1_high)
1160 return NULL_RTX;
1163 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
1164 NULL_RTX, 0, OPTAB_DIRECT);
1165 if (!temp)
1166 return NULL_RTX;
1168 /* OP1_HIGH should now be dead. */
1170 adjust = expand_binop (word_mode, add_optab, adjust, temp,
1171 NULL_RTX, 0, OPTAB_DIRECT);
1173 if (target && !REG_P (target))
1174 target = NULL_RTX;
1176 if (umulp)
1177 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1178 target, 1, OPTAB_DIRECT);
1179 else
1180 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1181 target, 1, OPTAB_DIRECT);
1183 if (!product)
1184 return NULL_RTX;
1186 product_high = operand_subword (product, high, 1, mode);
1187 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
1188 NULL_RTX, 0, OPTAB_DIRECT);
1189 emit_move_insn (product_high, adjust);
1190 return product;
1193 /* Wrapper around expand_binop which takes an rtx code to specify
1194 the operation to perform, not an optab pointer. All other
1195 arguments are the same. */
1197 expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
1198 rtx op1, rtx target, int unsignedp,
1199 enum optab_methods methods)
1201 optab binop = code_to_optab[(int) code];
1202 gcc_assert (binop);
1204 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1207 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1208 binop. Order them according to commutative_operand_precedence and, if
1209 possible, try to put TARGET or a pseudo first. */
1210 static bool
1211 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1213 int op0_prec = commutative_operand_precedence (op0);
1214 int op1_prec = commutative_operand_precedence (op1);
1216 if (op0_prec < op1_prec)
1217 return true;
1219 if (op0_prec > op1_prec)
1220 return false;
1222 /* With equal precedence, both orders are ok, but it is better if the
1223 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1224 if (target == 0 || REG_P (target))
1225 return (REG_P (op1) && !REG_P (op0)) || target == op1;
1226 else
1227 return rtx_equal_p (op1, target);
1230 /* Return true if BINOPTAB implements a shift operation. */
1232 static bool
1233 shift_optab_p (optab binoptab)
1235 switch (binoptab->code)
1237 case ASHIFT:
1238 case SS_ASHIFT:
1239 case US_ASHIFT:
1240 case ASHIFTRT:
1241 case LSHIFTRT:
1242 case ROTATE:
1243 case ROTATERT:
1244 return true;
1246 default:
1247 return false;
1251 /* Return true if BINOPTAB implements a commutative binary operation. */
1253 static bool
1254 commutative_optab_p (optab binoptab)
1256 return (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
1257 || binoptab == smul_widen_optab
1258 || binoptab == umul_widen_optab
1259 || binoptab == smul_highpart_optab
1260 || binoptab == umul_highpart_optab);
1263 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
1264 optimizing, and if the operand is a constant that costs more than
1265 1 instruction, force the constant into a register and return that
1266 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1268 static rtx
1269 avoid_expensive_constant (enum machine_mode mode, optab binoptab,
1270 int opn, rtx x, bool unsignedp)
1272 bool speed = optimize_insn_for_speed_p ();
1274 if (mode != VOIDmode
1275 && optimize
1276 && CONSTANT_P (x)
1277 && rtx_cost (x, binoptab->code, opn, speed) > set_src_cost (x, speed))
1279 if (CONST_INT_P (x))
1281 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
1282 if (intval != INTVAL (x))
1283 x = GEN_INT (intval);
1285 else
1286 x = convert_modes (mode, VOIDmode, x, unsignedp);
1287 x = force_reg (mode, x);
1289 return x;
1292 /* Helper function for expand_binop: handle the case where there
1293 is an insn that directly implements the indicated operation.
1294 Returns null if this is not possible. */
1295 static rtx
1296 expand_binop_directly (enum machine_mode mode, optab binoptab,
1297 rtx op0, rtx op1,
1298 rtx target, int unsignedp, enum optab_methods methods,
1299 rtx last)
1301 enum machine_mode from_mode = widened_mode (mode, op0, op1);
1302 enum insn_code icode = find_widening_optab_handler (binoptab, mode,
1303 from_mode, 1);
1304 enum machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
1305 enum machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
1306 enum machine_mode mode0, mode1, tmp_mode;
1307 struct expand_operand ops[3];
1308 bool commutative_p;
1309 rtx pat;
1310 rtx xop0 = op0, xop1 = op1;
1311 rtx swap;
1313 /* If it is a commutative operator and the modes would match
1314 if we would swap the operands, we can save the conversions. */
1315 commutative_p = commutative_optab_p (binoptab);
1316 if (commutative_p
1317 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1318 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode1)
1320 swap = xop0;
1321 xop0 = xop1;
1322 xop1 = swap;
1325 /* If we are optimizing, force expensive constants into a register. */
1326 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1327 if (!shift_optab_p (binoptab))
1328 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1330 /* In case the insn wants input operands in modes different from
1331 those of the actual operands, convert the operands. It would
1332 seem that we don't need to convert CONST_INTs, but we do, so
1333 that they're properly zero-extended, sign-extended or truncated
1334 for their mode. */
1336 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1337 if (xmode0 != VOIDmode && xmode0 != mode0)
1339 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1340 mode0 = xmode0;
1343 mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
1344 if (xmode1 != VOIDmode && xmode1 != mode1)
1346 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1347 mode1 = xmode1;
1350 /* If operation is commutative,
1351 try to make the first operand a register.
1352 Even better, try to make it the same as the target.
1353 Also try to make the last operand a constant. */
1354 if (commutative_p
1355 && swap_commutative_operands_with_target (target, xop0, xop1))
1357 swap = xop1;
1358 xop1 = xop0;
1359 xop0 = swap;
1362 /* Now, if insn's predicates don't allow our operands, put them into
1363 pseudo regs. */
1365 if (binoptab == vec_pack_trunc_optab
1366 || binoptab == vec_pack_usat_optab
1367 || binoptab == vec_pack_ssat_optab
1368 || binoptab == vec_pack_ufix_trunc_optab
1369 || binoptab == vec_pack_sfix_trunc_optab)
1371 /* The mode of the result is different then the mode of the
1372 arguments. */
1373 tmp_mode = insn_data[(int) icode].operand[0].mode;
1374 if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1376 delete_insns_since (last);
1377 return NULL_RTX;
1380 else
1381 tmp_mode = mode;
1383 create_output_operand (&ops[0], target, tmp_mode);
1384 create_input_operand (&ops[1], xop0, mode0);
1385 create_input_operand (&ops[2], xop1, mode1);
1386 pat = maybe_gen_insn (icode, 3, ops);
1387 if (pat)
1389 /* If PAT is composed of more than one insn, try to add an appropriate
1390 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1391 operand, call expand_binop again, this time without a target. */
1392 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1393 && ! add_equal_note (pat, ops[0].value, binoptab->code,
1394 ops[1].value, ops[2].value))
1396 delete_insns_since (last);
1397 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1398 unsignedp, methods);
1401 emit_insn (pat);
1402 return ops[0].value;
1404 delete_insns_since (last);
1405 return NULL_RTX;
1408 /* Generate code to perform an operation specified by BINOPTAB
1409 on operands OP0 and OP1, with result having machine-mode MODE.
1411 UNSIGNEDP is for the case where we have to widen the operands
1412 to perform the operation. It says to use zero-extension.
1414 If TARGET is nonzero, the value
1415 is generated there, if it is convenient to do so.
1416 In all cases an rtx is returned for the locus of the value;
1417 this may or may not be TARGET. */
1420 expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
1421 rtx target, int unsignedp, enum optab_methods methods)
1423 enum optab_methods next_methods
1424 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1425 ? OPTAB_WIDEN : methods);
1426 enum mode_class mclass;
1427 enum machine_mode wider_mode;
1428 rtx libfunc;
1429 rtx temp;
1430 rtx entry_last = get_last_insn ();
1431 rtx last;
1433 mclass = GET_MODE_CLASS (mode);
1435 /* If subtracting an integer constant, convert this into an addition of
1436 the negated constant. */
1438 if (binoptab == sub_optab && CONST_INT_P (op1))
1440 op1 = negate_rtx (mode, op1);
1441 binoptab = add_optab;
1444 /* Record where to delete back to if we backtrack. */
1445 last = get_last_insn ();
1447 /* If we can do it with a three-operand insn, do so. */
1449 if (methods != OPTAB_MUST_WIDEN
1450 && find_widening_optab_handler (binoptab, mode,
1451 widened_mode (mode, op0, op1), 1)
1452 != CODE_FOR_nothing)
1454 temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1455 unsignedp, methods, last);
1456 if (temp)
1457 return temp;
1460 /* If we were trying to rotate, and that didn't work, try rotating
1461 the other direction before falling back to shifts and bitwise-or. */
1462 if (((binoptab == rotl_optab
1463 && optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
1464 || (binoptab == rotr_optab
1465 && optab_handler (rotl_optab, mode) != CODE_FOR_nothing))
1466 && mclass == MODE_INT)
1468 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1469 rtx newop1;
1470 unsigned int bits = GET_MODE_PRECISION (mode);
1472 if (CONST_INT_P (op1))
1473 newop1 = GEN_INT (bits - INTVAL (op1));
1474 else if (targetm.shift_truncation_mask (mode) == bits - 1)
1475 newop1 = negate_rtx (GET_MODE (op1), op1);
1476 else
1477 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1478 GEN_INT (bits), op1,
1479 NULL_RTX, unsignedp, OPTAB_DIRECT);
1481 temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1482 target, unsignedp, methods, last);
1483 if (temp)
1484 return temp;
1487 /* If this is a multiply, see if we can do a widening operation that
1488 takes operands of this mode and makes a wider mode. */
1490 if (binoptab == smul_optab
1491 && GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1492 && (widening_optab_handler ((unsignedp ? umul_widen_optab
1493 : smul_widen_optab),
1494 GET_MODE_2XWIDER_MODE (mode), mode)
1495 != CODE_FOR_nothing))
1497 temp = expand_binop (GET_MODE_2XWIDER_MODE (mode),
1498 unsignedp ? umul_widen_optab : smul_widen_optab,
1499 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1501 if (temp != 0)
1503 if (GET_MODE_CLASS (mode) == MODE_INT
1504 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1505 return gen_lowpart (mode, temp);
1506 else
1507 return convert_to_mode (mode, temp, unsignedp);
1511 /* Look for a wider mode of the same class for which we think we
1512 can open-code the operation. Check for a widening multiply at the
1513 wider mode as well. */
1515 if (CLASS_HAS_WIDER_MODES_P (mclass)
1516 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1517 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1518 wider_mode != VOIDmode;
1519 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1521 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1522 || (binoptab == smul_optab
1523 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1524 && (find_widening_optab_handler ((unsignedp
1525 ? umul_widen_optab
1526 : smul_widen_optab),
1527 GET_MODE_WIDER_MODE (wider_mode),
1528 mode, 0)
1529 != CODE_FOR_nothing)))
1531 rtx xop0 = op0, xop1 = op1;
1532 int no_extend = 0;
1534 /* For certain integer operations, we need not actually extend
1535 the narrow operands, as long as we will truncate
1536 the results to the same narrowness. */
1538 if ((binoptab == ior_optab || binoptab == and_optab
1539 || binoptab == xor_optab
1540 || binoptab == add_optab || binoptab == sub_optab
1541 || binoptab == smul_optab || binoptab == ashl_optab)
1542 && mclass == MODE_INT)
1544 no_extend = 1;
1545 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1546 xop0, unsignedp);
1547 if (binoptab != ashl_optab)
1548 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1549 xop1, unsignedp);
1552 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1554 /* The second operand of a shift must always be extended. */
1555 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1556 no_extend && binoptab != ashl_optab);
1558 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1559 unsignedp, OPTAB_DIRECT);
1560 if (temp)
1562 if (mclass != MODE_INT
1563 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1565 if (target == 0)
1566 target = gen_reg_rtx (mode);
1567 convert_move (target, temp, 0);
1568 return target;
1570 else
1571 return gen_lowpart (mode, temp);
1573 else
1574 delete_insns_since (last);
1578 /* If operation is commutative,
1579 try to make the first operand a register.
1580 Even better, try to make it the same as the target.
1581 Also try to make the last operand a constant. */
1582 if (commutative_optab_p (binoptab)
1583 && swap_commutative_operands_with_target (target, op0, op1))
1585 temp = op1;
1586 op1 = op0;
1587 op0 = temp;
1590 /* These can be done a word at a time. */
1591 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1592 && mclass == MODE_INT
1593 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1594 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1596 int i;
1597 rtx insns;
1599 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1600 won't be accurate, so use a new target. */
1601 if (target == 0
1602 || target == op0
1603 || target == op1
1604 || !valid_multiword_target_p (target))
1605 target = gen_reg_rtx (mode);
1607 start_sequence ();
1609 /* Do the actual arithmetic. */
1610 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1612 rtx target_piece = operand_subword (target, i, 1, mode);
1613 rtx x = expand_binop (word_mode, binoptab,
1614 operand_subword_force (op0, i, mode),
1615 operand_subword_force (op1, i, mode),
1616 target_piece, unsignedp, next_methods);
1618 if (x == 0)
1619 break;
1621 if (target_piece != x)
1622 emit_move_insn (target_piece, x);
1625 insns = get_insns ();
1626 end_sequence ();
1628 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1630 emit_insn (insns);
1631 return target;
1635 /* Synthesize double word shifts from single word shifts. */
1636 if ((binoptab == lshr_optab || binoptab == ashl_optab
1637 || binoptab == ashr_optab)
1638 && mclass == MODE_INT
1639 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1640 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1641 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode)
1642 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1643 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1644 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1646 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1647 enum machine_mode op1_mode;
1649 double_shift_mask = targetm.shift_truncation_mask (mode);
1650 shift_mask = targetm.shift_truncation_mask (word_mode);
1651 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1653 /* Apply the truncation to constant shifts. */
1654 if (double_shift_mask > 0 && CONST_INT_P (op1))
1655 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1657 if (op1 == CONST0_RTX (op1_mode))
1658 return op0;
1660 /* Make sure that this is a combination that expand_doubleword_shift
1661 can handle. See the comments there for details. */
1662 if (double_shift_mask == 0
1663 || (shift_mask == BITS_PER_WORD - 1
1664 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1666 rtx insns;
1667 rtx into_target, outof_target;
1668 rtx into_input, outof_input;
1669 int left_shift, outof_word;
1671 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1672 won't be accurate, so use a new target. */
1673 if (target == 0
1674 || target == op0
1675 || target == op1
1676 || !valid_multiword_target_p (target))
1677 target = gen_reg_rtx (mode);
1679 start_sequence ();
1681 /* OUTOF_* is the word we are shifting bits away from, and
1682 INTO_* is the word that we are shifting bits towards, thus
1683 they differ depending on the direction of the shift and
1684 WORDS_BIG_ENDIAN. */
1686 left_shift = binoptab == ashl_optab;
1687 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1689 outof_target = operand_subword (target, outof_word, 1, mode);
1690 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1692 outof_input = operand_subword_force (op0, outof_word, mode);
1693 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1695 if (expand_doubleword_shift (op1_mode, binoptab,
1696 outof_input, into_input, op1,
1697 outof_target, into_target,
1698 unsignedp, next_methods, shift_mask))
1700 insns = get_insns ();
1701 end_sequence ();
1703 emit_insn (insns);
1704 return target;
1706 end_sequence ();
1710 /* Synthesize double word rotates from single word shifts. */
1711 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1712 && mclass == MODE_INT
1713 && CONST_INT_P (op1)
1714 && GET_MODE_PRECISION (mode) == 2 * BITS_PER_WORD
1715 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1716 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1718 rtx insns;
1719 rtx into_target, outof_target;
1720 rtx into_input, outof_input;
1721 rtx inter;
1722 int shift_count, left_shift, outof_word;
1724 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1725 won't be accurate, so use a new target. Do this also if target is not
1726 a REG, first because having a register instead may open optimization
1727 opportunities, and second because if target and op0 happen to be MEMs
1728 designating the same location, we would risk clobbering it too early
1729 in the code sequence we generate below. */
1730 if (target == 0
1731 || target == op0
1732 || target == op1
1733 || !REG_P (target)
1734 || !valid_multiword_target_p (target))
1735 target = gen_reg_rtx (mode);
1737 start_sequence ();
1739 shift_count = INTVAL (op1);
1741 /* OUTOF_* is the word we are shifting bits away from, and
1742 INTO_* is the word that we are shifting bits towards, thus
1743 they differ depending on the direction of the shift and
1744 WORDS_BIG_ENDIAN. */
1746 left_shift = (binoptab == rotl_optab);
1747 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1749 outof_target = operand_subword (target, outof_word, 1, mode);
1750 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1752 outof_input = operand_subword_force (op0, outof_word, mode);
1753 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1755 if (shift_count == BITS_PER_WORD)
1757 /* This is just a word swap. */
1758 emit_move_insn (outof_target, into_input);
1759 emit_move_insn (into_target, outof_input);
1760 inter = const0_rtx;
1762 else
1764 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1765 rtx first_shift_count, second_shift_count;
1766 optab reverse_unsigned_shift, unsigned_shift;
1768 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1769 ? lshr_optab : ashl_optab);
1771 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1772 ? ashl_optab : lshr_optab);
1774 if (shift_count > BITS_PER_WORD)
1776 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1777 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1779 else
1781 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1782 second_shift_count = GEN_INT (shift_count);
1785 into_temp1 = expand_binop (word_mode, unsigned_shift,
1786 outof_input, first_shift_count,
1787 NULL_RTX, unsignedp, next_methods);
1788 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1789 into_input, second_shift_count,
1790 NULL_RTX, unsignedp, next_methods);
1792 if (into_temp1 != 0 && into_temp2 != 0)
1793 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1794 into_target, unsignedp, next_methods);
1795 else
1796 inter = 0;
1798 if (inter != 0 && inter != into_target)
1799 emit_move_insn (into_target, inter);
1801 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1802 into_input, first_shift_count,
1803 NULL_RTX, unsignedp, next_methods);
1804 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1805 outof_input, second_shift_count,
1806 NULL_RTX, unsignedp, next_methods);
1808 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1809 inter = expand_binop (word_mode, ior_optab,
1810 outof_temp1, outof_temp2,
1811 outof_target, unsignedp, next_methods);
1813 if (inter != 0 && inter != outof_target)
1814 emit_move_insn (outof_target, inter);
1817 insns = get_insns ();
1818 end_sequence ();
1820 if (inter != 0)
1822 emit_insn (insns);
1823 return target;
1827 /* These can be done a word at a time by propagating carries. */
1828 if ((binoptab == add_optab || binoptab == sub_optab)
1829 && mclass == MODE_INT
1830 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1831 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1833 unsigned int i;
1834 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1835 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1836 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1837 rtx xop0, xop1, xtarget;
1839 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1840 value is one of those, use it. Otherwise, use 1 since it is the
1841 one easiest to get. */
1842 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1843 int normalizep = STORE_FLAG_VALUE;
1844 #else
1845 int normalizep = 1;
1846 #endif
1848 /* Prepare the operands. */
1849 xop0 = force_reg (mode, op0);
1850 xop1 = force_reg (mode, op1);
1852 xtarget = gen_reg_rtx (mode);
1854 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1855 target = xtarget;
1857 /* Indicate for flow that the entire target reg is being set. */
1858 if (REG_P (target))
1859 emit_clobber (xtarget);
1861 /* Do the actual arithmetic. */
1862 for (i = 0; i < nwords; i++)
1864 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1865 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1866 rtx op0_piece = operand_subword_force (xop0, index, mode);
1867 rtx op1_piece = operand_subword_force (xop1, index, mode);
1868 rtx x;
1870 /* Main add/subtract of the input operands. */
1871 x = expand_binop (word_mode, binoptab,
1872 op0_piece, op1_piece,
1873 target_piece, unsignedp, next_methods);
1874 if (x == 0)
1875 break;
1877 if (i + 1 < nwords)
1879 /* Store carry from main add/subtract. */
1880 carry_out = gen_reg_rtx (word_mode);
1881 carry_out = emit_store_flag_force (carry_out,
1882 (binoptab == add_optab
1883 ? LT : GT),
1884 x, op0_piece,
1885 word_mode, 1, normalizep);
1888 if (i > 0)
1890 rtx newx;
1892 /* Add/subtract previous carry to main result. */
1893 newx = expand_binop (word_mode,
1894 normalizep == 1 ? binoptab : otheroptab,
1895 x, carry_in,
1896 NULL_RTX, 1, next_methods);
1898 if (i + 1 < nwords)
1900 /* Get out carry from adding/subtracting carry in. */
1901 rtx carry_tmp = gen_reg_rtx (word_mode);
1902 carry_tmp = emit_store_flag_force (carry_tmp,
1903 (binoptab == add_optab
1904 ? LT : GT),
1905 newx, x,
1906 word_mode, 1, normalizep);
1908 /* Logical-ior the two poss. carry together. */
1909 carry_out = expand_binop (word_mode, ior_optab,
1910 carry_out, carry_tmp,
1911 carry_out, 0, next_methods);
1912 if (carry_out == 0)
1913 break;
1915 emit_move_insn (target_piece, newx);
1917 else
1919 if (x != target_piece)
1920 emit_move_insn (target_piece, x);
1923 carry_in = carry_out;
1926 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1928 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing
1929 || ! rtx_equal_p (target, xtarget))
1931 rtx temp = emit_move_insn (target, xtarget);
1933 set_unique_reg_note (temp,
1934 REG_EQUAL,
1935 gen_rtx_fmt_ee (binoptab->code, mode,
1936 copy_rtx (xop0),
1937 copy_rtx (xop1)));
1939 else
1940 target = xtarget;
1942 return target;
1945 else
1946 delete_insns_since (last);
1949 /* Attempt to synthesize double word multiplies using a sequence of word
1950 mode multiplications. We first attempt to generate a sequence using a
1951 more efficient unsigned widening multiply, and if that fails we then
1952 try using a signed widening multiply. */
1954 if (binoptab == smul_optab
1955 && mclass == MODE_INT
1956 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1957 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
1958 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
1960 rtx product = NULL_RTX;
1961 if (widening_optab_handler (umul_widen_optab, mode, word_mode)
1962 != CODE_FOR_nothing)
1964 product = expand_doubleword_mult (mode, op0, op1, target,
1965 true, methods);
1966 if (!product)
1967 delete_insns_since (last);
1970 if (product == NULL_RTX
1971 && widening_optab_handler (smul_widen_optab, mode, word_mode)
1972 != CODE_FOR_nothing)
1974 product = expand_doubleword_mult (mode, op0, op1, target,
1975 false, methods);
1976 if (!product)
1977 delete_insns_since (last);
1980 if (product != NULL_RTX)
1982 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing)
1984 temp = emit_move_insn (target ? target : product, product);
1985 set_unique_reg_note (temp,
1986 REG_EQUAL,
1987 gen_rtx_fmt_ee (MULT, mode,
1988 copy_rtx (op0),
1989 copy_rtx (op1)));
1991 return product;
1995 /* It can't be open-coded in this mode.
1996 Use a library call if one is available and caller says that's ok. */
1998 libfunc = optab_libfunc (binoptab, mode);
1999 if (libfunc
2000 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
2002 rtx insns;
2003 rtx op1x = op1;
2004 enum machine_mode op1_mode = mode;
2005 rtx value;
2007 start_sequence ();
2009 if (shift_optab_p (binoptab))
2011 op1_mode = targetm.libgcc_shift_count_mode ();
2012 /* Specify unsigned here,
2013 since negative shift counts are meaningless. */
2014 op1x = convert_to_mode (op1_mode, op1, 1);
2017 if (GET_MODE (op0) != VOIDmode
2018 && GET_MODE (op0) != mode)
2019 op0 = convert_to_mode (mode, op0, unsignedp);
2021 /* Pass 1 for NO_QUEUE so we don't lose any increments
2022 if the libcall is cse'd or moved. */
2023 value = emit_library_call_value (libfunc,
2024 NULL_RTX, LCT_CONST, mode, 2,
2025 op0, mode, op1x, op1_mode);
2027 insns = get_insns ();
2028 end_sequence ();
2030 target = gen_reg_rtx (mode);
2031 emit_libcall_block (insns, target, value,
2032 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
2034 return target;
2037 delete_insns_since (last);
2039 /* It can't be done in this mode. Can we do it in a wider mode? */
2041 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
2042 || methods == OPTAB_MUST_WIDEN))
2044 /* Caller says, don't even try. */
2045 delete_insns_since (entry_last);
2046 return 0;
2049 /* Compute the value of METHODS to pass to recursive calls.
2050 Don't allow widening to be tried recursively. */
2052 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
2054 /* Look for a wider mode of the same class for which it appears we can do
2055 the operation. */
2057 if (CLASS_HAS_WIDER_MODES_P (mclass))
2059 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2060 wider_mode != VOIDmode;
2061 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2063 if (find_widening_optab_handler (binoptab, wider_mode, mode, 1)
2064 != CODE_FOR_nothing
2065 || (methods == OPTAB_LIB
2066 && optab_libfunc (binoptab, wider_mode)))
2068 rtx xop0 = op0, xop1 = op1;
2069 int no_extend = 0;
2071 /* For certain integer operations, we need not actually extend
2072 the narrow operands, as long as we will truncate
2073 the results to the same narrowness. */
2075 if ((binoptab == ior_optab || binoptab == and_optab
2076 || binoptab == xor_optab
2077 || binoptab == add_optab || binoptab == sub_optab
2078 || binoptab == smul_optab || binoptab == ashl_optab)
2079 && mclass == MODE_INT)
2080 no_extend = 1;
2082 xop0 = widen_operand (xop0, wider_mode, mode,
2083 unsignedp, no_extend);
2085 /* The second operand of a shift must always be extended. */
2086 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
2087 no_extend && binoptab != ashl_optab);
2089 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
2090 unsignedp, methods);
2091 if (temp)
2093 if (mclass != MODE_INT
2094 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2096 if (target == 0)
2097 target = gen_reg_rtx (mode);
2098 convert_move (target, temp, 0);
2099 return target;
2101 else
2102 return gen_lowpart (mode, temp);
2104 else
2105 delete_insns_since (last);
2110 delete_insns_since (entry_last);
2111 return 0;
2114 /* Expand a binary operator which has both signed and unsigned forms.
2115 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2116 signed operations.
2118 If we widen unsigned operands, we may use a signed wider operation instead
2119 of an unsigned wider operation, since the result would be the same. */
2122 sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
2123 rtx op0, rtx op1, rtx target, int unsignedp,
2124 enum optab_methods methods)
2126 rtx temp;
2127 optab direct_optab = unsignedp ? uoptab : soptab;
2128 struct optab_d wide_soptab;
2130 /* Do it without widening, if possible. */
2131 temp = expand_binop (mode, direct_optab, op0, op1, target,
2132 unsignedp, OPTAB_DIRECT);
2133 if (temp || methods == OPTAB_DIRECT)
2134 return temp;
2136 /* Try widening to a signed int. Make a fake signed optab that
2137 hides any signed insn for direct use. */
2138 wide_soptab = *soptab;
2139 set_optab_handler (&wide_soptab, mode, CODE_FOR_nothing);
2140 /* We don't want to generate new hash table entries from this fake
2141 optab. */
2142 wide_soptab.libcall_gen = NULL;
2144 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2145 unsignedp, OPTAB_WIDEN);
2147 /* For unsigned operands, try widening to an unsigned int. */
2148 if (temp == 0 && unsignedp)
2149 temp = expand_binop (mode, uoptab, op0, op1, target,
2150 unsignedp, OPTAB_WIDEN);
2151 if (temp || methods == OPTAB_WIDEN)
2152 return temp;
2154 /* Use the right width libcall if that exists. */
2155 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
2156 if (temp || methods == OPTAB_LIB)
2157 return temp;
2159 /* Must widen and use a libcall, use either signed or unsigned. */
2160 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2161 unsignedp, methods);
2162 if (temp != 0)
2163 return temp;
2164 if (unsignedp)
2165 return expand_binop (mode, uoptab, op0, op1, target,
2166 unsignedp, methods);
2167 return 0;
2170 /* Generate code to perform an operation specified by UNOPPTAB
2171 on operand OP0, with two results to TARG0 and TARG1.
2172 We assume that the order of the operands for the instruction
2173 is TARG0, TARG1, OP0.
2175 Either TARG0 or TARG1 may be zero, but what that means is that
2176 the result is not actually wanted. We will generate it into
2177 a dummy pseudo-reg and discard it. They may not both be zero.
2179 Returns 1 if this operation can be performed; 0 if not. */
2182 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2183 int unsignedp)
2185 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2186 enum mode_class mclass;
2187 enum machine_mode wider_mode;
2188 rtx entry_last = get_last_insn ();
2189 rtx last;
2191 mclass = GET_MODE_CLASS (mode);
2193 if (!targ0)
2194 targ0 = gen_reg_rtx (mode);
2195 if (!targ1)
2196 targ1 = gen_reg_rtx (mode);
2198 /* Record where to go back to if we fail. */
2199 last = get_last_insn ();
2201 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2203 struct expand_operand ops[3];
2204 enum insn_code icode = optab_handler (unoptab, mode);
2206 create_fixed_operand (&ops[0], targ0);
2207 create_fixed_operand (&ops[1], targ1);
2208 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
2209 if (maybe_expand_insn (icode, 3, ops))
2210 return 1;
2213 /* It can't be done in this mode. Can we do it in a wider mode? */
2215 if (CLASS_HAS_WIDER_MODES_P (mclass))
2217 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2218 wider_mode != VOIDmode;
2219 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2221 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2223 rtx t0 = gen_reg_rtx (wider_mode);
2224 rtx t1 = gen_reg_rtx (wider_mode);
2225 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2227 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2229 convert_move (targ0, t0, unsignedp);
2230 convert_move (targ1, t1, unsignedp);
2231 return 1;
2233 else
2234 delete_insns_since (last);
2239 delete_insns_since (entry_last);
2240 return 0;
2243 /* Generate code to perform an operation specified by BINOPTAB
2244 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2245 We assume that the order of the operands for the instruction
2246 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2247 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2249 Either TARG0 or TARG1 may be zero, but what that means is that
2250 the result is not actually wanted. We will generate it into
2251 a dummy pseudo-reg and discard it. They may not both be zero.
2253 Returns 1 if this operation can be performed; 0 if not. */
2256 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2257 int unsignedp)
2259 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2260 enum mode_class mclass;
2261 enum machine_mode wider_mode;
2262 rtx entry_last = get_last_insn ();
2263 rtx last;
2265 mclass = GET_MODE_CLASS (mode);
2267 if (!targ0)
2268 targ0 = gen_reg_rtx (mode);
2269 if (!targ1)
2270 targ1 = gen_reg_rtx (mode);
2272 /* Record where to go back to if we fail. */
2273 last = get_last_insn ();
2275 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2277 struct expand_operand ops[4];
2278 enum insn_code icode = optab_handler (binoptab, mode);
2279 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2280 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2281 rtx xop0 = op0, xop1 = op1;
2283 /* If we are optimizing, force expensive constants into a register. */
2284 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2285 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2287 create_fixed_operand (&ops[0], targ0);
2288 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2289 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
2290 create_fixed_operand (&ops[3], targ1);
2291 if (maybe_expand_insn (icode, 4, ops))
2292 return 1;
2293 delete_insns_since (last);
2296 /* It can't be done in this mode. Can we do it in a wider mode? */
2298 if (CLASS_HAS_WIDER_MODES_P (mclass))
2300 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2301 wider_mode != VOIDmode;
2302 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2304 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2306 rtx t0 = gen_reg_rtx (wider_mode);
2307 rtx t1 = gen_reg_rtx (wider_mode);
2308 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2309 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2311 if (expand_twoval_binop (binoptab, cop0, cop1,
2312 t0, t1, unsignedp))
2314 convert_move (targ0, t0, unsignedp);
2315 convert_move (targ1, t1, unsignedp);
2316 return 1;
2318 else
2319 delete_insns_since (last);
2324 delete_insns_since (entry_last);
2325 return 0;
2328 /* Expand the two-valued library call indicated by BINOPTAB, but
2329 preserve only one of the values. If TARG0 is non-NULL, the first
2330 value is placed into TARG0; otherwise the second value is placed
2331 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2332 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2333 This routine assumes that the value returned by the library call is
2334 as if the return value was of an integral mode twice as wide as the
2335 mode of OP0. Returns 1 if the call was successful. */
2337 bool
2338 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2339 rtx targ0, rtx targ1, enum rtx_code code)
2341 enum machine_mode mode;
2342 enum machine_mode libval_mode;
2343 rtx libval;
2344 rtx insns;
2345 rtx libfunc;
2347 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2348 gcc_assert (!targ0 != !targ1);
2350 mode = GET_MODE (op0);
2351 libfunc = optab_libfunc (binoptab, mode);
2352 if (!libfunc)
2353 return false;
2355 /* The value returned by the library function will have twice as
2356 many bits as the nominal MODE. */
2357 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2358 MODE_INT);
2359 start_sequence ();
2360 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2361 libval_mode, 2,
2362 op0, mode,
2363 op1, mode);
2364 /* Get the part of VAL containing the value that we want. */
2365 libval = simplify_gen_subreg (mode, libval, libval_mode,
2366 targ0 ? 0 : GET_MODE_SIZE (mode));
2367 insns = get_insns ();
2368 end_sequence ();
2369 /* Move the into the desired location. */
2370 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2371 gen_rtx_fmt_ee (code, mode, op0, op1));
2373 return true;
2377 /* Wrapper around expand_unop which takes an rtx code to specify
2378 the operation to perform, not an optab pointer. All other
2379 arguments are the same. */
2381 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2382 rtx target, int unsignedp)
2384 optab unop = code_to_optab[(int) code];
2385 gcc_assert (unop);
2387 return expand_unop (mode, unop, op0, target, unsignedp);
2390 /* Try calculating
2391 (clz:narrow x)
2393 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2395 A similar operation can be used for clrsb. UNOPTAB says which operation
2396 we are trying to expand. */
2397 static rtx
2398 widen_leading (enum machine_mode mode, rtx op0, rtx target, optab unoptab)
2400 enum mode_class mclass = GET_MODE_CLASS (mode);
2401 if (CLASS_HAS_WIDER_MODES_P (mclass))
2403 enum machine_mode wider_mode;
2404 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2405 wider_mode != VOIDmode;
2406 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2408 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2410 rtx xop0, temp, last;
2412 last = get_last_insn ();
2414 if (target == 0)
2415 target = gen_reg_rtx (mode);
2416 xop0 = widen_operand (op0, wider_mode, mode,
2417 unoptab != clrsb_optab, false);
2418 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2419 unoptab != clrsb_optab);
2420 if (temp != 0)
2421 temp = expand_binop (wider_mode, sub_optab, temp,
2422 GEN_INT (GET_MODE_PRECISION (wider_mode)
2423 - GET_MODE_PRECISION (mode)),
2424 target, true, OPTAB_DIRECT);
2425 if (temp == 0)
2426 delete_insns_since (last);
2428 return temp;
2432 return 0;
2435 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2436 quantities, choosing which based on whether the high word is nonzero. */
2437 static rtx
2438 expand_doubleword_clz (enum machine_mode mode, rtx op0, rtx target)
2440 rtx xop0 = force_reg (mode, op0);
2441 rtx subhi = gen_highpart (word_mode, xop0);
2442 rtx sublo = gen_lowpart (word_mode, xop0);
2443 rtx hi0_label = gen_label_rtx ();
2444 rtx after_label = gen_label_rtx ();
2445 rtx seq, temp, result;
2447 /* If we were not given a target, use a word_mode register, not a
2448 'mode' register. The result will fit, and nobody is expecting
2449 anything bigger (the return type of __builtin_clz* is int). */
2450 if (!target)
2451 target = gen_reg_rtx (word_mode);
2453 /* In any case, write to a word_mode scratch in both branches of the
2454 conditional, so we can ensure there is a single move insn setting
2455 'target' to tag a REG_EQUAL note on. */
2456 result = gen_reg_rtx (word_mode);
2458 start_sequence ();
2460 /* If the high word is not equal to zero,
2461 then clz of the full value is clz of the high word. */
2462 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2463 word_mode, true, hi0_label);
2465 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2466 if (!temp)
2467 goto fail;
2469 if (temp != result)
2470 convert_move (result, temp, true);
2472 emit_jump_insn (gen_jump (after_label));
2473 emit_barrier ();
2475 /* Else clz of the full value is clz of the low word plus the number
2476 of bits in the high word. */
2477 emit_label (hi0_label);
2479 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2480 if (!temp)
2481 goto fail;
2482 temp = expand_binop (word_mode, add_optab, temp,
2483 GEN_INT (GET_MODE_BITSIZE (word_mode)),
2484 result, true, OPTAB_DIRECT);
2485 if (!temp)
2486 goto fail;
2487 if (temp != result)
2488 convert_move (result, temp, true);
2490 emit_label (after_label);
2491 convert_move (target, result, true);
2493 seq = get_insns ();
2494 end_sequence ();
2496 add_equal_note (seq, target, CLZ, xop0, 0);
2497 emit_insn (seq);
2498 return target;
2500 fail:
2501 end_sequence ();
2502 return 0;
2505 /* Try calculating
2506 (bswap:narrow x)
2508 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2509 static rtx
2510 widen_bswap (enum machine_mode mode, rtx op0, rtx target)
2512 enum mode_class mclass = GET_MODE_CLASS (mode);
2513 enum machine_mode wider_mode;
2514 rtx x, last;
2516 if (!CLASS_HAS_WIDER_MODES_P (mclass))
2517 return NULL_RTX;
2519 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2520 wider_mode != VOIDmode;
2521 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2522 if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing)
2523 goto found;
2524 return NULL_RTX;
2526 found:
2527 last = get_last_insn ();
2529 x = widen_operand (op0, wider_mode, mode, true, true);
2530 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2532 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2533 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2534 if (x != 0)
2535 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2536 GET_MODE_BITSIZE (wider_mode)
2537 - GET_MODE_BITSIZE (mode),
2538 NULL_RTX, true);
2540 if (x != 0)
2542 if (target == 0)
2543 target = gen_reg_rtx (mode);
2544 emit_move_insn (target, gen_lowpart (mode, x));
2546 else
2547 delete_insns_since (last);
2549 return target;
2552 /* Try calculating bswap as two bswaps of two word-sized operands. */
2554 static rtx
2555 expand_doubleword_bswap (enum machine_mode mode, rtx op, rtx target)
2557 rtx t0, t1;
2559 t1 = expand_unop (word_mode, bswap_optab,
2560 operand_subword_force (op, 0, mode), NULL_RTX, true);
2561 t0 = expand_unop (word_mode, bswap_optab,
2562 operand_subword_force (op, 1, mode), NULL_RTX, true);
2564 if (target == 0 || !valid_multiword_target_p (target))
2565 target = gen_reg_rtx (mode);
2566 if (REG_P (target))
2567 emit_clobber (target);
2568 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2569 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2571 return target;
2574 /* Try calculating (parity x) as (and (popcount x) 1), where
2575 popcount can also be done in a wider mode. */
2576 static rtx
2577 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2579 enum mode_class mclass = GET_MODE_CLASS (mode);
2580 if (CLASS_HAS_WIDER_MODES_P (mclass))
2582 enum machine_mode wider_mode;
2583 for (wider_mode = mode; wider_mode != VOIDmode;
2584 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2586 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2588 rtx xop0, temp, last;
2590 last = get_last_insn ();
2592 if (target == 0)
2593 target = gen_reg_rtx (mode);
2594 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2595 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2596 true);
2597 if (temp != 0)
2598 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2599 target, true, OPTAB_DIRECT);
2600 if (temp == 0)
2601 delete_insns_since (last);
2603 return temp;
2607 return 0;
2610 /* Try calculating ctz(x) as K - clz(x & -x) ,
2611 where K is GET_MODE_PRECISION(mode) - 1.
2613 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2614 don't have to worry about what the hardware does in that case. (If
2615 the clz instruction produces the usual value at 0, which is K, the
2616 result of this code sequence will be -1; expand_ffs, below, relies
2617 on this. It might be nice to have it be K instead, for consistency
2618 with the (very few) processors that provide a ctz with a defined
2619 value, but that would take one more instruction, and it would be
2620 less convenient for expand_ffs anyway. */
2622 static rtx
2623 expand_ctz (enum machine_mode mode, rtx op0, rtx target)
2625 rtx seq, temp;
2627 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2628 return 0;
2630 start_sequence ();
2632 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2633 if (temp)
2634 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2635 true, OPTAB_DIRECT);
2636 if (temp)
2637 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2638 if (temp)
2639 temp = expand_binop (mode, sub_optab, GEN_INT (GET_MODE_PRECISION (mode) - 1),
2640 temp, target,
2641 true, OPTAB_DIRECT);
2642 if (temp == 0)
2644 end_sequence ();
2645 return 0;
2648 seq = get_insns ();
2649 end_sequence ();
2651 add_equal_note (seq, temp, CTZ, op0, 0);
2652 emit_insn (seq);
2653 return temp;
2657 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2658 else with the sequence used by expand_clz.
2660 The ffs builtin promises to return zero for a zero value and ctz/clz
2661 may have an undefined value in that case. If they do not give us a
2662 convenient value, we have to generate a test and branch. */
2663 static rtx
2664 expand_ffs (enum machine_mode mode, rtx op0, rtx target)
2666 HOST_WIDE_INT val = 0;
2667 bool defined_at_zero = false;
2668 rtx temp, seq;
2670 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2672 start_sequence ();
2674 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2675 if (!temp)
2676 goto fail;
2678 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2680 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2682 start_sequence ();
2683 temp = expand_ctz (mode, op0, 0);
2684 if (!temp)
2685 goto fail;
2687 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2689 defined_at_zero = true;
2690 val = (GET_MODE_PRECISION (mode) - 1) - val;
2693 else
2694 return 0;
2696 if (defined_at_zero && val == -1)
2697 /* No correction needed at zero. */;
2698 else
2700 /* We don't try to do anything clever with the situation found
2701 on some processors (eg Alpha) where ctz(0:mode) ==
2702 bitsize(mode). If someone can think of a way to send N to -1
2703 and leave alone all values in the range 0..N-1 (where N is a
2704 power of two), cheaper than this test-and-branch, please add it.
2706 The test-and-branch is done after the operation itself, in case
2707 the operation sets condition codes that can be recycled for this.
2708 (This is true on i386, for instance.) */
2710 rtx nonzero_label = gen_label_rtx ();
2711 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2712 mode, true, nonzero_label);
2714 convert_move (temp, GEN_INT (-1), false);
2715 emit_label (nonzero_label);
2718 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2719 to produce a value in the range 0..bitsize. */
2720 temp = expand_binop (mode, add_optab, temp, GEN_INT (1),
2721 target, false, OPTAB_DIRECT);
2722 if (!temp)
2723 goto fail;
2725 seq = get_insns ();
2726 end_sequence ();
2728 add_equal_note (seq, temp, FFS, op0, 0);
2729 emit_insn (seq);
2730 return temp;
2732 fail:
2733 end_sequence ();
2734 return 0;
2737 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2738 conditions, VAL may already be a SUBREG against which we cannot generate
2739 a further SUBREG. In this case, we expect forcing the value into a
2740 register will work around the situation. */
2742 static rtx
2743 lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2744 enum machine_mode imode)
2746 rtx ret;
2747 ret = lowpart_subreg (omode, val, imode);
2748 if (ret == NULL)
2750 val = force_reg (imode, val);
2751 ret = lowpart_subreg (omode, val, imode);
2752 gcc_assert (ret != NULL);
2754 return ret;
2757 /* Expand a floating point absolute value or negation operation via a
2758 logical operation on the sign bit. */
2760 static rtx
2761 expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2762 rtx op0, rtx target)
2764 const struct real_format *fmt;
2765 int bitpos, word, nwords, i;
2766 enum machine_mode imode;
2767 double_int mask;
2768 rtx temp, insns;
2770 /* The format has to have a simple sign bit. */
2771 fmt = REAL_MODE_FORMAT (mode);
2772 if (fmt == NULL)
2773 return NULL_RTX;
2775 bitpos = fmt->signbit_rw;
2776 if (bitpos < 0)
2777 return NULL_RTX;
2779 /* Don't create negative zeros if the format doesn't support them. */
2780 if (code == NEG && !fmt->has_signed_zero)
2781 return NULL_RTX;
2783 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2785 imode = int_mode_for_mode (mode);
2786 if (imode == BLKmode)
2787 return NULL_RTX;
2788 word = 0;
2789 nwords = 1;
2791 else
2793 imode = word_mode;
2795 if (FLOAT_WORDS_BIG_ENDIAN)
2796 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2797 else
2798 word = bitpos / BITS_PER_WORD;
2799 bitpos = bitpos % BITS_PER_WORD;
2800 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2803 mask = double_int_setbit (double_int_zero, bitpos);
2804 if (code == ABS)
2805 mask = double_int_not (mask);
2807 if (target == 0
2808 || target == op0
2809 || (nwords > 1 && !valid_multiword_target_p (target)))
2810 target = gen_reg_rtx (mode);
2812 if (nwords > 1)
2814 start_sequence ();
2816 for (i = 0; i < nwords; ++i)
2818 rtx targ_piece = operand_subword (target, i, 1, mode);
2819 rtx op0_piece = operand_subword_force (op0, i, mode);
2821 if (i == word)
2823 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2824 op0_piece,
2825 immed_double_int_const (mask, imode),
2826 targ_piece, 1, OPTAB_LIB_WIDEN);
2827 if (temp != targ_piece)
2828 emit_move_insn (targ_piece, temp);
2830 else
2831 emit_move_insn (targ_piece, op0_piece);
2834 insns = get_insns ();
2835 end_sequence ();
2837 emit_insn (insns);
2839 else
2841 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2842 gen_lowpart (imode, op0),
2843 immed_double_int_const (mask, imode),
2844 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2845 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2847 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2848 gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
2851 return target;
2854 /* As expand_unop, but will fail rather than attempt the operation in a
2855 different mode or with a libcall. */
2856 static rtx
2857 expand_unop_direct (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2858 int unsignedp)
2860 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2862 struct expand_operand ops[2];
2863 enum insn_code icode = optab_handler (unoptab, mode);
2864 rtx last = get_last_insn ();
2865 rtx pat;
2867 create_output_operand (&ops[0], target, mode);
2868 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2869 pat = maybe_gen_insn (icode, 2, ops);
2870 if (pat)
2872 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2873 && ! add_equal_note (pat, ops[0].value, unoptab->code,
2874 ops[1].value, NULL_RTX))
2876 delete_insns_since (last);
2877 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2880 emit_insn (pat);
2882 return ops[0].value;
2885 return 0;
2888 /* Generate code to perform an operation specified by UNOPTAB
2889 on operand OP0, with result having machine-mode MODE.
2891 UNSIGNEDP is for the case where we have to widen the operands
2892 to perform the operation. It says to use zero-extension.
2894 If TARGET is nonzero, the value
2895 is generated there, if it is convenient to do so.
2896 In all cases an rtx is returned for the locus of the value;
2897 this may or may not be TARGET. */
2900 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2901 int unsignedp)
2903 enum mode_class mclass = GET_MODE_CLASS (mode);
2904 enum machine_mode wider_mode;
2905 rtx temp;
2906 rtx libfunc;
2908 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
2909 if (temp)
2910 return temp;
2912 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2914 /* Widening (or narrowing) clz needs special treatment. */
2915 if (unoptab == clz_optab)
2917 temp = widen_leading (mode, op0, target, unoptab);
2918 if (temp)
2919 return temp;
2921 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2922 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2924 temp = expand_doubleword_clz (mode, op0, target);
2925 if (temp)
2926 return temp;
2929 goto try_libcall;
2932 if (unoptab == clrsb_optab)
2934 temp = widen_leading (mode, op0, target, unoptab);
2935 if (temp)
2936 return temp;
2937 goto try_libcall;
2940 /* Widening (or narrowing) bswap needs special treatment. */
2941 if (unoptab == bswap_optab)
2943 temp = widen_bswap (mode, op0, target);
2944 if (temp)
2945 return temp;
2947 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2948 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2950 temp = expand_doubleword_bswap (mode, op0, target);
2951 if (temp)
2952 return temp;
2955 goto try_libcall;
2958 if (CLASS_HAS_WIDER_MODES_P (mclass))
2959 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2960 wider_mode != VOIDmode;
2961 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2963 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2965 rtx xop0 = op0;
2966 rtx last = get_last_insn ();
2968 /* For certain operations, we need not actually extend
2969 the narrow operand, as long as we will truncate the
2970 results to the same narrowness. */
2972 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2973 (unoptab == neg_optab
2974 || unoptab == one_cmpl_optab)
2975 && mclass == MODE_INT);
2977 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2978 unsignedp);
2980 if (temp)
2982 if (mclass != MODE_INT
2983 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2985 if (target == 0)
2986 target = gen_reg_rtx (mode);
2987 convert_move (target, temp, 0);
2988 return target;
2990 else
2991 return gen_lowpart (mode, temp);
2993 else
2994 delete_insns_since (last);
2998 /* These can be done a word at a time. */
2999 if (unoptab == one_cmpl_optab
3000 && mclass == MODE_INT
3001 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
3002 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3004 int i;
3005 rtx insns;
3007 if (target == 0 || target == op0 || !valid_multiword_target_p (target))
3008 target = gen_reg_rtx (mode);
3010 start_sequence ();
3012 /* Do the actual arithmetic. */
3013 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
3015 rtx target_piece = operand_subword (target, i, 1, mode);
3016 rtx x = expand_unop (word_mode, unoptab,
3017 operand_subword_force (op0, i, mode),
3018 target_piece, unsignedp);
3020 if (target_piece != x)
3021 emit_move_insn (target_piece, x);
3024 insns = get_insns ();
3025 end_sequence ();
3027 emit_insn (insns);
3028 return target;
3031 if (unoptab->code == NEG)
3033 /* Try negating floating point values by flipping the sign bit. */
3034 if (SCALAR_FLOAT_MODE_P (mode))
3036 temp = expand_absneg_bit (NEG, mode, op0, target);
3037 if (temp)
3038 return temp;
3041 /* If there is no negation pattern, and we have no negative zero,
3042 try subtracting from zero. */
3043 if (!HONOR_SIGNED_ZEROS (mode))
3045 temp = expand_binop (mode, (unoptab == negv_optab
3046 ? subv_optab : sub_optab),
3047 CONST0_RTX (mode), op0, target,
3048 unsignedp, OPTAB_DIRECT);
3049 if (temp)
3050 return temp;
3054 /* Try calculating parity (x) as popcount (x) % 2. */
3055 if (unoptab == parity_optab)
3057 temp = expand_parity (mode, op0, target);
3058 if (temp)
3059 return temp;
3062 /* Try implementing ffs (x) in terms of clz (x). */
3063 if (unoptab == ffs_optab)
3065 temp = expand_ffs (mode, op0, target);
3066 if (temp)
3067 return temp;
3070 /* Try implementing ctz (x) in terms of clz (x). */
3071 if (unoptab == ctz_optab)
3073 temp = expand_ctz (mode, op0, target);
3074 if (temp)
3075 return temp;
3078 try_libcall:
3079 /* Now try a library call in this mode. */
3080 libfunc = optab_libfunc (unoptab, mode);
3081 if (libfunc)
3083 rtx insns;
3084 rtx value;
3085 rtx eq_value;
3086 enum machine_mode outmode = mode;
3088 /* All of these functions return small values. Thus we choose to
3089 have them return something that isn't a double-word. */
3090 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3091 || unoptab == clrsb_optab || unoptab == popcount_optab
3092 || unoptab == parity_optab)
3093 outmode
3094 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
3095 optab_libfunc (unoptab, mode)));
3097 start_sequence ();
3099 /* Pass 1 for NO_QUEUE so we don't lose any increments
3100 if the libcall is cse'd or moved. */
3101 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
3102 1, op0, mode);
3103 insns = get_insns ();
3104 end_sequence ();
3106 target = gen_reg_rtx (outmode);
3107 eq_value = gen_rtx_fmt_e (unoptab->code, mode, op0);
3108 if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode))
3109 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
3110 else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
3111 eq_value = simplify_gen_unary (ZERO_EXTEND, outmode, eq_value, mode);
3112 emit_libcall_block (insns, target, value, eq_value);
3114 return target;
3117 /* It can't be done in this mode. Can we do it in a wider mode? */
3119 if (CLASS_HAS_WIDER_MODES_P (mclass))
3121 for (wider_mode = GET_MODE_WIDER_MODE (mode);
3122 wider_mode != VOIDmode;
3123 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3125 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
3126 || optab_libfunc (unoptab, wider_mode))
3128 rtx xop0 = op0;
3129 rtx last = get_last_insn ();
3131 /* For certain operations, we need not actually extend
3132 the narrow operand, as long as we will truncate the
3133 results to the same narrowness. */
3135 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3136 (unoptab == neg_optab
3137 || unoptab == one_cmpl_optab)
3138 && mclass == MODE_INT);
3140 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3141 unsignedp);
3143 /* If we are generating clz using wider mode, adjust the
3144 result. Similarly for clrsb. */
3145 if ((unoptab == clz_optab || unoptab == clrsb_optab)
3146 && temp != 0)
3147 temp = expand_binop (wider_mode, sub_optab, temp,
3148 GEN_INT (GET_MODE_PRECISION (wider_mode)
3149 - GET_MODE_PRECISION (mode)),
3150 target, true, OPTAB_DIRECT);
3152 if (temp)
3154 if (mclass != MODE_INT)
3156 if (target == 0)
3157 target = gen_reg_rtx (mode);
3158 convert_move (target, temp, 0);
3159 return target;
3161 else
3162 return gen_lowpart (mode, temp);
3164 else
3165 delete_insns_since (last);
3170 /* One final attempt at implementing negation via subtraction,
3171 this time allowing widening of the operand. */
3172 if (unoptab->code == NEG && !HONOR_SIGNED_ZEROS (mode))
3174 rtx temp;
3175 temp = expand_binop (mode,
3176 unoptab == negv_optab ? subv_optab : sub_optab,
3177 CONST0_RTX (mode), op0,
3178 target, unsignedp, OPTAB_LIB_WIDEN);
3179 if (temp)
3180 return temp;
3183 return 0;
3186 /* Emit code to compute the absolute value of OP0, with result to
3187 TARGET if convenient. (TARGET may be 0.) The return value says
3188 where the result actually is to be found.
3190 MODE is the mode of the operand; the mode of the result is
3191 different but can be deduced from MODE.
3196 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
3197 int result_unsignedp)
3199 rtx temp;
3201 if (! flag_trapv)
3202 result_unsignedp = 1;
3204 /* First try to do it with a special abs instruction. */
3205 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3206 op0, target, 0);
3207 if (temp != 0)
3208 return temp;
3210 /* For floating point modes, try clearing the sign bit. */
3211 if (SCALAR_FLOAT_MODE_P (mode))
3213 temp = expand_absneg_bit (ABS, mode, op0, target);
3214 if (temp)
3215 return temp;
3218 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3219 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3220 && !HONOR_SIGNED_ZEROS (mode))
3222 rtx last = get_last_insn ();
3224 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
3225 if (temp != 0)
3226 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3227 OPTAB_WIDEN);
3229 if (temp != 0)
3230 return temp;
3232 delete_insns_since (last);
3235 /* If this machine has expensive jumps, we can do integer absolute
3236 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3237 where W is the width of MODE. */
3239 if (GET_MODE_CLASS (mode) == MODE_INT
3240 && BRANCH_COST (optimize_insn_for_speed_p (),
3241 false) >= 2)
3243 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3244 GET_MODE_PRECISION (mode) - 1,
3245 NULL_RTX, 0);
3247 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3248 OPTAB_LIB_WIDEN);
3249 if (temp != 0)
3250 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3251 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3253 if (temp != 0)
3254 return temp;
3257 return NULL_RTX;
3261 expand_abs (enum machine_mode mode, rtx op0, rtx target,
3262 int result_unsignedp, int safe)
3264 rtx temp, op1;
3266 if (! flag_trapv)
3267 result_unsignedp = 1;
3269 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3270 if (temp != 0)
3271 return temp;
3273 /* If that does not win, use conditional jump and negate. */
3275 /* It is safe to use the target if it is the same
3276 as the source if this is also a pseudo register */
3277 if (op0 == target && REG_P (op0)
3278 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3279 safe = 1;
3281 op1 = gen_label_rtx ();
3282 if (target == 0 || ! safe
3283 || GET_MODE (target) != mode
3284 || (MEM_P (target) && MEM_VOLATILE_P (target))
3285 || (REG_P (target)
3286 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3287 target = gen_reg_rtx (mode);
3289 emit_move_insn (target, op0);
3290 NO_DEFER_POP;
3292 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3293 NULL_RTX, NULL_RTX, op1, -1);
3295 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3296 target, target, 0);
3297 if (op0 != target)
3298 emit_move_insn (target, op0);
3299 emit_label (op1);
3300 OK_DEFER_POP;
3301 return target;
3304 /* Emit code to compute the one's complement absolute value of OP0
3305 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3306 (TARGET may be NULL_RTX.) The return value says where the result
3307 actually is to be found.
3309 MODE is the mode of the operand; the mode of the result is
3310 different but can be deduced from MODE. */
3313 expand_one_cmpl_abs_nojump (enum machine_mode mode, rtx op0, rtx target)
3315 rtx temp;
3317 /* Not applicable for floating point modes. */
3318 if (FLOAT_MODE_P (mode))
3319 return NULL_RTX;
3321 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3322 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3324 rtx last = get_last_insn ();
3326 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3327 if (temp != 0)
3328 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3329 OPTAB_WIDEN);
3331 if (temp != 0)
3332 return temp;
3334 delete_insns_since (last);
3337 /* If this machine has expensive jumps, we can do one's complement
3338 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3340 if (GET_MODE_CLASS (mode) == MODE_INT
3341 && BRANCH_COST (optimize_insn_for_speed_p (),
3342 false) >= 2)
3344 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3345 GET_MODE_PRECISION (mode) - 1,
3346 NULL_RTX, 0);
3348 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3349 OPTAB_LIB_WIDEN);
3351 if (temp != 0)
3352 return temp;
3355 return NULL_RTX;
3358 /* A subroutine of expand_copysign, perform the copysign operation using the
3359 abs and neg primitives advertised to exist on the target. The assumption
3360 is that we have a split register file, and leaving op0 in fp registers,
3361 and not playing with subregs so much, will help the register allocator. */
3363 static rtx
3364 expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3365 int bitpos, bool op0_is_abs)
3367 enum machine_mode imode;
3368 enum insn_code icode;
3369 rtx sign, label;
3371 if (target == op1)
3372 target = NULL_RTX;
3374 /* Check if the back end provides an insn that handles signbit for the
3375 argument's mode. */
3376 icode = optab_handler (signbit_optab, mode);
3377 if (icode != CODE_FOR_nothing)
3379 imode = insn_data[(int) icode].operand[0].mode;
3380 sign = gen_reg_rtx (imode);
3381 emit_unop_insn (icode, sign, op1, UNKNOWN);
3383 else
3385 double_int mask;
3387 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3389 imode = int_mode_for_mode (mode);
3390 if (imode == BLKmode)
3391 return NULL_RTX;
3392 op1 = gen_lowpart (imode, op1);
3394 else
3396 int word;
3398 imode = word_mode;
3399 if (FLOAT_WORDS_BIG_ENDIAN)
3400 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3401 else
3402 word = bitpos / BITS_PER_WORD;
3403 bitpos = bitpos % BITS_PER_WORD;
3404 op1 = operand_subword_force (op1, word, mode);
3407 mask = double_int_setbit (double_int_zero, bitpos);
3409 sign = expand_binop (imode, and_optab, op1,
3410 immed_double_int_const (mask, imode),
3411 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3414 if (!op0_is_abs)
3416 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3417 if (op0 == NULL)
3418 return NULL_RTX;
3419 target = op0;
3421 else
3423 if (target == NULL_RTX)
3424 target = copy_to_reg (op0);
3425 else
3426 emit_move_insn (target, op0);
3429 label = gen_label_rtx ();
3430 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3432 if (GET_CODE (op0) == CONST_DOUBLE)
3433 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3434 else
3435 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3436 if (op0 != target)
3437 emit_move_insn (target, op0);
3439 emit_label (label);
3441 return target;
3445 /* A subroutine of expand_copysign, perform the entire copysign operation
3446 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3447 is true if op0 is known to have its sign bit clear. */
3449 static rtx
3450 expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3451 int bitpos, bool op0_is_abs)
3453 enum machine_mode imode;
3454 double_int mask;
3455 int word, nwords, i;
3456 rtx temp, insns;
3458 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3460 imode = int_mode_for_mode (mode);
3461 if (imode == BLKmode)
3462 return NULL_RTX;
3463 word = 0;
3464 nwords = 1;
3466 else
3468 imode = word_mode;
3470 if (FLOAT_WORDS_BIG_ENDIAN)
3471 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3472 else
3473 word = bitpos / BITS_PER_WORD;
3474 bitpos = bitpos % BITS_PER_WORD;
3475 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3478 mask = double_int_setbit (double_int_zero, bitpos);
3480 if (target == 0
3481 || target == op0
3482 || target == op1
3483 || (nwords > 1 && !valid_multiword_target_p (target)))
3484 target = gen_reg_rtx (mode);
3486 if (nwords > 1)
3488 start_sequence ();
3490 for (i = 0; i < nwords; ++i)
3492 rtx targ_piece = operand_subword (target, i, 1, mode);
3493 rtx op0_piece = operand_subword_force (op0, i, mode);
3495 if (i == word)
3497 if (!op0_is_abs)
3498 op0_piece
3499 = expand_binop (imode, and_optab, op0_piece,
3500 immed_double_int_const (double_int_not (mask),
3501 imode),
3502 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3504 op1 = expand_binop (imode, and_optab,
3505 operand_subword_force (op1, i, mode),
3506 immed_double_int_const (mask, imode),
3507 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3509 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3510 targ_piece, 1, OPTAB_LIB_WIDEN);
3511 if (temp != targ_piece)
3512 emit_move_insn (targ_piece, temp);
3514 else
3515 emit_move_insn (targ_piece, op0_piece);
3518 insns = get_insns ();
3519 end_sequence ();
3521 emit_insn (insns);
3523 else
3525 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3526 immed_double_int_const (mask, imode),
3527 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3529 op0 = gen_lowpart (imode, op0);
3530 if (!op0_is_abs)
3531 op0 = expand_binop (imode, and_optab, op0,
3532 immed_double_int_const (double_int_not (mask),
3533 imode),
3534 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3536 temp = expand_binop (imode, ior_optab, op0, op1,
3537 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3538 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3541 return target;
3544 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3545 scalar floating point mode. Return NULL if we do not know how to
3546 expand the operation inline. */
3549 expand_copysign (rtx op0, rtx op1, rtx target)
3551 enum machine_mode mode = GET_MODE (op0);
3552 const struct real_format *fmt;
3553 bool op0_is_abs;
3554 rtx temp;
3556 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3557 gcc_assert (GET_MODE (op1) == mode);
3559 /* First try to do it with a special instruction. */
3560 temp = expand_binop (mode, copysign_optab, op0, op1,
3561 target, 0, OPTAB_DIRECT);
3562 if (temp)
3563 return temp;
3565 fmt = REAL_MODE_FORMAT (mode);
3566 if (fmt == NULL || !fmt->has_signed_zero)
3567 return NULL_RTX;
3569 op0_is_abs = false;
3570 if (GET_CODE (op0) == CONST_DOUBLE)
3572 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3573 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3574 op0_is_abs = true;
3577 if (fmt->signbit_ro >= 0
3578 && (GET_CODE (op0) == CONST_DOUBLE
3579 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3580 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3582 temp = expand_copysign_absneg (mode, op0, op1, target,
3583 fmt->signbit_ro, op0_is_abs);
3584 if (temp)
3585 return temp;
3588 if (fmt->signbit_rw < 0)
3589 return NULL_RTX;
3590 return expand_copysign_bit (mode, op0, op1, target,
3591 fmt->signbit_rw, op0_is_abs);
3594 /* Generate an instruction whose insn-code is INSN_CODE,
3595 with two operands: an output TARGET and an input OP0.
3596 TARGET *must* be nonzero, and the output is always stored there.
3597 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3598 the value that is stored into TARGET.
3600 Return false if expansion failed. */
3602 bool
3603 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3604 enum rtx_code code)
3606 struct expand_operand ops[2];
3607 rtx pat;
3609 create_output_operand (&ops[0], target, GET_MODE (target));
3610 create_input_operand (&ops[1], op0, GET_MODE (op0));
3611 pat = maybe_gen_insn (icode, 2, ops);
3612 if (!pat)
3613 return false;
3615 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3616 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX);
3618 emit_insn (pat);
3620 if (ops[0].value != target)
3621 emit_move_insn (target, ops[0].value);
3622 return true;
3624 /* Generate an instruction whose insn-code is INSN_CODE,
3625 with two operands: an output TARGET and an input OP0.
3626 TARGET *must* be nonzero, and the output is always stored there.
3627 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3628 the value that is stored into TARGET. */
3630 void
3631 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3633 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3634 gcc_assert (ok);
3637 struct no_conflict_data
3639 rtx target, first, insn;
3640 bool must_stay;
3643 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3644 the currently examined clobber / store has to stay in the list of
3645 insns that constitute the actual libcall block. */
3646 static void
3647 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3649 struct no_conflict_data *p= (struct no_conflict_data *) p0;
3651 /* If this inns directly contributes to setting the target, it must stay. */
3652 if (reg_overlap_mentioned_p (p->target, dest))
3653 p->must_stay = true;
3654 /* If we haven't committed to keeping any other insns in the list yet,
3655 there is nothing more to check. */
3656 else if (p->insn == p->first)
3657 return;
3658 /* If this insn sets / clobbers a register that feeds one of the insns
3659 already in the list, this insn has to stay too. */
3660 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3661 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3662 || reg_used_between_p (dest, p->first, p->insn)
3663 /* Likewise if this insn depends on a register set by a previous
3664 insn in the list, or if it sets a result (presumably a hard
3665 register) that is set or clobbered by a previous insn.
3666 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3667 SET_DEST perform the former check on the address, and the latter
3668 check on the MEM. */
3669 || (GET_CODE (set) == SET
3670 && (modified_in_p (SET_SRC (set), p->first)
3671 || modified_in_p (SET_DEST (set), p->first)
3672 || modified_between_p (SET_SRC (set), p->first, p->insn)
3673 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3674 p->must_stay = true;
3678 /* Emit code to make a call to a constant function or a library call.
3680 INSNS is a list containing all insns emitted in the call.
3681 These insns leave the result in RESULT. Our block is to copy RESULT
3682 to TARGET, which is logically equivalent to EQUIV.
3684 We first emit any insns that set a pseudo on the assumption that these are
3685 loading constants into registers; doing so allows them to be safely cse'ed
3686 between blocks. Then we emit all the other insns in the block, followed by
3687 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3688 note with an operand of EQUIV. */
3690 void
3691 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3693 rtx final_dest = target;
3694 rtx next, last, insn;
3696 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3697 into a MEM later. Protect the libcall block from this change. */
3698 if (! REG_P (target) || REG_USERVAR_P (target))
3699 target = gen_reg_rtx (GET_MODE (target));
3701 /* If we're using non-call exceptions, a libcall corresponding to an
3702 operation that may trap may also trap. */
3703 /* ??? See the comment in front of make_reg_eh_region_note. */
3704 if (cfun->can_throw_non_call_exceptions && may_trap_p (equiv))
3706 for (insn = insns; insn; insn = NEXT_INSN (insn))
3707 if (CALL_P (insn))
3709 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3710 if (note)
3712 int lp_nr = INTVAL (XEXP (note, 0));
3713 if (lp_nr == 0 || lp_nr == INT_MIN)
3714 remove_note (insn, note);
3718 else
3720 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3721 reg note to indicate that this call cannot throw or execute a nonlocal
3722 goto (unless there is already a REG_EH_REGION note, in which case
3723 we update it). */
3724 for (insn = insns; insn; insn = NEXT_INSN (insn))
3725 if (CALL_P (insn))
3726 make_reg_eh_region_note_nothrow_nononlocal (insn);
3729 /* First emit all insns that set pseudos. Remove them from the list as
3730 we go. Avoid insns that set pseudos which were referenced in previous
3731 insns. These can be generated by move_by_pieces, for example,
3732 to update an address. Similarly, avoid insns that reference things
3733 set in previous insns. */
3735 for (insn = insns; insn; insn = next)
3737 rtx set = single_set (insn);
3739 next = NEXT_INSN (insn);
3741 if (set != 0 && REG_P (SET_DEST (set))
3742 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3744 struct no_conflict_data data;
3746 data.target = const0_rtx;
3747 data.first = insns;
3748 data.insn = insn;
3749 data.must_stay = 0;
3750 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3751 if (! data.must_stay)
3753 if (PREV_INSN (insn))
3754 NEXT_INSN (PREV_INSN (insn)) = next;
3755 else
3756 insns = next;
3758 if (next)
3759 PREV_INSN (next) = PREV_INSN (insn);
3761 add_insn (insn);
3765 /* Some ports use a loop to copy large arguments onto the stack.
3766 Don't move anything outside such a loop. */
3767 if (LABEL_P (insn))
3768 break;
3771 /* Write the remaining insns followed by the final copy. */
3772 for (insn = insns; insn; insn = next)
3774 next = NEXT_INSN (insn);
3776 add_insn (insn);
3779 last = emit_move_insn (target, result);
3780 if (optab_handler (mov_optab, GET_MODE (target)) != CODE_FOR_nothing)
3781 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3783 if (final_dest != target)
3784 emit_move_insn (final_dest, target);
3787 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3788 PURPOSE describes how this comparison will be used. CODE is the rtx
3789 comparison code we will be using.
3791 ??? Actually, CODE is slightly weaker than that. A target is still
3792 required to implement all of the normal bcc operations, but not
3793 required to implement all (or any) of the unordered bcc operations. */
3796 can_compare_p (enum rtx_code code, enum machine_mode mode,
3797 enum can_compare_purpose purpose)
3799 rtx test;
3800 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
3803 enum insn_code icode;
3805 if (purpose == ccp_jump
3806 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
3807 && insn_operand_matches (icode, 0, test))
3808 return 1;
3809 if (purpose == ccp_store_flag
3810 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
3811 && insn_operand_matches (icode, 1, test))
3812 return 1;
3813 if (purpose == ccp_cmov
3814 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
3815 return 1;
3817 mode = GET_MODE_WIDER_MODE (mode);
3818 PUT_MODE (test, mode);
3820 while (mode != VOIDmode);
3822 return 0;
3825 /* This function is called when we are going to emit a compare instruction that
3826 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3828 *PMODE is the mode of the inputs (in case they are const_int).
3829 *PUNSIGNEDP nonzero says that the operands are unsigned;
3830 this matters if they need to be widened (as given by METHODS).
3832 If they have mode BLKmode, then SIZE specifies the size of both operands.
3834 This function performs all the setup necessary so that the caller only has
3835 to emit a single comparison insn. This setup can involve doing a BLKmode
3836 comparison or emitting a library call to perform the comparison if no insn
3837 is available to handle it.
3838 The values which are passed in through pointers can be modified; the caller
3839 should perform the comparison on the modified values. Constant
3840 comparisons must have already been folded. */
3842 static void
3843 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3844 int unsignedp, enum optab_methods methods,
3845 rtx *ptest, enum machine_mode *pmode)
3847 enum machine_mode mode = *pmode;
3848 rtx libfunc, test;
3849 enum machine_mode cmp_mode;
3850 enum mode_class mclass;
3852 /* The other methods are not needed. */
3853 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
3854 || methods == OPTAB_LIB_WIDEN);
3856 /* If we are optimizing, force expensive constants into a register. */
3857 if (CONSTANT_P (x) && optimize
3858 && (rtx_cost (x, COMPARE, 0, optimize_insn_for_speed_p ())
3859 > COSTS_N_INSNS (1)))
3860 x = force_reg (mode, x);
3862 if (CONSTANT_P (y) && optimize
3863 && (rtx_cost (y, COMPARE, 1, optimize_insn_for_speed_p ())
3864 > COSTS_N_INSNS (1)))
3865 y = force_reg (mode, y);
3867 #ifdef HAVE_cc0
3868 /* Make sure if we have a canonical comparison. The RTL
3869 documentation states that canonical comparisons are required only
3870 for targets which have cc0. */
3871 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3872 #endif
3874 /* Don't let both operands fail to indicate the mode. */
3875 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3876 x = force_reg (mode, x);
3877 if (mode == VOIDmode)
3878 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
3880 /* Handle all BLKmode compares. */
3882 if (mode == BLKmode)
3884 enum machine_mode result_mode;
3885 enum insn_code cmp_code;
3886 tree length_type;
3887 rtx libfunc;
3888 rtx result;
3889 rtx opalign
3890 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3892 gcc_assert (size);
3894 /* Try to use a memory block compare insn - either cmpstr
3895 or cmpmem will do. */
3896 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3897 cmp_mode != VOIDmode;
3898 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3900 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
3901 if (cmp_code == CODE_FOR_nothing)
3902 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
3903 if (cmp_code == CODE_FOR_nothing)
3904 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
3905 if (cmp_code == CODE_FOR_nothing)
3906 continue;
3908 /* Must make sure the size fits the insn's mode. */
3909 if ((CONST_INT_P (size)
3910 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3911 || (GET_MODE_BITSIZE (GET_MODE (size))
3912 > GET_MODE_BITSIZE (cmp_mode)))
3913 continue;
3915 result_mode = insn_data[cmp_code].operand[0].mode;
3916 result = gen_reg_rtx (result_mode);
3917 size = convert_to_mode (cmp_mode, size, 1);
3918 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3920 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
3921 *pmode = result_mode;
3922 return;
3925 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
3926 goto fail;
3928 /* Otherwise call a library function, memcmp. */
3929 libfunc = memcmp_libfunc;
3930 length_type = sizetype;
3931 result_mode = TYPE_MODE (integer_type_node);
3932 cmp_mode = TYPE_MODE (length_type);
3933 size = convert_to_mode (TYPE_MODE (length_type), size,
3934 TYPE_UNSIGNED (length_type));
3936 result = emit_library_call_value (libfunc, 0, LCT_PURE,
3937 result_mode, 3,
3938 XEXP (x, 0), Pmode,
3939 XEXP (y, 0), Pmode,
3940 size, cmp_mode);
3942 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
3943 *pmode = result_mode;
3944 return;
3947 /* Don't allow operands to the compare to trap, as that can put the
3948 compare and branch in different basic blocks. */
3949 if (cfun->can_throw_non_call_exceptions)
3951 if (may_trap_p (x))
3952 x = force_reg (mode, x);
3953 if (may_trap_p (y))
3954 y = force_reg (mode, y);
3957 if (GET_MODE_CLASS (mode) == MODE_CC)
3959 gcc_assert (can_compare_p (comparison, CCmode, ccp_jump));
3960 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3961 return;
3964 mclass = GET_MODE_CLASS (mode);
3965 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3966 cmp_mode = mode;
3969 enum insn_code icode;
3970 icode = optab_handler (cbranch_optab, cmp_mode);
3971 if (icode != CODE_FOR_nothing
3972 && insn_operand_matches (icode, 0, test))
3974 rtx last = get_last_insn ();
3975 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
3976 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
3977 if (op0 && op1
3978 && insn_operand_matches (icode, 1, op0)
3979 && insn_operand_matches (icode, 2, op1))
3981 XEXP (test, 0) = op0;
3982 XEXP (test, 1) = op1;
3983 *ptest = test;
3984 *pmode = cmp_mode;
3985 return;
3987 delete_insns_since (last);
3990 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
3991 break;
3992 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode);
3994 while (cmp_mode != VOIDmode);
3996 if (methods != OPTAB_LIB_WIDEN)
3997 goto fail;
3999 if (!SCALAR_FLOAT_MODE_P (mode))
4001 rtx result;
4003 /* Handle a libcall just for the mode we are using. */
4004 libfunc = optab_libfunc (cmp_optab, mode);
4005 gcc_assert (libfunc);
4007 /* If we want unsigned, and this mode has a distinct unsigned
4008 comparison routine, use that. */
4009 if (unsignedp)
4011 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
4012 if (ulibfunc)
4013 libfunc = ulibfunc;
4016 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4017 targetm.libgcc_cmp_return_mode (),
4018 2, x, mode, y, mode);
4020 /* There are two kinds of comparison routines. Biased routines
4021 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4022 of gcc expect that the comparison operation is equivalent
4023 to the modified comparison. For signed comparisons compare the
4024 result against 1 in the biased case, and zero in the unbiased
4025 case. For unsigned comparisons always compare against 1 after
4026 biasing the unbiased result by adding 1. This gives us a way to
4027 represent LTU.
4028 The comparisons in the fixed-point helper library are always
4029 biased. */
4030 x = result;
4031 y = const1_rtx;
4033 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
4035 if (unsignedp)
4036 x = plus_constant (result, 1);
4037 else
4038 y = const0_rtx;
4041 *pmode = word_mode;
4042 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
4043 ptest, pmode);
4045 else
4046 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
4048 return;
4050 fail:
4051 *ptest = NULL_RTX;
4054 /* Before emitting an insn with code ICODE, make sure that X, which is going
4055 to be used for operand OPNUM of the insn, is converted from mode MODE to
4056 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4057 that it is accepted by the operand predicate. Return the new value. */
4060 prepare_operand (enum insn_code icode, rtx x, int opnum, enum machine_mode mode,
4061 enum machine_mode wider_mode, int unsignedp)
4063 if (mode != wider_mode)
4064 x = convert_modes (wider_mode, mode, x, unsignedp);
4066 if (!insn_operand_matches (icode, opnum, x))
4068 if (reload_completed)
4069 return NULL_RTX;
4070 x = copy_to_mode_reg (insn_data[(int) icode].operand[opnum].mode, x);
4073 return x;
4076 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4077 we can do the branch. */
4079 static void
4080 emit_cmp_and_jump_insn_1 (rtx test, enum machine_mode mode, rtx label)
4082 enum machine_mode optab_mode;
4083 enum mode_class mclass;
4084 enum insn_code icode;
4086 mclass = GET_MODE_CLASS (mode);
4087 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
4088 icode = optab_handler (cbranch_optab, optab_mode);
4090 gcc_assert (icode != CODE_FOR_nothing);
4091 gcc_assert (insn_operand_matches (icode, 0, test));
4092 emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0), XEXP (test, 1), label));
4095 /* Generate code to compare X with Y so that the condition codes are
4096 set and to jump to LABEL if the condition is true. If X is a
4097 constant and Y is not a constant, then the comparison is swapped to
4098 ensure that the comparison RTL has the canonical form.
4100 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4101 need to be widened. UNSIGNEDP is also used to select the proper
4102 branch condition code.
4104 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4106 MODE is the mode of the inputs (in case they are const_int).
4108 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4109 It will be potentially converted into an unsigned variant based on
4110 UNSIGNEDP to select a proper jump instruction. */
4112 void
4113 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4114 enum machine_mode mode, int unsignedp, rtx label)
4116 rtx op0 = x, op1 = y;
4117 rtx test;
4119 /* Swap operands and condition to ensure canonical RTL. */
4120 if (swap_commutative_operands_p (x, y)
4121 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4123 op0 = y, op1 = x;
4124 comparison = swap_condition (comparison);
4127 /* If OP0 is still a constant, then both X and Y must be constants
4128 or the opposite comparison is not supported. Force X into a register
4129 to create canonical RTL. */
4130 if (CONSTANT_P (op0))
4131 op0 = force_reg (mode, op0);
4133 if (unsignedp)
4134 comparison = unsigned_condition (comparison);
4136 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4137 &test, &mode);
4138 emit_cmp_and_jump_insn_1 (test, mode, label);
4142 /* Emit a library call comparison between floating point X and Y.
4143 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4145 static void
4146 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4147 rtx *ptest, enum machine_mode *pmode)
4149 enum rtx_code swapped = swap_condition (comparison);
4150 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4151 enum machine_mode orig_mode = GET_MODE (x);
4152 enum machine_mode mode, cmp_mode;
4153 rtx true_rtx, false_rtx;
4154 rtx value, target, insns, equiv;
4155 rtx libfunc = 0;
4156 bool reversed_p = false;
4157 cmp_mode = targetm.libgcc_cmp_return_mode ();
4159 for (mode = orig_mode;
4160 mode != VOIDmode;
4161 mode = GET_MODE_WIDER_MODE (mode))
4163 if (code_to_optab[comparison]
4164 && (libfunc = optab_libfunc (code_to_optab[comparison], mode)))
4165 break;
4167 if (code_to_optab[swapped]
4168 && (libfunc = optab_libfunc (code_to_optab[swapped], mode)))
4170 rtx tmp;
4171 tmp = x; x = y; y = tmp;
4172 comparison = swapped;
4173 break;
4176 if (code_to_optab[reversed]
4177 && (libfunc = optab_libfunc (code_to_optab[reversed], mode)))
4179 comparison = reversed;
4180 reversed_p = true;
4181 break;
4185 gcc_assert (mode != VOIDmode);
4187 if (mode != orig_mode)
4189 x = convert_to_mode (mode, x, 0);
4190 y = convert_to_mode (mode, y, 0);
4193 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4194 the RTL. The allows the RTL optimizers to delete the libcall if the
4195 condition can be determined at compile-time. */
4196 if (comparison == UNORDERED
4197 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4199 true_rtx = const_true_rtx;
4200 false_rtx = const0_rtx;
4202 else
4204 switch (comparison)
4206 case EQ:
4207 true_rtx = const0_rtx;
4208 false_rtx = const_true_rtx;
4209 break;
4211 case NE:
4212 true_rtx = const_true_rtx;
4213 false_rtx = const0_rtx;
4214 break;
4216 case GT:
4217 true_rtx = const1_rtx;
4218 false_rtx = const0_rtx;
4219 break;
4221 case GE:
4222 true_rtx = const0_rtx;
4223 false_rtx = constm1_rtx;
4224 break;
4226 case LT:
4227 true_rtx = constm1_rtx;
4228 false_rtx = const0_rtx;
4229 break;
4231 case LE:
4232 true_rtx = const0_rtx;
4233 false_rtx = const1_rtx;
4234 break;
4236 default:
4237 gcc_unreachable ();
4241 if (comparison == UNORDERED)
4243 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4244 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4245 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4246 temp, const_true_rtx, equiv);
4248 else
4250 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4251 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4252 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4253 equiv, true_rtx, false_rtx);
4256 start_sequence ();
4257 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4258 cmp_mode, 2, x, mode, y, mode);
4259 insns = get_insns ();
4260 end_sequence ();
4262 target = gen_reg_rtx (cmp_mode);
4263 emit_libcall_block (insns, target, value, equiv);
4265 if (comparison == UNORDERED
4266 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4267 || reversed_p)
4268 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4269 else
4270 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4272 *pmode = cmp_mode;
4275 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4277 void
4278 emit_indirect_jump (rtx loc)
4280 struct expand_operand ops[1];
4282 create_address_operand (&ops[0], loc);
4283 expand_jump_insn (CODE_FOR_indirect_jump, 1, ops);
4284 emit_barrier ();
4287 #ifdef HAVE_conditional_move
4289 /* Emit a conditional move instruction if the machine supports one for that
4290 condition and machine mode.
4292 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4293 the mode to use should they be constants. If it is VOIDmode, they cannot
4294 both be constants.
4296 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4297 should be stored there. MODE is the mode to use should they be constants.
4298 If it is VOIDmode, they cannot both be constants.
4300 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4301 is not supported. */
4304 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4305 enum machine_mode cmode, rtx op2, rtx op3,
4306 enum machine_mode mode, int unsignedp)
4308 rtx tem, comparison, last;
4309 enum insn_code icode;
4310 enum rtx_code reversed;
4312 /* If one operand is constant, make it the second one. Only do this
4313 if the other operand is not constant as well. */
4315 if (swap_commutative_operands_p (op0, op1))
4317 tem = op0;
4318 op0 = op1;
4319 op1 = tem;
4320 code = swap_condition (code);
4323 /* get_condition will prefer to generate LT and GT even if the old
4324 comparison was against zero, so undo that canonicalization here since
4325 comparisons against zero are cheaper. */
4326 if (code == LT && op1 == const1_rtx)
4327 code = LE, op1 = const0_rtx;
4328 else if (code == GT && op1 == constm1_rtx)
4329 code = GE, op1 = const0_rtx;
4331 if (cmode == VOIDmode)
4332 cmode = GET_MODE (op0);
4334 if (swap_commutative_operands_p (op2, op3)
4335 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4336 != UNKNOWN))
4338 tem = op2;
4339 op2 = op3;
4340 op3 = tem;
4341 code = reversed;
4344 if (mode == VOIDmode)
4345 mode = GET_MODE (op2);
4347 icode = direct_optab_handler (movcc_optab, mode);
4349 if (icode == CODE_FOR_nothing)
4350 return 0;
4352 if (!target)
4353 target = gen_reg_rtx (mode);
4355 code = unsignedp ? unsigned_condition (code) : code;
4356 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4358 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4359 return NULL and let the caller figure out how best to deal with this
4360 situation. */
4361 if (!COMPARISON_P (comparison))
4362 return NULL_RTX;
4364 do_pending_stack_adjust ();
4365 last = get_last_insn ();
4366 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4367 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4368 &comparison, &cmode);
4369 if (comparison)
4371 struct expand_operand ops[4];
4373 create_output_operand (&ops[0], target, mode);
4374 create_fixed_operand (&ops[1], comparison);
4375 create_input_operand (&ops[2], op2, mode);
4376 create_input_operand (&ops[3], op3, mode);
4377 if (maybe_expand_insn (icode, 4, ops))
4379 if (ops[0].value != target)
4380 convert_move (target, ops[0].value, false);
4381 return target;
4384 delete_insns_since (last);
4385 return NULL_RTX;
4388 /* Return nonzero if a conditional move of mode MODE is supported.
4390 This function is for combine so it can tell whether an insn that looks
4391 like a conditional move is actually supported by the hardware. If we
4392 guess wrong we lose a bit on optimization, but that's it. */
4393 /* ??? sparc64 supports conditionally moving integers values based on fp
4394 comparisons, and vice versa. How do we handle them? */
4397 can_conditionally_move_p (enum machine_mode mode)
4399 if (direct_optab_handler (movcc_optab, mode) != CODE_FOR_nothing)
4400 return 1;
4402 return 0;
4405 #endif /* HAVE_conditional_move */
4407 /* Emit a conditional addition instruction if the machine supports one for that
4408 condition and machine mode.
4410 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4411 the mode to use should they be constants. If it is VOIDmode, they cannot
4412 both be constants.
4414 OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4415 should be stored there. MODE is the mode to use should they be constants.
4416 If it is VOIDmode, they cannot both be constants.
4418 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4419 is not supported. */
4422 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4423 enum machine_mode cmode, rtx op2, rtx op3,
4424 enum machine_mode mode, int unsignedp)
4426 rtx tem, comparison, last;
4427 enum insn_code icode;
4428 enum rtx_code reversed;
4430 /* If one operand is constant, make it the second one. Only do this
4431 if the other operand is not constant as well. */
4433 if (swap_commutative_operands_p (op0, op1))
4435 tem = op0;
4436 op0 = op1;
4437 op1 = tem;
4438 code = swap_condition (code);
4441 /* get_condition will prefer to generate LT and GT even if the old
4442 comparison was against zero, so undo that canonicalization here since
4443 comparisons against zero are cheaper. */
4444 if (code == LT && op1 == const1_rtx)
4445 code = LE, op1 = const0_rtx;
4446 else if (code == GT && op1 == constm1_rtx)
4447 code = GE, op1 = const0_rtx;
4449 if (cmode == VOIDmode)
4450 cmode = GET_MODE (op0);
4452 if (swap_commutative_operands_p (op2, op3)
4453 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4454 != UNKNOWN))
4456 tem = op2;
4457 op2 = op3;
4458 op3 = tem;
4459 code = reversed;
4462 if (mode == VOIDmode)
4463 mode = GET_MODE (op2);
4465 icode = optab_handler (addcc_optab, mode);
4467 if (icode == CODE_FOR_nothing)
4468 return 0;
4470 if (!target)
4471 target = gen_reg_rtx (mode);
4473 code = unsignedp ? unsigned_condition (code) : code;
4474 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4476 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4477 return NULL and let the caller figure out how best to deal with this
4478 situation. */
4479 if (!COMPARISON_P (comparison))
4480 return NULL_RTX;
4482 do_pending_stack_adjust ();
4483 last = get_last_insn ();
4484 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4485 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4486 &comparison, &cmode);
4487 if (comparison)
4489 struct expand_operand ops[4];
4491 create_output_operand (&ops[0], target, mode);
4492 create_fixed_operand (&ops[1], comparison);
4493 create_input_operand (&ops[2], op2, mode);
4494 create_input_operand (&ops[3], op3, mode);
4495 if (maybe_expand_insn (icode, 4, ops))
4497 if (ops[0].value != target)
4498 convert_move (target, ops[0].value, false);
4499 return target;
4502 delete_insns_since (last);
4503 return NULL_RTX;
4506 /* These functions attempt to generate an insn body, rather than
4507 emitting the insn, but if the gen function already emits them, we
4508 make no attempt to turn them back into naked patterns. */
4510 /* Generate and return an insn body to add Y to X. */
4513 gen_add2_insn (rtx x, rtx y)
4515 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
4517 gcc_assert (insn_operand_matches (icode, 0, x));
4518 gcc_assert (insn_operand_matches (icode, 1, x));
4519 gcc_assert (insn_operand_matches (icode, 2, y));
4521 return GEN_FCN (icode) (x, x, y);
4524 /* Generate and return an insn body to add r1 and c,
4525 storing the result in r0. */
4528 gen_add3_insn (rtx r0, rtx r1, rtx c)
4530 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
4532 if (icode == CODE_FOR_nothing
4533 || !insn_operand_matches (icode, 0, r0)
4534 || !insn_operand_matches (icode, 1, r1)
4535 || !insn_operand_matches (icode, 2, c))
4536 return NULL_RTX;
4538 return GEN_FCN (icode) (r0, r1, c);
4542 have_add2_insn (rtx x, rtx y)
4544 enum insn_code icode;
4546 gcc_assert (GET_MODE (x) != VOIDmode);
4548 icode = optab_handler (add_optab, GET_MODE (x));
4550 if (icode == CODE_FOR_nothing)
4551 return 0;
4553 if (!insn_operand_matches (icode, 0, x)
4554 || !insn_operand_matches (icode, 1, x)
4555 || !insn_operand_matches (icode, 2, y))
4556 return 0;
4558 return 1;
4561 /* Generate and return an insn body to subtract Y from X. */
4564 gen_sub2_insn (rtx x, rtx y)
4566 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
4568 gcc_assert (insn_operand_matches (icode, 0, x));
4569 gcc_assert (insn_operand_matches (icode, 1, x));
4570 gcc_assert (insn_operand_matches (icode, 2, y));
4572 return GEN_FCN (icode) (x, x, y);
4575 /* Generate and return an insn body to subtract r1 and c,
4576 storing the result in r0. */
4579 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4581 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
4583 if (icode == CODE_FOR_nothing
4584 || !insn_operand_matches (icode, 0, r0)
4585 || !insn_operand_matches (icode, 1, r1)
4586 || !insn_operand_matches (icode, 2, c))
4587 return NULL_RTX;
4589 return GEN_FCN (icode) (r0, r1, c);
4593 have_sub2_insn (rtx x, rtx y)
4595 enum insn_code icode;
4597 gcc_assert (GET_MODE (x) != VOIDmode);
4599 icode = optab_handler (sub_optab, GET_MODE (x));
4601 if (icode == CODE_FOR_nothing)
4602 return 0;
4604 if (!insn_operand_matches (icode, 0, x)
4605 || !insn_operand_matches (icode, 1, x)
4606 || !insn_operand_matches (icode, 2, y))
4607 return 0;
4609 return 1;
4612 /* Generate the body of an instruction to copy Y into X.
4613 It may be a list of insns, if one insn isn't enough. */
4616 gen_move_insn (rtx x, rtx y)
4618 rtx seq;
4620 start_sequence ();
4621 emit_move_insn_1 (x, y);
4622 seq = get_insns ();
4623 end_sequence ();
4624 return seq;
4627 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4628 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4629 no such operation exists, CODE_FOR_nothing will be returned. */
4631 enum insn_code
4632 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4633 int unsignedp)
4635 convert_optab tab;
4636 #ifdef HAVE_ptr_extend
4637 if (unsignedp < 0)
4638 return CODE_FOR_ptr_extend;
4639 #endif
4641 tab = unsignedp ? zext_optab : sext_optab;
4642 return convert_optab_handler (tab, to_mode, from_mode);
4645 /* Generate the body of an insn to extend Y (with mode MFROM)
4646 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4649 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4650 enum machine_mode mfrom, int unsignedp)
4652 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4653 return GEN_FCN (icode) (x, y);
4656 /* can_fix_p and can_float_p say whether the target machine
4657 can directly convert a given fixed point type to
4658 a given floating point type, or vice versa.
4659 The returned value is the CODE_FOR_... value to use,
4660 or CODE_FOR_nothing if these modes cannot be directly converted.
4662 *TRUNCP_PTR is set to 1 if it is necessary to output
4663 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4665 static enum insn_code
4666 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4667 int unsignedp, int *truncp_ptr)
4669 convert_optab tab;
4670 enum insn_code icode;
4672 tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4673 icode = convert_optab_handler (tab, fixmode, fltmode);
4674 if (icode != CODE_FOR_nothing)
4676 *truncp_ptr = 0;
4677 return icode;
4680 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4681 for this to work. We need to rework the fix* and ftrunc* patterns
4682 and documentation. */
4683 tab = unsignedp ? ufix_optab : sfix_optab;
4684 icode = convert_optab_handler (tab, fixmode, fltmode);
4685 if (icode != CODE_FOR_nothing
4686 && optab_handler (ftrunc_optab, fltmode) != CODE_FOR_nothing)
4688 *truncp_ptr = 1;
4689 return icode;
4692 *truncp_ptr = 0;
4693 return CODE_FOR_nothing;
4696 enum insn_code
4697 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4698 int unsignedp)
4700 convert_optab tab;
4702 tab = unsignedp ? ufloat_optab : sfloat_optab;
4703 return convert_optab_handler (tab, fltmode, fixmode);
4706 /* Generate code to convert FROM to floating point
4707 and store in TO. FROM must be fixed point and not VOIDmode.
4708 UNSIGNEDP nonzero means regard FROM as unsigned.
4709 Normally this is done by correcting the final value
4710 if it is negative. */
4712 void
4713 expand_float (rtx to, rtx from, int unsignedp)
4715 enum insn_code icode;
4716 rtx target = to;
4717 enum machine_mode fmode, imode;
4718 bool can_do_signed = false;
4720 /* Crash now, because we won't be able to decide which mode to use. */
4721 gcc_assert (GET_MODE (from) != VOIDmode);
4723 /* Look for an insn to do the conversion. Do it in the specified
4724 modes if possible; otherwise convert either input, output or both to
4725 wider mode. If the integer mode is wider than the mode of FROM,
4726 we can do the conversion signed even if the input is unsigned. */
4728 for (fmode = GET_MODE (to); fmode != VOIDmode;
4729 fmode = GET_MODE_WIDER_MODE (fmode))
4730 for (imode = GET_MODE (from); imode != VOIDmode;
4731 imode = GET_MODE_WIDER_MODE (imode))
4733 int doing_unsigned = unsignedp;
4735 if (fmode != GET_MODE (to)
4736 && significand_size (fmode) < GET_MODE_PRECISION (GET_MODE (from)))
4737 continue;
4739 icode = can_float_p (fmode, imode, unsignedp);
4740 if (icode == CODE_FOR_nothing && unsignedp)
4742 enum insn_code scode = can_float_p (fmode, imode, 0);
4743 if (scode != CODE_FOR_nothing)
4744 can_do_signed = true;
4745 if (imode != GET_MODE (from))
4746 icode = scode, doing_unsigned = 0;
4749 if (icode != CODE_FOR_nothing)
4751 if (imode != GET_MODE (from))
4752 from = convert_to_mode (imode, from, unsignedp);
4754 if (fmode != GET_MODE (to))
4755 target = gen_reg_rtx (fmode);
4757 emit_unop_insn (icode, target, from,
4758 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4760 if (target != to)
4761 convert_move (to, target, 0);
4762 return;
4766 /* Unsigned integer, and no way to convert directly. Convert as signed,
4767 then unconditionally adjust the result. */
4768 if (unsignedp && can_do_signed)
4770 rtx label = gen_label_rtx ();
4771 rtx temp;
4772 REAL_VALUE_TYPE offset;
4774 /* Look for a usable floating mode FMODE wider than the source and at
4775 least as wide as the target. Using FMODE will avoid rounding woes
4776 with unsigned values greater than the signed maximum value. */
4778 for (fmode = GET_MODE (to); fmode != VOIDmode;
4779 fmode = GET_MODE_WIDER_MODE (fmode))
4780 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4781 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4782 break;
4784 if (fmode == VOIDmode)
4786 /* There is no such mode. Pretend the target is wide enough. */
4787 fmode = GET_MODE (to);
4789 /* Avoid double-rounding when TO is narrower than FROM. */
4790 if ((significand_size (fmode) + 1)
4791 < GET_MODE_PRECISION (GET_MODE (from)))
4793 rtx temp1;
4794 rtx neglabel = gen_label_rtx ();
4796 /* Don't use TARGET if it isn't a register, is a hard register,
4797 or is the wrong mode. */
4798 if (!REG_P (target)
4799 || REGNO (target) < FIRST_PSEUDO_REGISTER
4800 || GET_MODE (target) != fmode)
4801 target = gen_reg_rtx (fmode);
4803 imode = GET_MODE (from);
4804 do_pending_stack_adjust ();
4806 /* Test whether the sign bit is set. */
4807 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4808 0, neglabel);
4810 /* The sign bit is not set. Convert as signed. */
4811 expand_float (target, from, 0);
4812 emit_jump_insn (gen_jump (label));
4813 emit_barrier ();
4815 /* The sign bit is set.
4816 Convert to a usable (positive signed) value by shifting right
4817 one bit, while remembering if a nonzero bit was shifted
4818 out; i.e., compute (from & 1) | (from >> 1). */
4820 emit_label (neglabel);
4821 temp = expand_binop (imode, and_optab, from, const1_rtx,
4822 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4823 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
4824 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4825 OPTAB_LIB_WIDEN);
4826 expand_float (target, temp, 0);
4828 /* Multiply by 2 to undo the shift above. */
4829 temp = expand_binop (fmode, add_optab, target, target,
4830 target, 0, OPTAB_LIB_WIDEN);
4831 if (temp != target)
4832 emit_move_insn (target, temp);
4834 do_pending_stack_adjust ();
4835 emit_label (label);
4836 goto done;
4840 /* If we are about to do some arithmetic to correct for an
4841 unsigned operand, do it in a pseudo-register. */
4843 if (GET_MODE (to) != fmode
4844 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4845 target = gen_reg_rtx (fmode);
4847 /* Convert as signed integer to floating. */
4848 expand_float (target, from, 0);
4850 /* If FROM is negative (and therefore TO is negative),
4851 correct its value by 2**bitwidth. */
4853 do_pending_stack_adjust ();
4854 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4855 0, label);
4858 real_2expN (&offset, GET_MODE_PRECISION (GET_MODE (from)), fmode);
4859 temp = expand_binop (fmode, add_optab, target,
4860 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4861 target, 0, OPTAB_LIB_WIDEN);
4862 if (temp != target)
4863 emit_move_insn (target, temp);
4865 do_pending_stack_adjust ();
4866 emit_label (label);
4867 goto done;
4870 /* No hardware instruction available; call a library routine. */
4872 rtx libfunc;
4873 rtx insns;
4874 rtx value;
4875 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4877 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4878 from = convert_to_mode (SImode, from, unsignedp);
4880 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4881 gcc_assert (libfunc);
4883 start_sequence ();
4885 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4886 GET_MODE (to), 1, from,
4887 GET_MODE (from));
4888 insns = get_insns ();
4889 end_sequence ();
4891 emit_libcall_block (insns, target, value,
4892 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
4893 GET_MODE (to), from));
4896 done:
4898 /* Copy result to requested destination
4899 if we have been computing in a temp location. */
4901 if (target != to)
4903 if (GET_MODE (target) == GET_MODE (to))
4904 emit_move_insn (to, target);
4905 else
4906 convert_move (to, target, 0);
4910 /* Generate code to convert FROM to fixed point and store in TO. FROM
4911 must be floating point. */
4913 void
4914 expand_fix (rtx to, rtx from, int unsignedp)
4916 enum insn_code icode;
4917 rtx target = to;
4918 enum machine_mode fmode, imode;
4919 int must_trunc = 0;
4921 /* We first try to find a pair of modes, one real and one integer, at
4922 least as wide as FROM and TO, respectively, in which we can open-code
4923 this conversion. If the integer mode is wider than the mode of TO,
4924 we can do the conversion either signed or unsigned. */
4926 for (fmode = GET_MODE (from); fmode != VOIDmode;
4927 fmode = GET_MODE_WIDER_MODE (fmode))
4928 for (imode = GET_MODE (to); imode != VOIDmode;
4929 imode = GET_MODE_WIDER_MODE (imode))
4931 int doing_unsigned = unsignedp;
4933 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4934 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4935 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4937 if (icode != CODE_FOR_nothing)
4939 rtx last = get_last_insn ();
4940 if (fmode != GET_MODE (from))
4941 from = convert_to_mode (fmode, from, 0);
4943 if (must_trunc)
4945 rtx temp = gen_reg_rtx (GET_MODE (from));
4946 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4947 temp, 0);
4950 if (imode != GET_MODE (to))
4951 target = gen_reg_rtx (imode);
4953 if (maybe_emit_unop_insn (icode, target, from,
4954 doing_unsigned ? UNSIGNED_FIX : FIX))
4956 if (target != to)
4957 convert_move (to, target, unsignedp);
4958 return;
4960 delete_insns_since (last);
4964 /* For an unsigned conversion, there is one more way to do it.
4965 If we have a signed conversion, we generate code that compares
4966 the real value to the largest representable positive number. If if
4967 is smaller, the conversion is done normally. Otherwise, subtract
4968 one plus the highest signed number, convert, and add it back.
4970 We only need to check all real modes, since we know we didn't find
4971 anything with a wider integer mode.
4973 This code used to extend FP value into mode wider than the destination.
4974 This is needed for decimal float modes which cannot accurately
4975 represent one plus the highest signed number of the same size, but
4976 not for binary modes. Consider, for instance conversion from SFmode
4977 into DImode.
4979 The hot path through the code is dealing with inputs smaller than 2^63
4980 and doing just the conversion, so there is no bits to lose.
4982 In the other path we know the value is positive in the range 2^63..2^64-1
4983 inclusive. (as for other input overflow happens and result is undefined)
4984 So we know that the most important bit set in mantissa corresponds to
4985 2^63. The subtraction of 2^63 should not generate any rounding as it
4986 simply clears out that bit. The rest is trivial. */
4988 if (unsignedp && GET_MODE_PRECISION (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4989 for (fmode = GET_MODE (from); fmode != VOIDmode;
4990 fmode = GET_MODE_WIDER_MODE (fmode))
4991 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
4992 && (!DECIMAL_FLOAT_MODE_P (fmode)
4993 || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (GET_MODE (to))))
4995 int bitsize;
4996 REAL_VALUE_TYPE offset;
4997 rtx limit, lab1, lab2, insn;
4999 bitsize = GET_MODE_PRECISION (GET_MODE (to));
5000 real_2expN (&offset, bitsize - 1, fmode);
5001 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
5002 lab1 = gen_label_rtx ();
5003 lab2 = gen_label_rtx ();
5005 if (fmode != GET_MODE (from))
5006 from = convert_to_mode (fmode, from, 0);
5008 /* See if we need to do the subtraction. */
5009 do_pending_stack_adjust ();
5010 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
5011 0, lab1);
5013 /* If not, do the signed "fix" and branch around fixup code. */
5014 expand_fix (to, from, 0);
5015 emit_jump_insn (gen_jump (lab2));
5016 emit_barrier ();
5018 /* Otherwise, subtract 2**(N-1), convert to signed number,
5019 then add 2**(N-1). Do the addition using XOR since this
5020 will often generate better code. */
5021 emit_label (lab1);
5022 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5023 NULL_RTX, 0, OPTAB_LIB_WIDEN);
5024 expand_fix (to, target, 0);
5025 target = expand_binop (GET_MODE (to), xor_optab, to,
5026 gen_int_mode
5027 ((HOST_WIDE_INT) 1 << (bitsize - 1),
5028 GET_MODE (to)),
5029 to, 1, OPTAB_LIB_WIDEN);
5031 if (target != to)
5032 emit_move_insn (to, target);
5034 emit_label (lab2);
5036 if (optab_handler (mov_optab, GET_MODE (to)) != CODE_FOR_nothing)
5038 /* Make a place for a REG_NOTE and add it. */
5039 insn = emit_move_insn (to, to);
5040 set_unique_reg_note (insn,
5041 REG_EQUAL,
5042 gen_rtx_fmt_e (UNSIGNED_FIX,
5043 GET_MODE (to),
5044 copy_rtx (from)));
5047 return;
5050 /* We can't do it with an insn, so use a library call. But first ensure
5051 that the mode of TO is at least as wide as SImode, since those are the
5052 only library calls we know about. */
5054 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
5056 target = gen_reg_rtx (SImode);
5058 expand_fix (target, from, unsignedp);
5060 else
5062 rtx insns;
5063 rtx value;
5064 rtx libfunc;
5066 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5067 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5068 gcc_assert (libfunc);
5070 start_sequence ();
5072 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5073 GET_MODE (to), 1, from,
5074 GET_MODE (from));
5075 insns = get_insns ();
5076 end_sequence ();
5078 emit_libcall_block (insns, target, value,
5079 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5080 GET_MODE (to), from));
5083 if (target != to)
5085 if (GET_MODE (to) == GET_MODE (target))
5086 emit_move_insn (to, target);
5087 else
5088 convert_move (to, target, 0);
5092 /* Generate code to convert FROM or TO a fixed-point.
5093 If UINTP is true, either TO or FROM is an unsigned integer.
5094 If SATP is true, we need to saturate the result. */
5096 void
5097 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5099 enum machine_mode to_mode = GET_MODE (to);
5100 enum machine_mode from_mode = GET_MODE (from);
5101 convert_optab tab;
5102 enum rtx_code this_code;
5103 enum insn_code code;
5104 rtx insns, value;
5105 rtx libfunc;
5107 if (to_mode == from_mode)
5109 emit_move_insn (to, from);
5110 return;
5113 if (uintp)
5115 tab = satp ? satfractuns_optab : fractuns_optab;
5116 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5118 else
5120 tab = satp ? satfract_optab : fract_optab;
5121 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5123 code = convert_optab_handler (tab, to_mode, from_mode);
5124 if (code != CODE_FOR_nothing)
5126 emit_unop_insn (code, to, from, this_code);
5127 return;
5130 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5131 gcc_assert (libfunc);
5133 start_sequence ();
5134 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5135 1, from, from_mode);
5136 insns = get_insns ();
5137 end_sequence ();
5139 emit_libcall_block (insns, to, value,
5140 gen_rtx_fmt_e (tab->code, to_mode, from));
5143 /* Generate code to convert FROM to fixed point and store in TO. FROM
5144 must be floating point, TO must be signed. Use the conversion optab
5145 TAB to do the conversion. */
5147 bool
5148 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5150 enum insn_code icode;
5151 rtx target = to;
5152 enum machine_mode fmode, imode;
5154 /* We first try to find a pair of modes, one real and one integer, at
5155 least as wide as FROM and TO, respectively, in which we can open-code
5156 this conversion. If the integer mode is wider than the mode of TO,
5157 we can do the conversion either signed or unsigned. */
5159 for (fmode = GET_MODE (from); fmode != VOIDmode;
5160 fmode = GET_MODE_WIDER_MODE (fmode))
5161 for (imode = GET_MODE (to); imode != VOIDmode;
5162 imode = GET_MODE_WIDER_MODE (imode))
5164 icode = convert_optab_handler (tab, imode, fmode);
5165 if (icode != CODE_FOR_nothing)
5167 rtx last = get_last_insn ();
5168 if (fmode != GET_MODE (from))
5169 from = convert_to_mode (fmode, from, 0);
5171 if (imode != GET_MODE (to))
5172 target = gen_reg_rtx (imode);
5174 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5176 delete_insns_since (last);
5177 continue;
5179 if (target != to)
5180 convert_move (to, target, 0);
5181 return true;
5185 return false;
5188 /* Report whether we have an instruction to perform the operation
5189 specified by CODE on operands of mode MODE. */
5191 have_insn_for (enum rtx_code code, enum machine_mode mode)
5193 return (code_to_optab[(int) code] != 0
5194 && (optab_handler (code_to_optab[(int) code], mode)
5195 != CODE_FOR_nothing));
5198 /* Set all insn_code fields to CODE_FOR_nothing. */
5200 static void
5201 init_insn_codes (void)
5203 memset (optab_table, 0, sizeof (optab_table));
5204 memset (convert_optab_table, 0, sizeof (convert_optab_table));
5205 memset (direct_optab_table, 0, sizeof (direct_optab_table));
5208 /* Initialize OP's code to CODE, and write it into the code_to_optab table. */
5209 static inline void
5210 init_optab (optab op, enum rtx_code code)
5212 op->code = code;
5213 code_to_optab[(int) code] = op;
5216 /* Same, but fill in its code as CODE, and do _not_ write it into
5217 the code_to_optab table. */
5218 static inline void
5219 init_optabv (optab op, enum rtx_code code)
5221 op->code = code;
5224 /* Conversion optabs never go in the code_to_optab table. */
5225 static void
5226 init_convert_optab (convert_optab op, enum rtx_code code)
5228 op->code = code;
5231 /* Initialize the libfunc fields of an entire group of entries in some
5232 optab. Each entry is set equal to a string consisting of a leading
5233 pair of underscores followed by a generic operation name followed by
5234 a mode name (downshifted to lowercase) followed by a single character
5235 representing the number of operands for the given operation (which is
5236 usually one of the characters '2', '3', or '4').
5238 OPTABLE is the table in which libfunc fields are to be initialized.
5239 OPNAME is the generic (string) name of the operation.
5240 SUFFIX is the character which specifies the number of operands for
5241 the given generic operation.
5242 MODE is the mode to generate for.
5245 static void
5246 gen_libfunc (optab optable, const char *opname, int suffix, enum machine_mode mode)
5248 unsigned opname_len = strlen (opname);
5249 const char *mname = GET_MODE_NAME (mode);
5250 unsigned mname_len = strlen (mname);
5251 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5252 int len = prefix_len + opname_len + mname_len + 1 + 1;
5253 char *libfunc_name = XALLOCAVEC (char, len);
5254 char *p;
5255 const char *q;
5257 p = libfunc_name;
5258 *p++ = '_';
5259 *p++ = '_';
5260 if (targetm.libfunc_gnu_prefix)
5262 *p++ = 'g';
5263 *p++ = 'n';
5264 *p++ = 'u';
5265 *p++ = '_';
5267 for (q = opname; *q; )
5268 *p++ = *q++;
5269 for (q = mname; *q; q++)
5270 *p++ = TOLOWER (*q);
5271 *p++ = suffix;
5272 *p = '\0';
5274 set_optab_libfunc (optable, mode,
5275 ggc_alloc_string (libfunc_name, p - libfunc_name));
5278 /* Like gen_libfunc, but verify that integer operation is involved. */
5280 static void
5281 gen_int_libfunc (optab optable, const char *opname, char suffix,
5282 enum machine_mode mode)
5284 int maxsize = 2 * BITS_PER_WORD;
5286 if (GET_MODE_CLASS (mode) != MODE_INT)
5287 return;
5288 if (maxsize < LONG_LONG_TYPE_SIZE)
5289 maxsize = LONG_LONG_TYPE_SIZE;
5290 if (GET_MODE_CLASS (mode) != MODE_INT
5291 || mode < word_mode || GET_MODE_BITSIZE (mode) > maxsize)
5292 return;
5293 gen_libfunc (optable, opname, suffix, mode);
5296 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */
5298 static void
5299 gen_fp_libfunc (optab optable, const char *opname, char suffix,
5300 enum machine_mode mode)
5302 char *dec_opname;
5304 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
5305 gen_libfunc (optable, opname, suffix, mode);
5306 if (DECIMAL_FLOAT_MODE_P (mode))
5308 dec_opname = XALLOCAVEC (char, sizeof (DECIMAL_PREFIX) + strlen (opname));
5309 /* For BID support, change the name to have either a bid_ or dpd_ prefix
5310 depending on the low level floating format used. */
5311 memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
5312 strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
5313 gen_libfunc (optable, dec_opname, suffix, mode);
5317 /* Like gen_libfunc, but verify that fixed-point operation is involved. */
5319 static void
5320 gen_fixed_libfunc (optab optable, const char *opname, char suffix,
5321 enum machine_mode mode)
5323 if (!ALL_FIXED_POINT_MODE_P (mode))
5324 return;
5325 gen_libfunc (optable, opname, suffix, mode);
5328 /* Like gen_libfunc, but verify that signed fixed-point operation is
5329 involved. */
5331 static void
5332 gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
5333 enum machine_mode mode)
5335 if (!SIGNED_FIXED_POINT_MODE_P (mode))
5336 return;
5337 gen_libfunc (optable, opname, suffix, mode);
5340 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
5341 involved. */
5343 static void
5344 gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
5345 enum machine_mode mode)
5347 if (!UNSIGNED_FIXED_POINT_MODE_P (mode))
5348 return;
5349 gen_libfunc (optable, opname, suffix, mode);
5352 /* Like gen_libfunc, but verify that FP or INT operation is involved. */
5354 static void
5355 gen_int_fp_libfunc (optab optable, const char *name, char suffix,
5356 enum machine_mode mode)
5358 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5359 gen_fp_libfunc (optable, name, suffix, mode);
5360 if (INTEGRAL_MODE_P (mode))
5361 gen_int_libfunc (optable, name, suffix, mode);
5364 /* Like gen_libfunc, but verify that FP or INT operation is involved
5365 and add 'v' suffix for integer operation. */
5367 static void
5368 gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
5369 enum machine_mode mode)
5371 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5372 gen_fp_libfunc (optable, name, suffix, mode);
5373 if (GET_MODE_CLASS (mode) == MODE_INT)
5375 int len = strlen (name);
5376 char *v_name = XALLOCAVEC (char, len + 2);
5377 strcpy (v_name, name);
5378 v_name[len] = 'v';
5379 v_name[len + 1] = 0;
5380 gen_int_libfunc (optable, v_name, suffix, mode);
5384 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
5385 involved. */
5387 static void
5388 gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
5389 enum machine_mode mode)
5391 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5392 gen_fp_libfunc (optable, name, suffix, mode);
5393 if (INTEGRAL_MODE_P (mode))
5394 gen_int_libfunc (optable, name, suffix, mode);
5395 if (ALL_FIXED_POINT_MODE_P (mode))
5396 gen_fixed_libfunc (optable, name, suffix, mode);
5399 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
5400 involved. */
5402 static void
5403 gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5404 enum machine_mode mode)
5406 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5407 gen_fp_libfunc (optable, name, suffix, mode);
5408 if (INTEGRAL_MODE_P (mode))
5409 gen_int_libfunc (optable, name, suffix, mode);
5410 if (SIGNED_FIXED_POINT_MODE_P (mode))
5411 gen_signed_fixed_libfunc (optable, name, suffix, mode);
5414 /* Like gen_libfunc, but verify that INT or FIXED operation is
5415 involved. */
5417 static void
5418 gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
5419 enum machine_mode mode)
5421 if (INTEGRAL_MODE_P (mode))
5422 gen_int_libfunc (optable, name, suffix, mode);
5423 if (ALL_FIXED_POINT_MODE_P (mode))
5424 gen_fixed_libfunc (optable, name, suffix, mode);
5427 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
5428 involved. */
5430 static void
5431 gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5432 enum machine_mode mode)
5434 if (INTEGRAL_MODE_P (mode))
5435 gen_int_libfunc (optable, name, suffix, mode);
5436 if (SIGNED_FIXED_POINT_MODE_P (mode))
5437 gen_signed_fixed_libfunc (optable, name, suffix, mode);
5440 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
5441 involved. */
5443 static void
5444 gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
5445 enum machine_mode mode)
5447 if (INTEGRAL_MODE_P (mode))
5448 gen_int_libfunc (optable, name, suffix, mode);
5449 if (UNSIGNED_FIXED_POINT_MODE_P (mode))
5450 gen_unsigned_fixed_libfunc (optable, name, suffix, mode);
5453 /* Initialize the libfunc fields of an entire group of entries of an
5454 inter-mode-class conversion optab. The string formation rules are
5455 similar to the ones for init_libfuncs, above, but instead of having
5456 a mode name and an operand count these functions have two mode names
5457 and no operand count. */
5459 static void
5460 gen_interclass_conv_libfunc (convert_optab tab,
5461 const char *opname,
5462 enum machine_mode tmode,
5463 enum machine_mode fmode)
5465 size_t opname_len = strlen (opname);
5466 size_t mname_len = 0;
5468 const char *fname, *tname;
5469 const char *q;
5470 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5471 char *libfunc_name, *suffix;
5472 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5473 char *p;
5475 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5476 depends on which underlying decimal floating point format is used. */
5477 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5479 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5481 nondec_name = XALLOCAVEC (char, prefix_len + opname_len + mname_len + 1 + 1);
5482 nondec_name[0] = '_';
5483 nondec_name[1] = '_';
5484 if (targetm.libfunc_gnu_prefix)
5486 nondec_name[2] = 'g';
5487 nondec_name[3] = 'n';
5488 nondec_name[4] = 'u';
5489 nondec_name[5] = '_';
5492 memcpy (&nondec_name[prefix_len], opname, opname_len);
5493 nondec_suffix = nondec_name + opname_len + prefix_len;
5495 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
5496 dec_name[0] = '_';
5497 dec_name[1] = '_';
5498 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5499 memcpy (&dec_name[2+dec_len], opname, opname_len);
5500 dec_suffix = dec_name + dec_len + opname_len + 2;
5502 fname = GET_MODE_NAME (fmode);
5503 tname = GET_MODE_NAME (tmode);
5505 if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5507 libfunc_name = dec_name;
5508 suffix = dec_suffix;
5510 else
5512 libfunc_name = nondec_name;
5513 suffix = nondec_suffix;
5516 p = suffix;
5517 for (q = fname; *q; p++, q++)
5518 *p = TOLOWER (*q);
5519 for (q = tname; *q; p++, q++)
5520 *p = TOLOWER (*q);
5522 *p = '\0';
5524 set_conv_libfunc (tab, tmode, fmode,
5525 ggc_alloc_string (libfunc_name, p - libfunc_name));
5528 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5529 int->fp conversion. */
5531 static void
5532 gen_int_to_fp_conv_libfunc (convert_optab tab,
5533 const char *opname,
5534 enum machine_mode tmode,
5535 enum machine_mode fmode)
5537 if (GET_MODE_CLASS (fmode) != MODE_INT)
5538 return;
5539 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5540 return;
5541 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5544 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
5545 naming scheme. */
5547 static void
5548 gen_ufloat_conv_libfunc (convert_optab tab,
5549 const char *opname ATTRIBUTE_UNUSED,
5550 enum machine_mode tmode,
5551 enum machine_mode fmode)
5553 if (DECIMAL_FLOAT_MODE_P (tmode))
5554 gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode);
5555 else
5556 gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode);
5559 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5560 fp->int conversion. */
5562 static void
5563 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
5564 const char *opname,
5565 enum machine_mode tmode,
5566 enum machine_mode fmode)
5568 if (GET_MODE_CLASS (fmode) != MODE_INT)
5569 return;
5570 if (GET_MODE_CLASS (tmode) != MODE_FLOAT)
5571 return;
5572 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5575 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5576 fp->int conversion with no decimal floating point involved. */
5578 static void
5579 gen_fp_to_int_conv_libfunc (convert_optab tab,
5580 const char *opname,
5581 enum machine_mode tmode,
5582 enum machine_mode fmode)
5584 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5585 return;
5586 if (GET_MODE_CLASS (tmode) != MODE_INT)
5587 return;
5588 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5591 /* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
5592 The string formation rules are
5593 similar to the ones for init_libfunc, above. */
5595 static void
5596 gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
5597 enum machine_mode tmode, enum machine_mode fmode)
5599 size_t opname_len = strlen (opname);
5600 size_t mname_len = 0;
5602 const char *fname, *tname;
5603 const char *q;
5604 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
5605 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5606 char *libfunc_name, *suffix;
5607 char *p;
5609 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5610 depends on which underlying decimal floating point format is used. */
5611 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5613 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5615 nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
5616 nondec_name[0] = '_';
5617 nondec_name[1] = '_';
5618 if (targetm.libfunc_gnu_prefix)
5620 nondec_name[2] = 'g';
5621 nondec_name[3] = 'n';
5622 nondec_name[4] = 'u';
5623 nondec_name[5] = '_';
5625 memcpy (&nondec_name[prefix_len], opname, opname_len);
5626 nondec_suffix = nondec_name + opname_len + prefix_len;
5628 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
5629 dec_name[0] = '_';
5630 dec_name[1] = '_';
5631 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5632 memcpy (&dec_name[2 + dec_len], opname, opname_len);
5633 dec_suffix = dec_name + dec_len + opname_len + 2;
5635 fname = GET_MODE_NAME (fmode);
5636 tname = GET_MODE_NAME (tmode);
5638 if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5640 libfunc_name = dec_name;
5641 suffix = dec_suffix;
5643 else
5645 libfunc_name = nondec_name;
5646 suffix = nondec_suffix;
5649 p = suffix;
5650 for (q = fname; *q; p++, q++)
5651 *p = TOLOWER (*q);
5652 for (q = tname; *q; p++, q++)
5653 *p = TOLOWER (*q);
5655 *p++ = '2';
5656 *p = '\0';
5658 set_conv_libfunc (tab, tmode, fmode,
5659 ggc_alloc_string (libfunc_name, p - libfunc_name));
5662 /* Pick proper libcall for trunc_optab. We need to chose if we do
5663 truncation or extension and interclass or intraclass. */
5665 static void
5666 gen_trunc_conv_libfunc (convert_optab tab,
5667 const char *opname,
5668 enum machine_mode tmode,
5669 enum machine_mode fmode)
5671 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5672 return;
5673 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5674 return;
5675 if (tmode == fmode)
5676 return;
5678 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
5679 || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
5680 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5682 if (GET_MODE_PRECISION (fmode) <= GET_MODE_PRECISION (tmode))
5683 return;
5685 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
5686 && GET_MODE_CLASS (fmode) == MODE_FLOAT)
5687 || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
5688 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5691 /* Pick proper libcall for extend_optab. We need to chose if we do
5692 truncation or extension and interclass or intraclass. */
5694 static void
5695 gen_extend_conv_libfunc (convert_optab tab,
5696 const char *opname ATTRIBUTE_UNUSED,
5697 enum machine_mode tmode,
5698 enum machine_mode fmode)
5700 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5701 return;
5702 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5703 return;
5704 if (tmode == fmode)
5705 return;
5707 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
5708 || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
5709 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5711 if (GET_MODE_PRECISION (fmode) > GET_MODE_PRECISION (tmode))
5712 return;
5714 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
5715 && GET_MODE_CLASS (fmode) == MODE_FLOAT)
5716 || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
5717 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5720 /* Pick proper libcall for fract_optab. We need to chose if we do
5721 interclass or intraclass. */
5723 static void
5724 gen_fract_conv_libfunc (convert_optab tab,
5725 const char *opname,
5726 enum machine_mode tmode,
5727 enum machine_mode fmode)
5729 if (tmode == fmode)
5730 return;
5731 if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode)))
5732 return;
5734 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
5735 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5736 else
5737 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5740 /* Pick proper libcall for fractuns_optab. */
5742 static void
5743 gen_fractuns_conv_libfunc (convert_optab tab,
5744 const char *opname,
5745 enum machine_mode tmode,
5746 enum machine_mode fmode)
5748 if (tmode == fmode)
5749 return;
5750 /* One mode must be a fixed-point mode, and the other must be an integer
5751 mode. */
5752 if (!((ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT)
5753 || (ALL_FIXED_POINT_MODE_P (fmode)
5754 && GET_MODE_CLASS (tmode) == MODE_INT)))
5755 return;
5757 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5760 /* Pick proper libcall for satfract_optab. We need to chose if we do
5761 interclass or intraclass. */
5763 static void
5764 gen_satfract_conv_libfunc (convert_optab tab,
5765 const char *opname,
5766 enum machine_mode tmode,
5767 enum machine_mode fmode)
5769 if (tmode == fmode)
5770 return;
5771 /* TMODE must be a fixed-point mode. */
5772 if (!ALL_FIXED_POINT_MODE_P (tmode))
5773 return;
5775 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
5776 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5777 else
5778 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5781 /* Pick proper libcall for satfractuns_optab. */
5783 static void
5784 gen_satfractuns_conv_libfunc (convert_optab tab,
5785 const char *opname,
5786 enum machine_mode tmode,
5787 enum machine_mode fmode)
5789 if (tmode == fmode)
5790 return;
5791 /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
5792 if (!(ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT))
5793 return;
5795 gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5798 /* A table of previously-created libfuncs, hashed by name. */
5799 static GTY ((param_is (union tree_node))) htab_t libfunc_decls;
5801 /* Hashtable callbacks for libfunc_decls. */
5803 static hashval_t
5804 libfunc_decl_hash (const void *entry)
5806 return IDENTIFIER_HASH_VALUE (DECL_NAME ((const_tree) entry));
5809 static int
5810 libfunc_decl_eq (const void *entry1, const void *entry2)
5812 return DECL_NAME ((const_tree) entry1) == (const_tree) entry2;
5815 /* Build a decl for a libfunc named NAME. */
5817 tree
5818 build_libfunc_function (const char *name)
5820 tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
5821 get_identifier (name),
5822 build_function_type (integer_type_node, NULL_TREE));
5823 /* ??? We don't have any type information except for this is
5824 a function. Pretend this is "int foo()". */
5825 DECL_ARTIFICIAL (decl) = 1;
5826 DECL_EXTERNAL (decl) = 1;
5827 TREE_PUBLIC (decl) = 1;
5828 gcc_assert (DECL_ASSEMBLER_NAME (decl));
5830 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
5831 are the flags assigned by targetm.encode_section_info. */
5832 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
5834 return decl;
5838 init_one_libfunc (const char *name)
5840 tree id, decl;
5841 void **slot;
5842 hashval_t hash;
5844 if (libfunc_decls == NULL)
5845 libfunc_decls = htab_create_ggc (37, libfunc_decl_hash,
5846 libfunc_decl_eq, NULL);
5848 /* See if we have already created a libfunc decl for this function. */
5849 id = get_identifier (name);
5850 hash = IDENTIFIER_HASH_VALUE (id);
5851 slot = htab_find_slot_with_hash (libfunc_decls, id, hash, INSERT);
5852 decl = (tree) *slot;
5853 if (decl == NULL)
5855 /* Create a new decl, so that it can be passed to
5856 targetm.encode_section_info. */
5857 decl = build_libfunc_function (name);
5858 *slot = decl;
5860 return XEXP (DECL_RTL (decl), 0);
5863 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */
5866 set_user_assembler_libfunc (const char *name, const char *asmspec)
5868 tree id, decl;
5869 void **slot;
5870 hashval_t hash;
5872 id = get_identifier (name);
5873 hash = IDENTIFIER_HASH_VALUE (id);
5874 slot = htab_find_slot_with_hash (libfunc_decls, id, hash, NO_INSERT);
5875 gcc_assert (slot);
5876 decl = (tree) *slot;
5877 set_user_assembler_name (decl, asmspec);
5878 return XEXP (DECL_RTL (decl), 0);
5881 /* Call this to reset the function entry for one optab (OPTABLE) in mode
5882 MODE to NAME, which should be either 0 or a string constant. */
5883 void
5884 set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
5886 rtx val;
5887 struct libfunc_entry e;
5888 struct libfunc_entry **slot;
5889 e.optab = (size_t) (optable - &optab_table[0]);
5890 e.mode1 = mode;
5891 e.mode2 = VOIDmode;
5893 if (name)
5894 val = init_one_libfunc (name);
5895 else
5896 val = 0;
5897 slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
5898 if (*slot == NULL)
5899 *slot = ggc_alloc_libfunc_entry ();
5900 (*slot)->optab = (size_t) (optable - &optab_table[0]);
5901 (*slot)->mode1 = mode;
5902 (*slot)->mode2 = VOIDmode;
5903 (*slot)->libfunc = val;
5906 /* Call this to reset the function entry for one conversion optab
5907 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
5908 either 0 or a string constant. */
5909 void
5910 set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
5911 enum machine_mode fmode, const char *name)
5913 rtx val;
5914 struct libfunc_entry e;
5915 struct libfunc_entry **slot;
5916 e.optab = (size_t) (optable - &convert_optab_table[0]);
5917 e.mode1 = tmode;
5918 e.mode2 = fmode;
5920 if (name)
5921 val = init_one_libfunc (name);
5922 else
5923 val = 0;
5924 slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
5925 if (*slot == NULL)
5926 *slot = ggc_alloc_libfunc_entry ();
5927 (*slot)->optab = (size_t) (optable - &convert_optab_table[0]);
5928 (*slot)->mode1 = tmode;
5929 (*slot)->mode2 = fmode;
5930 (*slot)->libfunc = val;
5933 /* Call this to initialize the contents of the optabs
5934 appropriately for the current target machine. */
5936 void
5937 init_optabs (void)
5939 if (libfunc_hash)
5941 htab_empty (libfunc_hash);
5942 /* We statically initialize the insn_codes with the equivalent of
5943 CODE_FOR_nothing. Repeat the process if reinitialising. */
5944 init_insn_codes ();
5946 else
5947 libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
5949 init_optab (add_optab, PLUS);
5950 init_optabv (addv_optab, PLUS);
5951 init_optab (sub_optab, MINUS);
5952 init_optabv (subv_optab, MINUS);
5953 init_optab (ssadd_optab, SS_PLUS);
5954 init_optab (usadd_optab, US_PLUS);
5955 init_optab (sssub_optab, SS_MINUS);
5956 init_optab (ussub_optab, US_MINUS);
5957 init_optab (smul_optab, MULT);
5958 init_optab (ssmul_optab, SS_MULT);
5959 init_optab (usmul_optab, US_MULT);
5960 init_optabv (smulv_optab, MULT);
5961 init_optab (smul_highpart_optab, UNKNOWN);
5962 init_optab (umul_highpart_optab, UNKNOWN);
5963 init_optab (smul_widen_optab, UNKNOWN);
5964 init_optab (umul_widen_optab, UNKNOWN);
5965 init_optab (usmul_widen_optab, UNKNOWN);
5966 init_optab (smadd_widen_optab, UNKNOWN);
5967 init_optab (umadd_widen_optab, UNKNOWN);
5968 init_optab (ssmadd_widen_optab, UNKNOWN);
5969 init_optab (usmadd_widen_optab, UNKNOWN);
5970 init_optab (smsub_widen_optab, UNKNOWN);
5971 init_optab (umsub_widen_optab, UNKNOWN);
5972 init_optab (ssmsub_widen_optab, UNKNOWN);
5973 init_optab (usmsub_widen_optab, UNKNOWN);
5974 init_optab (sdiv_optab, DIV);
5975 init_optab (ssdiv_optab, SS_DIV);
5976 init_optab (usdiv_optab, US_DIV);
5977 init_optabv (sdivv_optab, DIV);
5978 init_optab (sdivmod_optab, UNKNOWN);
5979 init_optab (udiv_optab, UDIV);
5980 init_optab (udivmod_optab, UNKNOWN);
5981 init_optab (smod_optab, MOD);
5982 init_optab (umod_optab, UMOD);
5983 init_optab (fmod_optab, UNKNOWN);
5984 init_optab (remainder_optab, UNKNOWN);
5985 init_optab (ftrunc_optab, UNKNOWN);
5986 init_optab (and_optab, AND);
5987 init_optab (ior_optab, IOR);
5988 init_optab (xor_optab, XOR);
5989 init_optab (ashl_optab, ASHIFT);
5990 init_optab (ssashl_optab, SS_ASHIFT);
5991 init_optab (usashl_optab, US_ASHIFT);
5992 init_optab (ashr_optab, ASHIFTRT);
5993 init_optab (lshr_optab, LSHIFTRT);
5994 init_optabv (vashl_optab, ASHIFT);
5995 init_optabv (vashr_optab, ASHIFTRT);
5996 init_optabv (vlshr_optab, LSHIFTRT);
5997 init_optab (rotl_optab, ROTATE);
5998 init_optab (rotr_optab, ROTATERT);
5999 init_optab (smin_optab, SMIN);
6000 init_optab (smax_optab, SMAX);
6001 init_optab (umin_optab, UMIN);
6002 init_optab (umax_optab, UMAX);
6003 init_optab (pow_optab, UNKNOWN);
6004 init_optab (atan2_optab, UNKNOWN);
6005 init_optab (fma_optab, FMA);
6006 init_optab (fms_optab, UNKNOWN);
6007 init_optab (fnma_optab, UNKNOWN);
6008 init_optab (fnms_optab, UNKNOWN);
6010 /* These three have codes assigned exclusively for the sake of
6011 have_insn_for. */
6012 init_optab (mov_optab, SET);
6013 init_optab (movstrict_optab, STRICT_LOW_PART);
6014 init_optab (cbranch_optab, COMPARE);
6016 init_optab (cmov_optab, UNKNOWN);
6017 init_optab (cstore_optab, UNKNOWN);
6018 init_optab (ctrap_optab, UNKNOWN);
6020 init_optab (storent_optab, UNKNOWN);
6022 init_optab (cmp_optab, UNKNOWN);
6023 init_optab (ucmp_optab, UNKNOWN);
6025 init_optab (eq_optab, EQ);
6026 init_optab (ne_optab, NE);
6027 init_optab (gt_optab, GT);
6028 init_optab (ge_optab, GE);
6029 init_optab (lt_optab, LT);
6030 init_optab (le_optab, LE);
6031 init_optab (unord_optab, UNORDERED);
6033 init_optab (neg_optab, NEG);
6034 init_optab (ssneg_optab, SS_NEG);
6035 init_optab (usneg_optab, US_NEG);
6036 init_optabv (negv_optab, NEG);
6037 init_optab (abs_optab, ABS);
6038 init_optabv (absv_optab, ABS);
6039 init_optab (addcc_optab, UNKNOWN);
6040 init_optab (one_cmpl_optab, NOT);
6041 init_optab (bswap_optab, BSWAP);
6042 init_optab (ffs_optab, FFS);
6043 init_optab (clz_optab, CLZ);
6044 init_optab (ctz_optab, CTZ);
6045 init_optab (clrsb_optab, CLRSB);
6046 init_optab (popcount_optab, POPCOUNT);
6047 init_optab (parity_optab, PARITY);
6048 init_optab (sqrt_optab, SQRT);
6049 init_optab (floor_optab, UNKNOWN);
6050 init_optab (ceil_optab, UNKNOWN);
6051 init_optab (round_optab, UNKNOWN);
6052 init_optab (btrunc_optab, UNKNOWN);
6053 init_optab (nearbyint_optab, UNKNOWN);
6054 init_optab (rint_optab, UNKNOWN);
6055 init_optab (sincos_optab, UNKNOWN);
6056 init_optab (sin_optab, UNKNOWN);
6057 init_optab (asin_optab, UNKNOWN);
6058 init_optab (cos_optab, UNKNOWN);
6059 init_optab (acos_optab, UNKNOWN);
6060 init_optab (exp_optab, UNKNOWN);
6061 init_optab (exp10_optab, UNKNOWN);
6062 init_optab (exp2_optab, UNKNOWN);
6063 init_optab (expm1_optab, UNKNOWN);
6064 init_optab (ldexp_optab, UNKNOWN);
6065 init_optab (scalb_optab, UNKNOWN);
6066 init_optab (significand_optab, UNKNOWN);
6067 init_optab (logb_optab, UNKNOWN);
6068 init_optab (ilogb_optab, UNKNOWN);
6069 init_optab (log_optab, UNKNOWN);
6070 init_optab (log10_optab, UNKNOWN);
6071 init_optab (log2_optab, UNKNOWN);
6072 init_optab (log1p_optab, UNKNOWN);
6073 init_optab (tan_optab, UNKNOWN);
6074 init_optab (atan_optab, UNKNOWN);
6075 init_optab (copysign_optab, UNKNOWN);
6076 init_optab (signbit_optab, UNKNOWN);
6078 init_optab (isinf_optab, UNKNOWN);
6080 init_optab (strlen_optab, UNKNOWN);
6081 init_optab (push_optab, UNKNOWN);
6083 init_optab (reduc_smax_optab, UNKNOWN);
6084 init_optab (reduc_umax_optab, UNKNOWN);
6085 init_optab (reduc_smin_optab, UNKNOWN);
6086 init_optab (reduc_umin_optab, UNKNOWN);
6087 init_optab (reduc_splus_optab, UNKNOWN);
6088 init_optab (reduc_uplus_optab, UNKNOWN);
6090 init_optab (ssum_widen_optab, UNKNOWN);
6091 init_optab (usum_widen_optab, UNKNOWN);
6092 init_optab (sdot_prod_optab, UNKNOWN);
6093 init_optab (udot_prod_optab, UNKNOWN);
6095 init_optab (vec_extract_optab, UNKNOWN);
6096 init_optab (vec_extract_even_optab, UNKNOWN);
6097 init_optab (vec_extract_odd_optab, UNKNOWN);
6098 init_optab (vec_interleave_high_optab, UNKNOWN);
6099 init_optab (vec_interleave_low_optab, UNKNOWN);
6100 init_optab (vec_set_optab, UNKNOWN);
6101 init_optab (vec_init_optab, UNKNOWN);
6102 init_optab (vec_shl_optab, UNKNOWN);
6103 init_optab (vec_shr_optab, UNKNOWN);
6104 init_optab (vec_realign_load_optab, UNKNOWN);
6105 init_optab (movmisalign_optab, UNKNOWN);
6106 init_optab (vec_widen_umult_hi_optab, UNKNOWN);
6107 init_optab (vec_widen_umult_lo_optab, UNKNOWN);
6108 init_optab (vec_widen_smult_hi_optab, UNKNOWN);
6109 init_optab (vec_widen_smult_lo_optab, UNKNOWN);
6110 init_optab (vec_unpacks_hi_optab, UNKNOWN);
6111 init_optab (vec_unpacks_lo_optab, UNKNOWN);
6112 init_optab (vec_unpacku_hi_optab, UNKNOWN);
6113 init_optab (vec_unpacku_lo_optab, UNKNOWN);
6114 init_optab (vec_unpacks_float_hi_optab, UNKNOWN);
6115 init_optab (vec_unpacks_float_lo_optab, UNKNOWN);
6116 init_optab (vec_unpacku_float_hi_optab, UNKNOWN);
6117 init_optab (vec_unpacku_float_lo_optab, UNKNOWN);
6118 init_optab (vec_pack_trunc_optab, UNKNOWN);
6119 init_optab (vec_pack_usat_optab, UNKNOWN);
6120 init_optab (vec_pack_ssat_optab, UNKNOWN);
6121 init_optab (vec_pack_ufix_trunc_optab, UNKNOWN);
6122 init_optab (vec_pack_sfix_trunc_optab, UNKNOWN);
6124 init_optab (powi_optab, UNKNOWN);
6126 /* Conversions. */
6127 init_convert_optab (sext_optab, SIGN_EXTEND);
6128 init_convert_optab (zext_optab, ZERO_EXTEND);
6129 init_convert_optab (trunc_optab, TRUNCATE);
6130 init_convert_optab (sfix_optab, FIX);
6131 init_convert_optab (ufix_optab, UNSIGNED_FIX);
6132 init_convert_optab (sfixtrunc_optab, UNKNOWN);
6133 init_convert_optab (ufixtrunc_optab, UNKNOWN);
6134 init_convert_optab (sfloat_optab, FLOAT);
6135 init_convert_optab (ufloat_optab, UNSIGNED_FLOAT);
6136 init_convert_optab (lrint_optab, UNKNOWN);
6137 init_convert_optab (lround_optab, UNKNOWN);
6138 init_convert_optab (lfloor_optab, UNKNOWN);
6139 init_convert_optab (lceil_optab, UNKNOWN);
6141 init_convert_optab (fract_optab, FRACT_CONVERT);
6142 init_convert_optab (fractuns_optab, UNSIGNED_FRACT_CONVERT);
6143 init_convert_optab (satfract_optab, SAT_FRACT);
6144 init_convert_optab (satfractuns_optab, UNSIGNED_SAT_FRACT);
6146 /* Fill in the optabs with the insns we support. */
6147 init_all_optabs ();
6149 /* Initialize the optabs with the names of the library functions. */
6150 add_optab->libcall_basename = "add";
6151 add_optab->libcall_suffix = '3';
6152 add_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6153 addv_optab->libcall_basename = "add";
6154 addv_optab->libcall_suffix = '3';
6155 addv_optab->libcall_gen = gen_intv_fp_libfunc;
6156 ssadd_optab->libcall_basename = "ssadd";
6157 ssadd_optab->libcall_suffix = '3';
6158 ssadd_optab->libcall_gen = gen_signed_fixed_libfunc;
6159 usadd_optab->libcall_basename = "usadd";
6160 usadd_optab->libcall_suffix = '3';
6161 usadd_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6162 sub_optab->libcall_basename = "sub";
6163 sub_optab->libcall_suffix = '3';
6164 sub_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6165 subv_optab->libcall_basename = "sub";
6166 subv_optab->libcall_suffix = '3';
6167 subv_optab->libcall_gen = gen_intv_fp_libfunc;
6168 sssub_optab->libcall_basename = "sssub";
6169 sssub_optab->libcall_suffix = '3';
6170 sssub_optab->libcall_gen = gen_signed_fixed_libfunc;
6171 ussub_optab->libcall_basename = "ussub";
6172 ussub_optab->libcall_suffix = '3';
6173 ussub_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6174 smul_optab->libcall_basename = "mul";
6175 smul_optab->libcall_suffix = '3';
6176 smul_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6177 smulv_optab->libcall_basename = "mul";
6178 smulv_optab->libcall_suffix = '3';
6179 smulv_optab->libcall_gen = gen_intv_fp_libfunc;
6180 ssmul_optab->libcall_basename = "ssmul";
6181 ssmul_optab->libcall_suffix = '3';
6182 ssmul_optab->libcall_gen = gen_signed_fixed_libfunc;
6183 usmul_optab->libcall_basename = "usmul";
6184 usmul_optab->libcall_suffix = '3';
6185 usmul_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6186 sdiv_optab->libcall_basename = "div";
6187 sdiv_optab->libcall_suffix = '3';
6188 sdiv_optab->libcall_gen = gen_int_fp_signed_fixed_libfunc;
6189 sdivv_optab->libcall_basename = "divv";
6190 sdivv_optab->libcall_suffix = '3';
6191 sdivv_optab->libcall_gen = gen_int_libfunc;
6192 ssdiv_optab->libcall_basename = "ssdiv";
6193 ssdiv_optab->libcall_suffix = '3';
6194 ssdiv_optab->libcall_gen = gen_signed_fixed_libfunc;
6195 udiv_optab->libcall_basename = "udiv";
6196 udiv_optab->libcall_suffix = '3';
6197 udiv_optab->libcall_gen = gen_int_unsigned_fixed_libfunc;
6198 usdiv_optab->libcall_basename = "usdiv";
6199 usdiv_optab->libcall_suffix = '3';
6200 usdiv_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6201 sdivmod_optab->libcall_basename = "divmod";
6202 sdivmod_optab->libcall_suffix = '4';
6203 sdivmod_optab->libcall_gen = gen_int_libfunc;
6204 udivmod_optab->libcall_basename = "udivmod";
6205 udivmod_optab->libcall_suffix = '4';
6206 udivmod_optab->libcall_gen = gen_int_libfunc;
6207 smod_optab->libcall_basename = "mod";
6208 smod_optab->libcall_suffix = '3';
6209 smod_optab->libcall_gen = gen_int_libfunc;
6210 umod_optab->libcall_basename = "umod";
6211 umod_optab->libcall_suffix = '3';
6212 umod_optab->libcall_gen = gen_int_libfunc;
6213 ftrunc_optab->libcall_basename = "ftrunc";
6214 ftrunc_optab->libcall_suffix = '2';
6215 ftrunc_optab->libcall_gen = gen_fp_libfunc;
6216 and_optab->libcall_basename = "and";
6217 and_optab->libcall_suffix = '3';
6218 and_optab->libcall_gen = gen_int_libfunc;
6219 ior_optab->libcall_basename = "ior";
6220 ior_optab->libcall_suffix = '3';
6221 ior_optab->libcall_gen = gen_int_libfunc;
6222 xor_optab->libcall_basename = "xor";
6223 xor_optab->libcall_suffix = '3';
6224 xor_optab->libcall_gen = gen_int_libfunc;
6225 ashl_optab->libcall_basename = "ashl";
6226 ashl_optab->libcall_suffix = '3';
6227 ashl_optab->libcall_gen = gen_int_fixed_libfunc;
6228 ssashl_optab->libcall_basename = "ssashl";
6229 ssashl_optab->libcall_suffix = '3';
6230 ssashl_optab->libcall_gen = gen_signed_fixed_libfunc;
6231 usashl_optab->libcall_basename = "usashl";
6232 usashl_optab->libcall_suffix = '3';
6233 usashl_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6234 ashr_optab->libcall_basename = "ashr";
6235 ashr_optab->libcall_suffix = '3';
6236 ashr_optab->libcall_gen = gen_int_signed_fixed_libfunc;
6237 lshr_optab->libcall_basename = "lshr";
6238 lshr_optab->libcall_suffix = '3';
6239 lshr_optab->libcall_gen = gen_int_unsigned_fixed_libfunc;
6240 smin_optab->libcall_basename = "min";
6241 smin_optab->libcall_suffix = '3';
6242 smin_optab->libcall_gen = gen_int_fp_libfunc;
6243 smax_optab->libcall_basename = "max";
6244 smax_optab->libcall_suffix = '3';
6245 smax_optab->libcall_gen = gen_int_fp_libfunc;
6246 umin_optab->libcall_basename = "umin";
6247 umin_optab->libcall_suffix = '3';
6248 umin_optab->libcall_gen = gen_int_libfunc;
6249 umax_optab->libcall_basename = "umax";
6250 umax_optab->libcall_suffix = '3';
6251 umax_optab->libcall_gen = gen_int_libfunc;
6252 neg_optab->libcall_basename = "neg";
6253 neg_optab->libcall_suffix = '2';
6254 neg_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6255 ssneg_optab->libcall_basename = "ssneg";
6256 ssneg_optab->libcall_suffix = '2';
6257 ssneg_optab->libcall_gen = gen_signed_fixed_libfunc;
6258 usneg_optab->libcall_basename = "usneg";
6259 usneg_optab->libcall_suffix = '2';
6260 usneg_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6261 negv_optab->libcall_basename = "neg";
6262 negv_optab->libcall_suffix = '2';
6263 negv_optab->libcall_gen = gen_intv_fp_libfunc;
6264 one_cmpl_optab->libcall_basename = "one_cmpl";
6265 one_cmpl_optab->libcall_suffix = '2';
6266 one_cmpl_optab->libcall_gen = gen_int_libfunc;
6267 ffs_optab->libcall_basename = "ffs";
6268 ffs_optab->libcall_suffix = '2';
6269 ffs_optab->libcall_gen = gen_int_libfunc;
6270 clz_optab->libcall_basename = "clz";
6271 clz_optab->libcall_suffix = '2';
6272 clz_optab->libcall_gen = gen_int_libfunc;
6273 ctz_optab->libcall_basename = "ctz";
6274 ctz_optab->libcall_suffix = '2';
6275 ctz_optab->libcall_gen = gen_int_libfunc;
6276 clrsb_optab->libcall_basename = "clrsb";
6277 clrsb_optab->libcall_suffix = '2';
6278 clrsb_optab->libcall_gen = gen_int_libfunc;
6279 popcount_optab->libcall_basename = "popcount";
6280 popcount_optab->libcall_suffix = '2';
6281 popcount_optab->libcall_gen = gen_int_libfunc;
6282 parity_optab->libcall_basename = "parity";
6283 parity_optab->libcall_suffix = '2';
6284 parity_optab->libcall_gen = gen_int_libfunc;
6286 /* Comparison libcalls for integers MUST come in pairs,
6287 signed/unsigned. */
6288 cmp_optab->libcall_basename = "cmp";
6289 cmp_optab->libcall_suffix = '2';
6290 cmp_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6291 ucmp_optab->libcall_basename = "ucmp";
6292 ucmp_optab->libcall_suffix = '2';
6293 ucmp_optab->libcall_gen = gen_int_libfunc;
6295 /* EQ etc are floating point only. */
6296 eq_optab->libcall_basename = "eq";
6297 eq_optab->libcall_suffix = '2';
6298 eq_optab->libcall_gen = gen_fp_libfunc;
6299 ne_optab->libcall_basename = "ne";
6300 ne_optab->libcall_suffix = '2';
6301 ne_optab->libcall_gen = gen_fp_libfunc;
6302 gt_optab->libcall_basename = "gt";
6303 gt_optab->libcall_suffix = '2';
6304 gt_optab->libcall_gen = gen_fp_libfunc;
6305 ge_optab->libcall_basename = "ge";
6306 ge_optab->libcall_suffix = '2';
6307 ge_optab->libcall_gen = gen_fp_libfunc;
6308 lt_optab->libcall_basename = "lt";
6309 lt_optab->libcall_suffix = '2';
6310 lt_optab->libcall_gen = gen_fp_libfunc;
6311 le_optab->libcall_basename = "le";
6312 le_optab->libcall_suffix = '2';
6313 le_optab->libcall_gen = gen_fp_libfunc;
6314 unord_optab->libcall_basename = "unord";
6315 unord_optab->libcall_suffix = '2';
6316 unord_optab->libcall_gen = gen_fp_libfunc;
6318 powi_optab->libcall_basename = "powi";
6319 powi_optab->libcall_suffix = '2';
6320 powi_optab->libcall_gen = gen_fp_libfunc;
6322 /* Conversions. */
6323 sfloat_optab->libcall_basename = "float";
6324 sfloat_optab->libcall_gen = gen_int_to_fp_conv_libfunc;
6325 ufloat_optab->libcall_gen = gen_ufloat_conv_libfunc;
6326 sfix_optab->libcall_basename = "fix";
6327 sfix_optab->libcall_gen = gen_fp_to_int_conv_libfunc;
6328 ufix_optab->libcall_basename = "fixuns";
6329 ufix_optab->libcall_gen = gen_fp_to_int_conv_libfunc;
6330 lrint_optab->libcall_basename = "lrint";
6331 lrint_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6332 lround_optab->libcall_basename = "lround";
6333 lround_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6334 lfloor_optab->libcall_basename = "lfloor";
6335 lfloor_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6336 lceil_optab->libcall_basename = "lceil";
6337 lceil_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6339 /* trunc_optab is also used for FLOAT_EXTEND. */
6340 sext_optab->libcall_basename = "extend";
6341 sext_optab->libcall_gen = gen_extend_conv_libfunc;
6342 trunc_optab->libcall_basename = "trunc";
6343 trunc_optab->libcall_gen = gen_trunc_conv_libfunc;
6345 /* Conversions for fixed-point modes and other modes. */
6346 fract_optab->libcall_basename = "fract";
6347 fract_optab->libcall_gen = gen_fract_conv_libfunc;
6348 satfract_optab->libcall_basename = "satfract";
6349 satfract_optab->libcall_gen = gen_satfract_conv_libfunc;
6350 fractuns_optab->libcall_basename = "fractuns";
6351 fractuns_optab->libcall_gen = gen_fractuns_conv_libfunc;
6352 satfractuns_optab->libcall_basename = "satfractuns";
6353 satfractuns_optab->libcall_gen = gen_satfractuns_conv_libfunc;
6355 /* The ffs function operates on `int'. Fall back on it if we do not
6356 have a libgcc2 function for that width. */
6357 if (INT_TYPE_SIZE < BITS_PER_WORD)
6358 set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, MODE_INT, 0),
6359 "ffs");
6361 /* Explicitly initialize the bswap libfuncs since we need them to be
6362 valid for things other than word_mode. */
6363 if (targetm.libfunc_gnu_prefix)
6365 set_optab_libfunc (bswap_optab, SImode, "__gnu_bswapsi2");
6366 set_optab_libfunc (bswap_optab, DImode, "__gnu_bswapdi2");
6368 else
6370 set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
6371 set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
6374 /* Use cabs for double complex abs, since systems generally have cabs.
6375 Don't define any libcall for float complex, so that cabs will be used. */
6376 if (complex_double_type_node)
6377 set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node), "cabs");
6379 abort_libfunc = init_one_libfunc ("abort");
6380 memcpy_libfunc = init_one_libfunc ("memcpy");
6381 memmove_libfunc = init_one_libfunc ("memmove");
6382 memcmp_libfunc = init_one_libfunc ("memcmp");
6383 memset_libfunc = init_one_libfunc ("memset");
6384 setbits_libfunc = init_one_libfunc ("__setbits");
6386 #ifndef DONT_USE_BUILTIN_SETJMP
6387 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
6388 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
6389 #else
6390 setjmp_libfunc = init_one_libfunc ("setjmp");
6391 longjmp_libfunc = init_one_libfunc ("longjmp");
6392 #endif
6393 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
6394 unwind_sjlj_unregister_libfunc
6395 = init_one_libfunc ("_Unwind_SjLj_Unregister");
6397 /* For function entry/exit instrumentation. */
6398 profile_function_entry_libfunc
6399 = init_one_libfunc ("__cyg_profile_func_enter");
6400 profile_function_exit_libfunc
6401 = init_one_libfunc ("__cyg_profile_func_exit");
6403 gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
6405 /* Allow the target to add more libcalls or rename some, etc. */
6406 targetm.init_libfuncs ();
6409 /* Print information about the current contents of the optabs on
6410 STDERR. */
6412 DEBUG_FUNCTION void
6413 debug_optab_libfuncs (void)
6415 int i;
6416 int j;
6417 int k;
6419 /* Dump the arithmetic optabs. */
6420 for (i = 0; i != (int) OTI_MAX; i++)
6421 for (j = 0; j < NUM_MACHINE_MODES; ++j)
6423 optab o;
6424 rtx l;
6426 o = &optab_table[i];
6427 l = optab_libfunc (o, (enum machine_mode) j);
6428 if (l)
6430 gcc_assert (GET_CODE (l) == SYMBOL_REF);
6431 fprintf (stderr, "%s\t%s:\t%s\n",
6432 GET_RTX_NAME (o->code),
6433 GET_MODE_NAME (j),
6434 XSTR (l, 0));
6438 /* Dump the conversion optabs. */
6439 for (i = 0; i < (int) COI_MAX; ++i)
6440 for (j = 0; j < NUM_MACHINE_MODES; ++j)
6441 for (k = 0; k < NUM_MACHINE_MODES; ++k)
6443 convert_optab o;
6444 rtx l;
6446 o = &convert_optab_table[i];
6447 l = convert_optab_libfunc (o, (enum machine_mode) j,
6448 (enum machine_mode) k);
6449 if (l)
6451 gcc_assert (GET_CODE (l) == SYMBOL_REF);
6452 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
6453 GET_RTX_NAME (o->code),
6454 GET_MODE_NAME (j),
6455 GET_MODE_NAME (k),
6456 XSTR (l, 0));
6462 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6463 CODE. Return 0 on failure. */
6466 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
6468 enum machine_mode mode = GET_MODE (op1);
6469 enum insn_code icode;
6470 rtx insn;
6471 rtx trap_rtx;
6473 if (mode == VOIDmode)
6474 return 0;
6476 icode = optab_handler (ctrap_optab, mode);
6477 if (icode == CODE_FOR_nothing)
6478 return 0;
6480 /* Some targets only accept a zero trap code. */
6481 if (!insn_operand_matches (icode, 3, tcode))
6482 return 0;
6484 do_pending_stack_adjust ();
6485 start_sequence ();
6486 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
6487 &trap_rtx, &mode);
6488 if (!trap_rtx)
6489 insn = NULL_RTX;
6490 else
6491 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
6492 tcode);
6494 /* If that failed, then give up. */
6495 if (insn == 0)
6497 end_sequence ();
6498 return 0;
6501 emit_insn (insn);
6502 insn = get_insns ();
6503 end_sequence ();
6504 return insn;
6507 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6508 or unsigned operation code. */
6510 static enum rtx_code
6511 get_rtx_code (enum tree_code tcode, bool unsignedp)
6513 enum rtx_code code;
6514 switch (tcode)
6516 case EQ_EXPR:
6517 code = EQ;
6518 break;
6519 case NE_EXPR:
6520 code = NE;
6521 break;
6522 case LT_EXPR:
6523 code = unsignedp ? LTU : LT;
6524 break;
6525 case LE_EXPR:
6526 code = unsignedp ? LEU : LE;
6527 break;
6528 case GT_EXPR:
6529 code = unsignedp ? GTU : GT;
6530 break;
6531 case GE_EXPR:
6532 code = unsignedp ? GEU : GE;
6533 break;
6535 case UNORDERED_EXPR:
6536 code = UNORDERED;
6537 break;
6538 case ORDERED_EXPR:
6539 code = ORDERED;
6540 break;
6541 case UNLT_EXPR:
6542 code = UNLT;
6543 break;
6544 case UNLE_EXPR:
6545 code = UNLE;
6546 break;
6547 case UNGT_EXPR:
6548 code = UNGT;
6549 break;
6550 case UNGE_EXPR:
6551 code = UNGE;
6552 break;
6553 case UNEQ_EXPR:
6554 code = UNEQ;
6555 break;
6556 case LTGT_EXPR:
6557 code = LTGT;
6558 break;
6560 default:
6561 gcc_unreachable ();
6563 return code;
6566 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6567 unsigned operators. Do not generate compare instruction. */
6569 static rtx
6570 vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
6572 struct expand_operand ops[2];
6573 enum rtx_code rcode;
6574 tree t_op0, t_op1;
6575 rtx rtx_op0, rtx_op1;
6577 /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
6578 ensures that condition is a relational operation. */
6579 gcc_assert (COMPARISON_CLASS_P (cond));
6581 rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
6582 t_op0 = TREE_OPERAND (cond, 0);
6583 t_op1 = TREE_OPERAND (cond, 1);
6585 /* Expand operands. */
6586 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
6587 EXPAND_STACK_PARM);
6588 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
6589 EXPAND_STACK_PARM);
6591 create_input_operand (&ops[0], rtx_op0, GET_MODE (rtx_op0));
6592 create_input_operand (&ops[1], rtx_op1, GET_MODE (rtx_op1));
6593 if (!maybe_legitimize_operands (icode, 4, 2, ops))
6594 gcc_unreachable ();
6595 return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
6598 /* Return insn code for TYPE, the type of a VEC_COND_EXPR. */
6600 static inline enum insn_code
6601 get_vcond_icode (tree type, enum machine_mode mode)
6603 enum insn_code icode = CODE_FOR_nothing;
6605 if (TYPE_UNSIGNED (type))
6606 icode = direct_optab_handler (vcondu_optab, mode);
6607 else
6608 icode = direct_optab_handler (vcond_optab, mode);
6609 return icode;
6612 /* Return TRUE iff, appropriate vector insns are available
6613 for vector cond expr with type TYPE in VMODE mode. */
6615 bool
6616 expand_vec_cond_expr_p (tree type, enum machine_mode vmode)
6618 if (get_vcond_icode (type, vmode) == CODE_FOR_nothing)
6619 return false;
6620 return true;
6623 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
6624 three operands. */
6627 expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
6628 rtx target)
6630 struct expand_operand ops[6];
6631 enum insn_code icode;
6632 rtx comparison, rtx_op1, rtx_op2;
6633 enum machine_mode mode = TYPE_MODE (vec_cond_type);
6634 bool unsignedp = TYPE_UNSIGNED (vec_cond_type);
6636 icode = get_vcond_icode (vec_cond_type, mode);
6637 if (icode == CODE_FOR_nothing)
6638 return 0;
6640 comparison = vector_compare_rtx (op0, unsignedp, icode);
6641 rtx_op1 = expand_normal (op1);
6642 rtx_op2 = expand_normal (op2);
6644 create_output_operand (&ops[0], target, mode);
6645 create_input_operand (&ops[1], rtx_op1, mode);
6646 create_input_operand (&ops[2], rtx_op2, mode);
6647 create_fixed_operand (&ops[3], comparison);
6648 create_fixed_operand (&ops[4], XEXP (comparison, 0));
6649 create_fixed_operand (&ops[5], XEXP (comparison, 1));
6650 expand_insn (icode, 6, ops);
6651 return ops[0].value;
6655 /* This is an internal subroutine of the other compare_and_swap expanders.
6656 MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
6657 operation. TARGET is an optional place to store the value result of
6658 the operation. ICODE is the particular instruction to expand. Return
6659 the result of the operation. */
6661 static rtx
6662 expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
6663 rtx target, enum insn_code icode)
6665 struct expand_operand ops[4];
6666 enum machine_mode mode = GET_MODE (mem);
6668 create_output_operand (&ops[0], target, mode);
6669 create_fixed_operand (&ops[1], mem);
6670 /* OLD_VAL and NEW_VAL may have been promoted to a wider mode.
6671 Shrink them if so. */
6672 create_convert_operand_to (&ops[2], old_val, mode, true);
6673 create_convert_operand_to (&ops[3], new_val, mode, true);
6674 if (maybe_expand_insn (icode, 4, ops))
6675 return ops[0].value;
6676 return NULL_RTX;
6679 /* Expand a compare-and-swap operation and return its value. */
6682 expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
6684 enum machine_mode mode = GET_MODE (mem);
6685 enum insn_code icode
6686 = direct_optab_handler (sync_compare_and_swap_optab, mode);
6688 if (icode == CODE_FOR_nothing)
6689 return NULL_RTX;
6691 return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
6694 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
6695 pattern. */
6697 static void
6698 find_cc_set (rtx x, const_rtx pat, void *data)
6700 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
6701 && GET_CODE (pat) == SET)
6703 rtx *p_cc_reg = (rtx *) data;
6704 gcc_assert (!*p_cc_reg);
6705 *p_cc_reg = x;
6709 /* Expand a compare-and-swap operation and store true into the result if
6710 the operation was successful and false otherwise. Return the result.
6711 Unlike other routines, TARGET is not optional. */
6714 expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
6716 enum machine_mode mode = GET_MODE (mem);
6717 enum insn_code icode;
6718 rtx subtarget, seq, cc_reg;
6720 /* If the target supports a compare-and-swap pattern that simultaneously
6721 sets some flag for success, then use it. Otherwise use the regular
6722 compare-and-swap and follow that immediately with a compare insn. */
6723 icode = direct_optab_handler (sync_compare_and_swap_optab, mode);
6724 if (icode == CODE_FOR_nothing)
6725 return NULL_RTX;
6727 do_pending_stack_adjust ();
6730 start_sequence ();
6731 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
6732 NULL_RTX, icode);
6733 cc_reg = NULL_RTX;
6734 if (subtarget == NULL_RTX)
6736 end_sequence ();
6737 return NULL_RTX;
6740 if (have_insn_for (COMPARE, CCmode))
6741 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
6742 seq = get_insns ();
6743 end_sequence ();
6745 /* We might be comparing against an old value. Try again. :-( */
6746 if (!cc_reg && MEM_P (old_val))
6748 seq = NULL_RTX;
6749 old_val = force_reg (mode, old_val);
6752 while (!seq);
6754 emit_insn (seq);
6755 if (cc_reg)
6756 return emit_store_flag_force (target, EQ, cc_reg, const0_rtx, VOIDmode, 0, 1);
6757 else
6758 return emit_store_flag_force (target, EQ, subtarget, old_val, VOIDmode, 1, 1);
6761 /* This is a helper function for the other atomic operations. This function
6762 emits a loop that contains SEQ that iterates until a compare-and-swap
6763 operation at the end succeeds. MEM is the memory to be modified. SEQ is
6764 a set of instructions that takes a value from OLD_REG as an input and
6765 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
6766 set to the current contents of MEM. After SEQ, a compare-and-swap will
6767 attempt to update MEM with NEW_REG. The function returns true when the
6768 loop was generated successfully. */
6770 static bool
6771 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
6773 enum machine_mode mode = GET_MODE (mem);
6774 enum insn_code icode;
6775 rtx label, cmp_reg, subtarget, cc_reg;
6777 /* The loop we want to generate looks like
6779 cmp_reg = mem;
6780 label:
6781 old_reg = cmp_reg;
6782 seq;
6783 cmp_reg = compare-and-swap(mem, old_reg, new_reg)
6784 if (cmp_reg != old_reg)
6785 goto label;
6787 Note that we only do the plain load from memory once. Subsequent
6788 iterations use the value loaded by the compare-and-swap pattern. */
6790 label = gen_label_rtx ();
6791 cmp_reg = gen_reg_rtx (mode);
6793 emit_move_insn (cmp_reg, mem);
6794 emit_label (label);
6795 emit_move_insn (old_reg, cmp_reg);
6796 if (seq)
6797 emit_insn (seq);
6799 /* If the target supports a compare-and-swap pattern that simultaneously
6800 sets some flag for success, then use it. Otherwise use the regular
6801 compare-and-swap and follow that immediately with a compare insn. */
6802 icode = direct_optab_handler (sync_compare_and_swap_optab, mode);
6803 if (icode == CODE_FOR_nothing)
6804 return false;
6806 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
6807 cmp_reg, icode);
6808 if (subtarget == NULL_RTX)
6809 return false;
6811 cc_reg = NULL_RTX;
6812 if (have_insn_for (COMPARE, CCmode))
6813 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
6814 if (cc_reg)
6816 cmp_reg = cc_reg;
6817 old_reg = const0_rtx;
6819 else
6821 if (subtarget != cmp_reg)
6822 emit_move_insn (cmp_reg, subtarget);
6825 /* ??? Mark this jump predicted not taken? */
6826 emit_cmp_and_jump_insns (cmp_reg, old_reg, NE, const0_rtx, GET_MODE (cmp_reg), 1,
6827 label);
6828 return true;
6831 /* This function generates the atomic operation MEM CODE= VAL. In this
6832 case, we do not care about any resulting value. Returns NULL if we
6833 cannot generate the operation. */
6836 expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
6838 enum machine_mode mode = GET_MODE (mem);
6839 enum insn_code icode;
6840 rtx insn;
6842 /* Look to see if the target supports the operation directly. */
6843 switch (code)
6845 case PLUS:
6846 icode = direct_optab_handler (sync_add_optab, mode);
6847 break;
6848 case IOR:
6849 icode = direct_optab_handler (sync_ior_optab, mode);
6850 break;
6851 case XOR:
6852 icode = direct_optab_handler (sync_xor_optab, mode);
6853 break;
6854 case AND:
6855 icode = direct_optab_handler (sync_and_optab, mode);
6856 break;
6857 case NOT:
6858 icode = direct_optab_handler (sync_nand_optab, mode);
6859 break;
6861 case MINUS:
6862 icode = direct_optab_handler (sync_sub_optab, mode);
6863 if (icode == CODE_FOR_nothing || CONST_INT_P (val))
6865 icode = direct_optab_handler (sync_add_optab, mode);
6866 if (icode != CODE_FOR_nothing)
6868 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6869 code = PLUS;
6872 break;
6874 default:
6875 gcc_unreachable ();
6878 /* Generate the direct operation, if present. */
6879 if (icode != CODE_FOR_nothing)
6881 struct expand_operand ops[2];
6883 create_fixed_operand (&ops[0], mem);
6884 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6885 create_convert_operand_to (&ops[1], val, mode, true);
6886 if (maybe_expand_insn (icode, 2, ops))
6887 return const0_rtx;
6890 /* Failing that, generate a compare-and-swap loop in which we perform the
6891 operation with normal arithmetic instructions. */
6892 if (direct_optab_handler (sync_compare_and_swap_optab, mode)
6893 != CODE_FOR_nothing)
6895 rtx t0 = gen_reg_rtx (mode), t1;
6897 start_sequence ();
6899 t1 = t0;
6900 if (code == NOT)
6902 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
6903 true, OPTAB_LIB_WIDEN);
6904 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
6906 else
6907 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6908 true, OPTAB_LIB_WIDEN);
6909 insn = get_insns ();
6910 end_sequence ();
6912 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6913 return const0_rtx;
6916 return NULL_RTX;
6919 /* This function generates the atomic operation MEM CODE= VAL. In this
6920 case, we do care about the resulting value: if AFTER is true then
6921 return the value MEM holds after the operation, if AFTER is false
6922 then return the value MEM holds before the operation. TARGET is an
6923 optional place for the result value to be stored. */
6926 expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
6927 bool after, rtx target)
6929 enum machine_mode mode = GET_MODE (mem);
6930 enum insn_code old_code, new_code, icode;
6931 bool compensate;
6932 rtx insn;
6934 /* Look to see if the target supports the operation directly. */
6935 switch (code)
6937 case PLUS:
6938 old_code = direct_optab_handler (sync_old_add_optab, mode);
6939 new_code = direct_optab_handler (sync_new_add_optab, mode);
6940 break;
6941 case IOR:
6942 old_code = direct_optab_handler (sync_old_ior_optab, mode);
6943 new_code = direct_optab_handler (sync_new_ior_optab, mode);
6944 break;
6945 case XOR:
6946 old_code = direct_optab_handler (sync_old_xor_optab, mode);
6947 new_code = direct_optab_handler (sync_new_xor_optab, mode);
6948 break;
6949 case AND:
6950 old_code = direct_optab_handler (sync_old_and_optab, mode);
6951 new_code = direct_optab_handler (sync_new_and_optab, mode);
6952 break;
6953 case NOT:
6954 old_code = direct_optab_handler (sync_old_nand_optab, mode);
6955 new_code = direct_optab_handler (sync_new_nand_optab, mode);
6956 break;
6958 case MINUS:
6959 old_code = direct_optab_handler (sync_old_sub_optab, mode);
6960 new_code = direct_optab_handler (sync_new_sub_optab, mode);
6961 if ((old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
6962 || CONST_INT_P (val))
6964 old_code = direct_optab_handler (sync_old_add_optab, mode);
6965 new_code = direct_optab_handler (sync_new_add_optab, mode);
6966 if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
6968 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6969 code = PLUS;
6972 break;
6974 default:
6975 gcc_unreachable ();
6978 /* If the target does supports the proper new/old operation, great. But
6979 if we only support the opposite old/new operation, check to see if we
6980 can compensate. In the case in which the old value is supported, then
6981 we can always perform the operation again with normal arithmetic. In
6982 the case in which the new value is supported, then we can only handle
6983 this in the case the operation is reversible. */
6984 compensate = false;
6985 if (after)
6987 icode = new_code;
6988 if (icode == CODE_FOR_nothing)
6990 icode = old_code;
6991 if (icode != CODE_FOR_nothing)
6992 compensate = true;
6995 else
6997 icode = old_code;
6998 if (icode == CODE_FOR_nothing
6999 && (code == PLUS || code == MINUS || code == XOR))
7001 icode = new_code;
7002 if (icode != CODE_FOR_nothing)
7003 compensate = true;
7007 /* If we found something supported, great. */
7008 if (icode != CODE_FOR_nothing)
7010 struct expand_operand ops[3];
7012 create_output_operand (&ops[0], target, mode);
7013 create_fixed_operand (&ops[1], mem);
7014 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7015 create_convert_operand_to (&ops[2], val, mode, true);
7016 if (maybe_expand_insn (icode, 3, ops))
7018 target = ops[0].value;
7019 val = ops[2].value;
7020 /* If we need to compensate for using an operation with the
7021 wrong return value, do so now. */
7022 if (compensate)
7024 if (!after)
7026 if (code == PLUS)
7027 code = MINUS;
7028 else if (code == MINUS)
7029 code = PLUS;
7032 if (code == NOT)
7034 target = expand_simple_binop (mode, AND, target, val,
7035 NULL_RTX, true,
7036 OPTAB_LIB_WIDEN);
7037 target = expand_simple_unop (mode, code, target,
7038 NULL_RTX, true);
7040 else
7041 target = expand_simple_binop (mode, code, target, val,
7042 NULL_RTX, true,
7043 OPTAB_LIB_WIDEN);
7046 return target;
7050 /* Failing that, generate a compare-and-swap loop in which we perform the
7051 operation with normal arithmetic instructions. */
7052 if (direct_optab_handler (sync_compare_and_swap_optab, mode)
7053 != CODE_FOR_nothing)
7055 rtx t0 = gen_reg_rtx (mode), t1;
7057 if (!target || !register_operand (target, mode))
7058 target = gen_reg_rtx (mode);
7060 start_sequence ();
7062 if (!after)
7063 emit_move_insn (target, t0);
7064 t1 = t0;
7065 if (code == NOT)
7067 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
7068 true, OPTAB_LIB_WIDEN);
7069 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
7071 else
7072 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
7073 true, OPTAB_LIB_WIDEN);
7074 if (after)
7075 emit_move_insn (target, t1);
7077 insn = get_insns ();
7078 end_sequence ();
7080 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7081 return target;
7084 return NULL_RTX;
7087 /* This function expands a test-and-set operation. Ideally we atomically
7088 store VAL in MEM and return the previous value in MEM. Some targets
7089 may not support this operation and only support VAL with the constant 1;
7090 in this case while the return value will be 0/1, but the exact value
7091 stored in MEM is target defined. TARGET is an option place to stick
7092 the return value. */
7095 expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
7097 enum machine_mode mode = GET_MODE (mem);
7098 enum insn_code icode;
7100 /* If the target supports the test-and-set directly, great. */
7101 icode = direct_optab_handler (sync_lock_test_and_set_optab, mode);
7102 if (icode != CODE_FOR_nothing)
7104 struct expand_operand ops[3];
7106 create_output_operand (&ops[0], target, mode);
7107 create_fixed_operand (&ops[1], mem);
7108 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7109 create_convert_operand_to (&ops[2], val, mode, true);
7110 if (maybe_expand_insn (icode, 3, ops))
7111 return ops[0].value;
7114 /* Otherwise, use a compare-and-swap loop for the exchange. */
7115 if (direct_optab_handler (sync_compare_and_swap_optab, mode)
7116 != CODE_FOR_nothing)
7118 if (!target || !register_operand (target, mode))
7119 target = gen_reg_rtx (mode);
7120 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7121 val = convert_modes (mode, GET_MODE (val), val, 1);
7122 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
7123 return target;
7126 return NULL_RTX;
7129 /* Return true if OPERAND is suitable for operand number OPNO of
7130 instruction ICODE. */
7132 bool
7133 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
7135 return (!insn_data[(int) icode].operand[opno].predicate
7136 || (insn_data[(int) icode].operand[opno].predicate
7137 (operand, insn_data[(int) icode].operand[opno].mode)));
7140 /* TARGET is a target of a multiword operation that we are going to
7141 implement as a series of word-mode operations. Return true if
7142 TARGET is suitable for this purpose. */
7144 bool
7145 valid_multiword_target_p (rtx target)
7147 enum machine_mode mode;
7148 int i;
7150 mode = GET_MODE (target);
7151 for (i = 0; i < GET_MODE_SIZE (mode); i += UNITS_PER_WORD)
7152 if (!validate_subreg (word_mode, mode, target, i))
7153 return false;
7154 return true;
7157 /* Like maybe_legitimize_operand, but do not change the code of the
7158 current rtx value. */
7160 static bool
7161 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
7162 struct expand_operand *op)
7164 /* See if the operand matches in its current form. */
7165 if (insn_operand_matches (icode, opno, op->value))
7166 return true;
7168 /* If the operand is a memory whose address has no side effects,
7169 try forcing the address into a register. The check for side
7170 effects is important because force_reg cannot handle things
7171 like auto-modified addresses. */
7172 if (insn_data[(int) icode].operand[opno].allows_mem
7173 && MEM_P (op->value)
7174 && !side_effects_p (XEXP (op->value, 0)))
7176 rtx addr, mem, last;
7178 last = get_last_insn ();
7179 addr = force_reg (Pmode, XEXP (op->value, 0));
7180 mem = replace_equiv_address (op->value, addr);
7181 if (insn_operand_matches (icode, opno, mem))
7183 op->value = mem;
7184 return true;
7186 delete_insns_since (last);
7189 return false;
7192 /* Try to make OP match operand OPNO of instruction ICODE. Return true
7193 on success, storing the new operand value back in OP. */
7195 static bool
7196 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
7197 struct expand_operand *op)
7199 enum machine_mode mode, imode;
7200 bool old_volatile_ok, result;
7202 mode = op->mode;
7203 switch (op->type)
7205 case EXPAND_FIXED:
7206 old_volatile_ok = volatile_ok;
7207 volatile_ok = true;
7208 result = maybe_legitimize_operand_same_code (icode, opno, op);
7209 volatile_ok = old_volatile_ok;
7210 return result;
7212 case EXPAND_OUTPUT:
7213 gcc_assert (mode != VOIDmode);
7214 if (op->value
7215 && op->value != const0_rtx
7216 && GET_MODE (op->value) == mode
7217 && maybe_legitimize_operand_same_code (icode, opno, op))
7218 return true;
7220 op->value = gen_reg_rtx (mode);
7221 break;
7223 case EXPAND_INPUT:
7224 input:
7225 gcc_assert (mode != VOIDmode);
7226 gcc_assert (GET_MODE (op->value) == VOIDmode
7227 || GET_MODE (op->value) == mode);
7228 if (maybe_legitimize_operand_same_code (icode, opno, op))
7229 return true;
7231 op->value = copy_to_mode_reg (mode, op->value);
7232 break;
7234 case EXPAND_CONVERT_TO:
7235 gcc_assert (mode != VOIDmode);
7236 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
7237 goto input;
7239 case EXPAND_CONVERT_FROM:
7240 if (GET_MODE (op->value) != VOIDmode)
7241 mode = GET_MODE (op->value);
7242 else
7243 /* The caller must tell us what mode this value has. */
7244 gcc_assert (mode != VOIDmode);
7246 imode = insn_data[(int) icode].operand[opno].mode;
7247 if (imode != VOIDmode && imode != mode)
7249 op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
7250 mode = imode;
7252 goto input;
7254 case EXPAND_ADDRESS:
7255 gcc_assert (mode != VOIDmode);
7256 op->value = convert_memory_address (mode, op->value);
7257 goto input;
7259 case EXPAND_INTEGER:
7260 mode = insn_data[(int) icode].operand[opno].mode;
7261 if (mode != VOIDmode && const_int_operand (op->value, mode))
7262 goto input;
7263 break;
7265 return insn_operand_matches (icode, opno, op->value);
7268 /* Make OP describe an input operand that should have the same value
7269 as VALUE, after any mode conversion that the target might request.
7270 TYPE is the type of VALUE. */
7272 void
7273 create_convert_operand_from_type (struct expand_operand *op,
7274 rtx value, tree type)
7276 create_convert_operand_from (op, value, TYPE_MODE (type),
7277 TYPE_UNSIGNED (type));
7280 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
7281 of instruction ICODE. Return true on success, leaving the new operand
7282 values in the OPS themselves. Emit no code on failure. */
7284 bool
7285 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
7286 unsigned int nops, struct expand_operand *ops)
7288 rtx last;
7289 unsigned int i;
7291 last = get_last_insn ();
7292 for (i = 0; i < nops; i++)
7293 if (!maybe_legitimize_operand (icode, opno + i, &ops[i]))
7295 delete_insns_since (last);
7296 return false;
7298 return true;
7301 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
7302 as its operands. Return the instruction pattern on success,
7303 and emit any necessary set-up code. Return null and emit no
7304 code on failure. */
7307 maybe_gen_insn (enum insn_code icode, unsigned int nops,
7308 struct expand_operand *ops)
7310 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
7311 if (!maybe_legitimize_operands (icode, 0, nops, ops))
7312 return NULL_RTX;
7314 switch (nops)
7316 case 1:
7317 return GEN_FCN (icode) (ops[0].value);
7318 case 2:
7319 return GEN_FCN (icode) (ops[0].value, ops[1].value);
7320 case 3:
7321 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
7322 case 4:
7323 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7324 ops[3].value);
7325 case 5:
7326 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7327 ops[3].value, ops[4].value);
7328 case 6:
7329 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7330 ops[3].value, ops[4].value, ops[5].value);
7332 gcc_unreachable ();
7335 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7336 as its operands. Return true on success and emit no code on failure. */
7338 bool
7339 maybe_expand_insn (enum insn_code icode, unsigned int nops,
7340 struct expand_operand *ops)
7342 rtx pat = maybe_gen_insn (icode, nops, ops);
7343 if (pat)
7345 emit_insn (pat);
7346 return true;
7348 return false;
7351 /* Like maybe_expand_insn, but for jumps. */
7353 bool
7354 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
7355 struct expand_operand *ops)
7357 rtx pat = maybe_gen_insn (icode, nops, ops);
7358 if (pat)
7360 emit_jump_insn (pat);
7361 return true;
7363 return false;
7366 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
7367 as its operands. */
7369 void
7370 expand_insn (enum insn_code icode, unsigned int nops,
7371 struct expand_operand *ops)
7373 if (!maybe_expand_insn (icode, nops, ops))
7374 gcc_unreachable ();
7377 /* Like expand_insn, but for jumps. */
7379 void
7380 expand_jump_insn (enum insn_code icode, unsigned int nops,
7381 struct expand_operand *ops)
7383 if (!maybe_expand_jump_insn (icode, nops, ops))
7384 gcc_unreachable ();
7387 #include "gt-optabs.h"