xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/optabs.c (revision 9fb66d812c00ebfb445c0b47dea128f32aa6fe96)
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2    Copyright (C) 1987-2019 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "target.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "memmodel.h"
29 #include "predict.h"
30 #include "tm_p.h"
31 #include "expmed.h"
32 #include "optabs.h"
33 #include "emit-rtl.h"
34 #include "recog.h"
35 #include "diagnostic-core.h"
36 #include "rtx-vector-builder.h"
37 
38 /* Include insn-config.h before expr.h so that HAVE_conditional_move
39    is properly defined.  */
40 #include "stor-layout.h"
41 #include "except.h"
42 #include "dojump.h"
43 #include "explow.h"
44 #include "expr.h"
45 #include "optabs-tree.h"
46 #include "libfuncs.h"
47 
48 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
49 				   machine_mode *);
50 static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int);
51 static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool);
52 
53 /* Debug facility for use in GDB.  */
54 void debug_optab_libfuncs (void);
55 
56 /* Add a REG_EQUAL note to the last insn in INSNS.  TARGET is being set to
57    the result of operation CODE applied to OP0 (and OP1 if it is a binary
58    operation).  OP0_MODE is OP0's mode.
59 
60    If the last insn does not set TARGET, don't do anything, but return 1.
61 
62    If the last insn or a previous insn sets TARGET and TARGET is one of OP0
63    or OP1, don't add the REG_EQUAL note but return 0.  Our caller can then
64    try again, ensuring that TARGET is not one of the operands.  */
65 
66 static int
67 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
68 		rtx op1, machine_mode op0_mode)
69 {
70   rtx_insn *last_insn;
71   rtx set;
72   rtx note;
73 
74   gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
75 
76   if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
77       && GET_RTX_CLASS (code) != RTX_BIN_ARITH
78       && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
79       && GET_RTX_CLASS (code) != RTX_COMPARE
80       && GET_RTX_CLASS (code) != RTX_UNARY)
81     return 1;
82 
83   if (GET_CODE (target) == ZERO_EXTRACT)
84     return 1;
85 
86   for (last_insn = insns;
87        NEXT_INSN (last_insn) != NULL_RTX;
88        last_insn = NEXT_INSN (last_insn))
89     ;
90 
91   /* If TARGET is in OP0 or OP1, punt.  We'd end up with a note referencing
92      a value changing in the insn, so the note would be invalid for CSE.  */
93   if (reg_overlap_mentioned_p (target, op0)
94       || (op1 && reg_overlap_mentioned_p (target, op1)))
95     {
96       if (MEM_P (target)
97 	  && (rtx_equal_p (target, op0)
98 	      || (op1 && rtx_equal_p (target, op1))))
99 	{
100 	  /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
101 	     over expanding it as temp = MEM op X, MEM = temp.  If the target
102 	     supports MEM = MEM op X instructions, it is sometimes too hard
103 	     to reconstruct that form later, especially if X is also a memory,
104 	     and due to multiple occurrences of addresses the address might
105 	     be forced into register unnecessarily.
106 	     Note that not emitting the REG_EQUIV note might inhibit
107 	     CSE in some cases.  */
108 	  set = single_set (last_insn);
109 	  if (set
110 	      && GET_CODE (SET_SRC (set)) == code
111 	      && MEM_P (SET_DEST (set))
112 	      && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
113 		  || (op1 && rtx_equal_p (SET_DEST (set),
114 					  XEXP (SET_SRC (set), 1)))))
115 	    return 1;
116 	}
117       return 0;
118     }
119 
120   set = set_for_reg_notes (last_insn);
121   if (set == NULL_RTX)
122     return 1;
123 
124   if (! rtx_equal_p (SET_DEST (set), target)
125       /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it.  */
126       && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
127 	  || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
128     return 1;
129 
130   if (GET_RTX_CLASS (code) == RTX_UNARY)
131     switch (code)
132       {
133       case FFS:
134       case CLZ:
135       case CTZ:
136       case CLRSB:
137       case POPCOUNT:
138       case PARITY:
139       case BSWAP:
140 	if (op0_mode != VOIDmode && GET_MODE (target) != op0_mode)
141 	  {
142 	    note = gen_rtx_fmt_e (code, op0_mode, copy_rtx (op0));
143 	    if (GET_MODE_UNIT_SIZE (op0_mode)
144 		> GET_MODE_UNIT_SIZE (GET_MODE (target)))
145 	      note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
146 					 note, op0_mode);
147 	    else
148 	      note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
149 					 note, op0_mode);
150 	    break;
151 	  }
152 	/* FALLTHRU */
153       default:
154 	note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
155 	break;
156       }
157   else
158     note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
159 
160   set_unique_reg_note (last_insn, REG_EQUAL, note);
161 
162   return 1;
163 }
164 
165 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
166    for a widening operation would be.  In most cases this would be OP0, but if
167    that's a constant it'll be VOIDmode, which isn't useful.  */
168 
169 static machine_mode
170 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
171 {
172   machine_mode m0 = GET_MODE (op0);
173   machine_mode m1 = GET_MODE (op1);
174   machine_mode result;
175 
176   if (m0 == VOIDmode && m1 == VOIDmode)
177     return to_mode;
178   else if (m0 == VOIDmode || GET_MODE_UNIT_SIZE (m0) < GET_MODE_UNIT_SIZE (m1))
179     result = m1;
180   else
181     result = m0;
182 
183   if (GET_MODE_UNIT_SIZE (result) > GET_MODE_UNIT_SIZE (to_mode))
184     return to_mode;
185 
186   return result;
187 }
188 
189 /* Widen OP to MODE and return the rtx for the widened operand.  UNSIGNEDP
190    says whether OP is signed or unsigned.  NO_EXTEND is nonzero if we need
191    not actually do a sign-extend or zero-extend, but can leave the
192    higher-order bits of the result rtx undefined, for example, in the case
193    of logical operations, but not right shifts.  */
194 
195 static rtx
196 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
197 	       int unsignedp, int no_extend)
198 {
199   rtx result;
200   scalar_int_mode int_mode;
201 
202   /* If we don't have to extend and this is a constant, return it.  */
203   if (no_extend && GET_MODE (op) == VOIDmode)
204     return op;
205 
206   /* If we must extend do so.  If OP is a SUBREG for a promoted object, also
207      extend since it will be more efficient to do so unless the signedness of
208      a promoted object differs from our extension.  */
209   if (! no_extend
210       || !is_a <scalar_int_mode> (mode, &int_mode)
211       || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
212 	  && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
213     return convert_modes (mode, oldmode, op, unsignedp);
214 
215   /* If MODE is no wider than a single word, we return a lowpart or paradoxical
216      SUBREG.  */
217   if (GET_MODE_SIZE (int_mode) <= UNITS_PER_WORD)
218     return gen_lowpart (int_mode, force_reg (GET_MODE (op), op));
219 
220   /* Otherwise, get an object of MODE, clobber it, and set the low-order
221      part to OP.  */
222 
223   result = gen_reg_rtx (int_mode);
224   emit_clobber (result);
225   emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
226   return result;
227 }
228 
229 /* Expand vector widening operations.
230 
231    There are two different classes of operations handled here:
232    1) Operations whose result is wider than all the arguments to the operation.
233       Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
234       In this case OP0 and optionally OP1 would be initialized,
235       but WIDE_OP wouldn't (not relevant for this case).
236    2) Operations whose result is of the same size as the last argument to the
237       operation, but wider than all the other arguments to the operation.
238       Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
239       In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
240 
241    E.g, when called to expand the following operations, this is how
242    the arguments will be initialized:
243                                 nops    OP0     OP1     WIDE_OP
244    widening-sum                 2       oprnd0  -       oprnd1
245    widening-dot-product         3       oprnd0  oprnd1  oprnd2
246    widening-mult                2       oprnd0  oprnd1  -
247    type-promotion (vec-unpack)  1       oprnd0  -       -  */
248 
249 rtx
250 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
251 			   rtx target, int unsignedp)
252 {
253   struct expand_operand eops[4];
254   tree oprnd0, oprnd1, oprnd2;
255   machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
256   optab widen_pattern_optab;
257   enum insn_code icode;
258   int nops = TREE_CODE_LENGTH (ops->code);
259   int op;
260   bool sbool = false;
261 
262   oprnd0 = ops->op0;
263   tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
264   if (ops->code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
265       || ops->code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
266     /* The sign is from the result type rather than operand's type
267        for these ops.  */
268     widen_pattern_optab
269       = optab_for_tree_code (ops->code, ops->type, optab_default);
270   else if ((ops->code == VEC_UNPACK_HI_EXPR
271 	    || ops->code == VEC_UNPACK_LO_EXPR)
272 	   && VECTOR_BOOLEAN_TYPE_P (ops->type)
273 	   && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (oprnd0))
274 	   && TYPE_MODE (ops->type) == TYPE_MODE (TREE_TYPE (oprnd0))
275 	   && SCALAR_INT_MODE_P (TYPE_MODE (ops->type)))
276     {
277       /* For VEC_UNPACK_{LO,HI}_EXPR if the mode of op0 and result is
278 	 the same scalar mode for VECTOR_BOOLEAN_TYPE_P vectors, use
279 	 vec_unpacks_sbool_{lo,hi}_optab, so that we can pass in
280 	 the pattern number of elements in the wider vector.  */
281       widen_pattern_optab
282 	= (ops->code == VEC_UNPACK_HI_EXPR
283 	   ? vec_unpacks_sbool_hi_optab : vec_unpacks_sbool_lo_optab);
284       sbool = true;
285     }
286   else
287     widen_pattern_optab
288       = optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
289   if (ops->code == WIDEN_MULT_PLUS_EXPR
290       || ops->code == WIDEN_MULT_MINUS_EXPR)
291     icode = find_widening_optab_handler (widen_pattern_optab,
292 					 TYPE_MODE (TREE_TYPE (ops->op2)),
293 					 tmode0);
294   else
295     icode = optab_handler (widen_pattern_optab, tmode0);
296   gcc_assert (icode != CODE_FOR_nothing);
297 
298   if (nops >= 2)
299     {
300       oprnd1 = ops->op1;
301       tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
302     }
303   else if (sbool)
304     {
305       nops = 2;
306       op1 = GEN_INT (TYPE_VECTOR_SUBPARTS (TREE_TYPE (oprnd0)).to_constant ());
307       tmode1 = tmode0;
308     }
309 
310   /* The last operand is of a wider mode than the rest of the operands.  */
311   if (nops == 2)
312     wmode = tmode1;
313   else if (nops == 3)
314     {
315       gcc_assert (tmode1 == tmode0);
316       gcc_assert (op1);
317       oprnd2 = ops->op2;
318       wmode = TYPE_MODE (TREE_TYPE (oprnd2));
319     }
320 
321   op = 0;
322   create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
323   create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
324   if (op1)
325     create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
326   if (wide_op)
327     create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
328   expand_insn (icode, op, eops);
329   return eops[0].value;
330 }
331 
332 /* Generate code to perform an operation specified by TERNARY_OPTAB
333    on operands OP0, OP1 and OP2, with result having machine-mode MODE.
334 
335    UNSIGNEDP is for the case where we have to widen the operands
336    to perform the operation.  It says to use zero-extension.
337 
338    If TARGET is nonzero, the value
339    is generated there, if it is convenient to do so.
340    In all cases an rtx is returned for the locus of the value;
341    this may or may not be TARGET.  */
342 
343 rtx
344 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
345 		   rtx op1, rtx op2, rtx target, int unsignedp)
346 {
347   struct expand_operand ops[4];
348   enum insn_code icode = optab_handler (ternary_optab, mode);
349 
350   gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
351 
352   create_output_operand (&ops[0], target, mode);
353   create_convert_operand_from (&ops[1], op0, mode, unsignedp);
354   create_convert_operand_from (&ops[2], op1, mode, unsignedp);
355   create_convert_operand_from (&ops[3], op2, mode, unsignedp);
356   expand_insn (icode, 4, ops);
357   return ops[0].value;
358 }
359 
360 
361 /* Like expand_binop, but return a constant rtx if the result can be
362    calculated at compile time.  The arguments and return value are
363    otherwise the same as for expand_binop.  */
364 
365 rtx
366 simplify_expand_binop (machine_mode mode, optab binoptab,
367 		       rtx op0, rtx op1, rtx target, int unsignedp,
368 		       enum optab_methods methods)
369 {
370   if (CONSTANT_P (op0) && CONSTANT_P (op1))
371     {
372       rtx x = simplify_binary_operation (optab_to_code (binoptab),
373 					 mode, op0, op1);
374       if (x)
375 	return x;
376     }
377 
378   return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
379 }
380 
381 /* Like simplify_expand_binop, but always put the result in TARGET.
382    Return true if the expansion succeeded.  */
383 
384 bool
385 force_expand_binop (machine_mode mode, optab binoptab,
386 		    rtx op0, rtx op1, rtx target, int unsignedp,
387 		    enum optab_methods methods)
388 {
389   rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
390 				 target, unsignedp, methods);
391   if (x == 0)
392     return false;
393   if (x != target)
394     emit_move_insn (target, x);
395   return true;
396 }
397 
398 /* Create a new vector value in VMODE with all elements set to OP.  The
399    mode of OP must be the element mode of VMODE.  If OP is a constant,
400    then the return value will be a constant.  */
401 
402 rtx
403 expand_vector_broadcast (machine_mode vmode, rtx op)
404 {
405   int n;
406   rtvec vec;
407 
408   gcc_checking_assert (VECTOR_MODE_P (vmode));
409 
410   if (valid_for_const_vector_p (vmode, op))
411     return gen_const_vec_duplicate (vmode, op);
412 
413   insn_code icode = optab_handler (vec_duplicate_optab, vmode);
414   if (icode != CODE_FOR_nothing)
415     {
416       struct expand_operand ops[2];
417       create_output_operand (&ops[0], NULL_RTX, vmode);
418       create_input_operand (&ops[1], op, GET_MODE (op));
419       expand_insn (icode, 2, ops);
420       return ops[0].value;
421     }
422 
423   if (!GET_MODE_NUNITS (vmode).is_constant (&n))
424     return NULL;
425 
426   /* ??? If the target doesn't have a vec_init, then we have no easy way
427      of performing this operation.  Most of this sort of generic support
428      is hidden away in the vector lowering support in gimple.  */
429   icode = convert_optab_handler (vec_init_optab, vmode,
430 				 GET_MODE_INNER (vmode));
431   if (icode == CODE_FOR_nothing)
432     return NULL;
433 
434   vec = rtvec_alloc (n);
435   for (int i = 0; i < n; ++i)
436     RTVEC_ELT (vec, i) = op;
437   rtx ret = gen_reg_rtx (vmode);
438   emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
439 
440   return ret;
441 }
442 
443 /* This subroutine of expand_doubleword_shift handles the cases in which
444    the effective shift value is >= BITS_PER_WORD.  The arguments and return
445    value are the same as for the parent routine, except that SUPERWORD_OP1
446    is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
447    INTO_TARGET may be null if the caller has decided to calculate it.  */
448 
449 static bool
450 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
451 			rtx outof_target, rtx into_target,
452 			int unsignedp, enum optab_methods methods)
453 {
454   if (into_target != 0)
455     if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
456 			     into_target, unsignedp, methods))
457       return false;
458 
459   if (outof_target != 0)
460     {
461       /* For a signed right shift, we must fill OUTOF_TARGET with copies
462 	 of the sign bit, otherwise we must fill it with zeros.  */
463       if (binoptab != ashr_optab)
464 	emit_move_insn (outof_target, CONST0_RTX (word_mode));
465       else
466 	if (!force_expand_binop (word_mode, binoptab, outof_input,
467 				 gen_int_shift_amount (word_mode,
468 						       BITS_PER_WORD - 1),
469 				 outof_target, unsignedp, methods))
470 	  return false;
471     }
472   return true;
473 }
474 
475 /* This subroutine of expand_doubleword_shift handles the cases in which
476    the effective shift value is < BITS_PER_WORD.  The arguments and return
477    value are the same as for the parent routine.  */
478 
479 static bool
480 expand_subword_shift (scalar_int_mode op1_mode, optab binoptab,
481 		      rtx outof_input, rtx into_input, rtx op1,
482 		      rtx outof_target, rtx into_target,
483 		      int unsignedp, enum optab_methods methods,
484 		      unsigned HOST_WIDE_INT shift_mask)
485 {
486   optab reverse_unsigned_shift, unsigned_shift;
487   rtx tmp, carries;
488 
489   reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
490   unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
491 
492   /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
493      We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
494      the opposite direction to BINOPTAB.  */
495   if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
496     {
497       carries = outof_input;
498       tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
499 					    op1_mode), op1_mode);
500       tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
501 				   0, true, methods);
502     }
503   else
504     {
505       /* We must avoid shifting by BITS_PER_WORD bits since that is either
506 	 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
507 	 has unknown behavior.  Do a single shift first, then shift by the
508 	 remainder.  It's OK to use ~OP1 as the remainder if shift counts
509 	 are truncated to the mode size.  */
510       carries = expand_binop (word_mode, reverse_unsigned_shift,
511 			      outof_input, const1_rtx, 0, unsignedp, methods);
512       if (shift_mask == BITS_PER_WORD - 1)
513 	{
514 	  tmp = immed_wide_int_const
515 	    (wi::minus_one (GET_MODE_PRECISION (op1_mode)), op1_mode);
516 	  tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
517 				       0, true, methods);
518 	}
519       else
520 	{
521 	  tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
522 						op1_mode), op1_mode);
523 	  tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
524 				       0, true, methods);
525 	}
526     }
527   if (tmp == 0 || carries == 0)
528     return false;
529   carries = expand_binop (word_mode, reverse_unsigned_shift,
530 			  carries, tmp, 0, unsignedp, methods);
531   if (carries == 0)
532     return false;
533 
534   /* Shift INTO_INPUT logically by OP1.  This is the last use of INTO_INPUT
535      so the result can go directly into INTO_TARGET if convenient.  */
536   tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
537 		      into_target, unsignedp, methods);
538   if (tmp == 0)
539     return false;
540 
541   /* Now OR in the bits carried over from OUTOF_INPUT.  */
542   if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
543 			   into_target, unsignedp, methods))
544     return false;
545 
546   /* Use a standard word_mode shift for the out-of half.  */
547   if (outof_target != 0)
548     if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
549 			     outof_target, unsignedp, methods))
550       return false;
551 
552   return true;
553 }
554 
555 
556 /* Try implementing expand_doubleword_shift using conditional moves.
557    The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
558    otherwise it is by >= BITS_PER_WORD.  SUBWORD_OP1 and SUPERWORD_OP1
559    are the shift counts to use in the former and latter case.  All other
560    arguments are the same as the parent routine.  */
561 
562 static bool
563 expand_doubleword_shift_condmove (scalar_int_mode op1_mode, optab binoptab,
564 				  enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
565 				  rtx outof_input, rtx into_input,
566 				  rtx subword_op1, rtx superword_op1,
567 				  rtx outof_target, rtx into_target,
568 				  int unsignedp, enum optab_methods methods,
569 				  unsigned HOST_WIDE_INT shift_mask)
570 {
571   rtx outof_superword, into_superword;
572 
573   /* Put the superword version of the output into OUTOF_SUPERWORD and
574      INTO_SUPERWORD.  */
575   outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
576   if (outof_target != 0 && subword_op1 == superword_op1)
577     {
578       /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
579 	 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD.  */
580       into_superword = outof_target;
581       if (!expand_superword_shift (binoptab, outof_input, superword_op1,
582 				   outof_superword, 0, unsignedp, methods))
583 	return false;
584     }
585   else
586     {
587       into_superword = gen_reg_rtx (word_mode);
588       if (!expand_superword_shift (binoptab, outof_input, superword_op1,
589 				   outof_superword, into_superword,
590 				   unsignedp, methods))
591 	return false;
592     }
593 
594   /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET.  */
595   if (!expand_subword_shift (op1_mode, binoptab,
596 			     outof_input, into_input, subword_op1,
597 			     outof_target, into_target,
598 			     unsignedp, methods, shift_mask))
599     return false;
600 
601   /* Select between them.  Do the INTO half first because INTO_SUPERWORD
602      might be the current value of OUTOF_TARGET.  */
603   if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
604 			      into_target, into_superword, word_mode, false))
605     return false;
606 
607   if (outof_target != 0)
608     if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
609 				outof_target, outof_superword,
610 				word_mode, false))
611       return false;
612 
613   return true;
614 }
615 
616 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
617    OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
618    input operand; the shift moves bits in the direction OUTOF_INPUT->
619    INTO_TARGET.  OUTOF_TARGET and INTO_TARGET are the equivalent words
620    of the target.  OP1 is the shift count and OP1_MODE is its mode.
621    If OP1 is constant, it will have been truncated as appropriate
622    and is known to be nonzero.
623 
624    If SHIFT_MASK is zero, the result of word shifts is undefined when the
625    shift count is outside the range [0, BITS_PER_WORD).  This routine must
626    avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
627 
628    If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
629    masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
630    fill with zeros or sign bits as appropriate.
631 
632    If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
633    a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
634    Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
635    In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
636    are undefined.
637 
638    BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop.  This function
639    may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
640    OUTOF_INPUT and OUTOF_TARGET.  OUTOF_TARGET can be null if the parent
641    function wants to calculate it itself.
642 
643    Return true if the shift could be successfully synthesized.  */
644 
645 static bool
646 expand_doubleword_shift (scalar_int_mode op1_mode, optab binoptab,
647 			 rtx outof_input, rtx into_input, rtx op1,
648 			 rtx outof_target, rtx into_target,
649 			 int unsignedp, enum optab_methods methods,
650 			 unsigned HOST_WIDE_INT shift_mask)
651 {
652   rtx superword_op1, tmp, cmp1, cmp2;
653   enum rtx_code cmp_code;
654 
655   /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
656      fill the result with sign or zero bits as appropriate.  If so, the value
657      of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1).   Recursively call
658      this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
659      and INTO_INPUT), then emit code to set up OUTOF_TARGET.
660 
661      This isn't worthwhile for constant shifts since the optimizers will
662      cope better with in-range shift counts.  */
663   if (shift_mask >= BITS_PER_WORD
664       && outof_target != 0
665       && !CONSTANT_P (op1))
666     {
667       if (!expand_doubleword_shift (op1_mode, binoptab,
668 				    outof_input, into_input, op1,
669 				    0, into_target,
670 				    unsignedp, methods, shift_mask))
671 	return false;
672       if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
673 			       outof_target, unsignedp, methods))
674 	return false;
675       return true;
676     }
677 
678   /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
679      is true when the effective shift value is less than BITS_PER_WORD.
680      Set SUPERWORD_OP1 to the shift count that should be used to shift
681      OUTOF_INPUT into INTO_TARGET when the condition is false.  */
682   tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
683   if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
684     {
685       /* Set CMP1 to OP1 & BITS_PER_WORD.  The result is zero iff OP1
686 	 is a subword shift count.  */
687       cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
688 				    0, true, methods);
689       cmp2 = CONST0_RTX (op1_mode);
690       cmp_code = EQ;
691       superword_op1 = op1;
692     }
693   else
694     {
695       /* Set CMP1 to OP1 - BITS_PER_WORD.  */
696       cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
697 				    0, true, methods);
698       cmp2 = CONST0_RTX (op1_mode);
699       cmp_code = LT;
700       superword_op1 = cmp1;
701     }
702   if (cmp1 == 0)
703     return false;
704 
705   /* If we can compute the condition at compile time, pick the
706      appropriate subroutine.  */
707   tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
708   if (tmp != 0 && CONST_INT_P (tmp))
709     {
710       if (tmp == const0_rtx)
711 	return expand_superword_shift (binoptab, outof_input, superword_op1,
712 				       outof_target, into_target,
713 				       unsignedp, methods);
714       else
715 	return expand_subword_shift (op1_mode, binoptab,
716 				     outof_input, into_input, op1,
717 				     outof_target, into_target,
718 				     unsignedp, methods, shift_mask);
719     }
720 
721   /* Try using conditional moves to generate straight-line code.  */
722   if (HAVE_conditional_move)
723     {
724       rtx_insn *start = get_last_insn ();
725       if (expand_doubleword_shift_condmove (op1_mode, binoptab,
726 					    cmp_code, cmp1, cmp2,
727 					    outof_input, into_input,
728 					    op1, superword_op1,
729 					    outof_target, into_target,
730 					    unsignedp, methods, shift_mask))
731 	return true;
732       delete_insns_since (start);
733     }
734 
735   /* As a last resort, use branches to select the correct alternative.  */
736   rtx_code_label *subword_label = gen_label_rtx ();
737   rtx_code_label *done_label = gen_label_rtx ();
738 
739   NO_DEFER_POP;
740   do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
741 			   0, 0, subword_label,
742 			   profile_probability::uninitialized ());
743   OK_DEFER_POP;
744 
745   if (!expand_superword_shift (binoptab, outof_input, superword_op1,
746 			       outof_target, into_target,
747 			       unsignedp, methods))
748     return false;
749 
750   emit_jump_insn (targetm.gen_jump (done_label));
751   emit_barrier ();
752   emit_label (subword_label);
753 
754   if (!expand_subword_shift (op1_mode, binoptab,
755 			     outof_input, into_input, op1,
756 			     outof_target, into_target,
757 			     unsignedp, methods, shift_mask))
758     return false;
759 
760   emit_label (done_label);
761   return true;
762 }
763 
764 /* Subroutine of expand_binop.  Perform a double word multiplication of
765    operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
766    as the target's word_mode.  This function return NULL_RTX if anything
767    goes wrong, in which case it may have already emitted instructions
768    which need to be deleted.
769 
770    If we want to multiply two two-word values and have normal and widening
771    multiplies of single-word values, we can do this with three smaller
772    multiplications.
773 
774    The multiplication proceeds as follows:
775 			         _______________________
776 			        [__op0_high_|__op0_low__]
777 			         _______________________
778         *			[__op1_high_|__op1_low__]
779         _______________________________________________
780 			         _______________________
781     (1)				[__op0_low__*__op1_low__]
782 		     _______________________
783     (2a)	    [__op0_low__*__op1_high_]
784 		     _______________________
785     (2b)	    [__op0_high_*__op1_low__]
786          _______________________
787     (3) [__op0_high_*__op1_high_]
788 
789 
790   This gives a 4-word result.  Since we are only interested in the
791   lower 2 words, partial result (3) and the upper words of (2a) and
792   (2b) don't need to be calculated.  Hence (2a) and (2b) can be
793   calculated using non-widening multiplication.
794 
795   (1), however, needs to be calculated with an unsigned widening
796   multiplication.  If this operation is not directly supported we
797   try using a signed widening multiplication and adjust the result.
798   This adjustment works as follows:
799 
800       If both operands are positive then no adjustment is needed.
801 
802       If the operands have different signs, for example op0_low < 0 and
803       op1_low >= 0, the instruction treats the most significant bit of
804       op0_low as a sign bit instead of a bit with significance
805       2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
806       with 2**BITS_PER_WORD - op0_low, and two's complements the
807       result.  Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
808       the result.
809 
810       Similarly, if both operands are negative, we need to add
811       (op0_low + op1_low) * 2**BITS_PER_WORD.
812 
813       We use a trick to adjust quickly.  We logically shift op0_low right
814       (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
815       op0_high (op1_high) before it is used to calculate 2b (2a).  If no
816       logical shift exists, we do an arithmetic right shift and subtract
817       the 0 or -1.  */
818 
819 static rtx
820 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
821 		       bool umulp, enum optab_methods methods)
822 {
823   int low = (WORDS_BIG_ENDIAN ? 1 : 0);
824   int high = (WORDS_BIG_ENDIAN ? 0 : 1);
825   rtx wordm1 = (umulp ? NULL_RTX
826 		: gen_int_shift_amount (word_mode, BITS_PER_WORD - 1));
827   rtx product, adjust, product_high, temp;
828 
829   rtx op0_high = operand_subword_force (op0, high, mode);
830   rtx op0_low = operand_subword_force (op0, low, mode);
831   rtx op1_high = operand_subword_force (op1, high, mode);
832   rtx op1_low = operand_subword_force (op1, low, mode);
833 
834   /* If we're using an unsigned multiply to directly compute the product
835      of the low-order words of the operands and perform any required
836      adjustments of the operands, we begin by trying two more multiplications
837      and then computing the appropriate sum.
838 
839      We have checked above that the required addition is provided.
840      Full-word addition will normally always succeed, especially if
841      it is provided at all, so we don't worry about its failure.  The
842      multiplication may well fail, however, so we do handle that.  */
843 
844   if (!umulp)
845     {
846       /* ??? This could be done with emit_store_flag where available.  */
847       temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
848 			   NULL_RTX, 1, methods);
849       if (temp)
850 	op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
851 				 NULL_RTX, 0, OPTAB_DIRECT);
852       else
853 	{
854 	  temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
855 			       NULL_RTX, 0, methods);
856 	  if (!temp)
857 	    return NULL_RTX;
858 	  op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
859 				   NULL_RTX, 0, OPTAB_DIRECT);
860 	}
861 
862       if (!op0_high)
863 	return NULL_RTX;
864     }
865 
866   adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
867 			 NULL_RTX, 0, OPTAB_DIRECT);
868   if (!adjust)
869     return NULL_RTX;
870 
871   /* OP0_HIGH should now be dead.  */
872 
873   if (!umulp)
874     {
875       /* ??? This could be done with emit_store_flag where available.  */
876       temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
877 			   NULL_RTX, 1, methods);
878       if (temp)
879 	op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
880 				 NULL_RTX, 0, OPTAB_DIRECT);
881       else
882 	{
883 	  temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
884 			       NULL_RTX, 0, methods);
885 	  if (!temp)
886 	    return NULL_RTX;
887 	  op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
888 				   NULL_RTX, 0, OPTAB_DIRECT);
889 	}
890 
891       if (!op1_high)
892 	return NULL_RTX;
893     }
894 
895   temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
896 		       NULL_RTX, 0, OPTAB_DIRECT);
897   if (!temp)
898     return NULL_RTX;
899 
900   /* OP1_HIGH should now be dead.  */
901 
902   adjust = expand_binop (word_mode, add_optab, adjust, temp,
903 			 NULL_RTX, 0, OPTAB_DIRECT);
904 
905   if (target && !REG_P (target))
906     target = NULL_RTX;
907 
908   /* *_widen_optab needs to determine operand mode, make sure at least
909      one operand has non-VOID mode.  */
910   if (GET_MODE (op0_low) == VOIDmode && GET_MODE (op1_low) == VOIDmode)
911     op0_low = force_reg (word_mode, op0_low);
912 
913   if (umulp)
914     product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
915 			    target, 1, OPTAB_DIRECT);
916   else
917     product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
918 			    target, 1, OPTAB_DIRECT);
919 
920   if (!product)
921     return NULL_RTX;
922 
923   product_high = operand_subword (product, high, 1, mode);
924   adjust = expand_binop (word_mode, add_optab, product_high, adjust,
925 			 NULL_RTX, 0, OPTAB_DIRECT);
926   emit_move_insn (product_high, adjust);
927   return product;
928 }
929 
930 /* Wrapper around expand_binop which takes an rtx code to specify
931    the operation to perform, not an optab pointer.  All other
932    arguments are the same.  */
933 rtx
934 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
935 		     rtx op1, rtx target, int unsignedp,
936 		     enum optab_methods methods)
937 {
938   optab binop = code_to_optab (code);
939   gcc_assert (binop);
940 
941   return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
942 }
943 
944 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
945    binop.  Order them according to commutative_operand_precedence and, if
946    possible, try to put TARGET or a pseudo first.  */
947 static bool
948 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
949 {
950   int op0_prec = commutative_operand_precedence (op0);
951   int op1_prec = commutative_operand_precedence (op1);
952 
953   if (op0_prec < op1_prec)
954     return true;
955 
956   if (op0_prec > op1_prec)
957     return false;
958 
959   /* With equal precedence, both orders are ok, but it is better if the
960      first operand is TARGET, or if both TARGET and OP0 are pseudos.  */
961   if (target == 0 || REG_P (target))
962     return (REG_P (op1) && !REG_P (op0)) || target == op1;
963   else
964     return rtx_equal_p (op1, target);
965 }
966 
967 /* Return true if BINOPTAB implements a shift operation.  */
968 
969 static bool
970 shift_optab_p (optab binoptab)
971 {
972   switch (optab_to_code (binoptab))
973     {
974     case ASHIFT:
975     case SS_ASHIFT:
976     case US_ASHIFT:
977     case ASHIFTRT:
978     case LSHIFTRT:
979     case ROTATE:
980     case ROTATERT:
981       return true;
982 
983     default:
984       return false;
985     }
986 }
987 
988 /* Return true if BINOPTAB implements a commutative binary operation.  */
989 
990 static bool
991 commutative_optab_p (optab binoptab)
992 {
993   return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
994 	  || binoptab == smul_widen_optab
995 	  || binoptab == umul_widen_optab
996 	  || binoptab == smul_highpart_optab
997 	  || binoptab == umul_highpart_optab);
998 }
999 
1000 /* X is to be used in mode MODE as operand OPN to BINOPTAB.  If we're
1001    optimizing, and if the operand is a constant that costs more than
1002    1 instruction, force the constant into a register and return that
1003    register.  Return X otherwise.  UNSIGNEDP says whether X is unsigned.  */
1004 
1005 static rtx
1006 avoid_expensive_constant (machine_mode mode, optab binoptab,
1007 			  int opn, rtx x, bool unsignedp)
1008 {
1009   bool speed = optimize_insn_for_speed_p ();
1010 
1011   if (mode != VOIDmode
1012       && optimize
1013       && CONSTANT_P (x)
1014       && (rtx_cost (x, mode, optab_to_code (binoptab), opn, speed)
1015 	  > set_src_cost (x, mode, speed)))
1016     {
1017       if (CONST_INT_P (x))
1018 	{
1019 	  HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
1020 	  if (intval != INTVAL (x))
1021 	    x = GEN_INT (intval);
1022 	}
1023       else
1024 	x = convert_modes (mode, VOIDmode, x, unsignedp);
1025       x = force_reg (mode, x);
1026     }
1027   return x;
1028 }
1029 
1030 /* Helper function for expand_binop: handle the case where there
1031    is an insn ICODE that directly implements the indicated operation.
1032    Returns null if this is not possible.  */
1033 static rtx
1034 expand_binop_directly (enum insn_code icode, machine_mode mode, optab binoptab,
1035 		       rtx op0, rtx op1,
1036 		       rtx target, int unsignedp, enum optab_methods methods,
1037 		       rtx_insn *last)
1038 {
1039   machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
1040   machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
1041   machine_mode mode0, mode1, tmp_mode;
1042   struct expand_operand ops[3];
1043   bool commutative_p;
1044   rtx_insn *pat;
1045   rtx xop0 = op0, xop1 = op1;
1046   bool canonicalize_op1 = false;
1047 
1048   /* If it is a commutative operator and the modes would match
1049      if we would swap the operands, we can save the conversions.  */
1050   commutative_p = commutative_optab_p (binoptab);
1051   if (commutative_p
1052       && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1053       && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode1)
1054     std::swap (xop0, xop1);
1055 
1056   /* If we are optimizing, force expensive constants into a register.  */
1057   xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1058   if (!shift_optab_p (binoptab))
1059     xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1060   else
1061     /* Shifts and rotates often use a different mode for op1 from op0;
1062        for VOIDmode constants we don't know the mode, so force it
1063        to be canonicalized using convert_modes.  */
1064     canonicalize_op1 = true;
1065 
1066   /* In case the insn wants input operands in modes different from
1067      those of the actual operands, convert the operands.  It would
1068      seem that we don't need to convert CONST_INTs, but we do, so
1069      that they're properly zero-extended, sign-extended or truncated
1070      for their mode.  */
1071 
1072   mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1073   if (xmode0 != VOIDmode && xmode0 != mode0)
1074     {
1075       xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1076       mode0 = xmode0;
1077     }
1078 
1079   mode1 = ((GET_MODE (xop1) != VOIDmode || canonicalize_op1)
1080 	   ? GET_MODE (xop1) : mode);
1081   if (xmode1 != VOIDmode && xmode1 != mode1)
1082     {
1083       xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1084       mode1 = xmode1;
1085     }
1086 
1087   /* If operation is commutative,
1088      try to make the first operand a register.
1089      Even better, try to make it the same as the target.
1090      Also try to make the last operand a constant.  */
1091   if (commutative_p
1092       && swap_commutative_operands_with_target (target, xop0, xop1))
1093     std::swap (xop0, xop1);
1094 
1095   /* Now, if insn's predicates don't allow our operands, put them into
1096      pseudo regs.  */
1097 
1098   if (binoptab == vec_pack_trunc_optab
1099       || binoptab == vec_pack_usat_optab
1100       || binoptab == vec_pack_ssat_optab
1101       || binoptab == vec_pack_ufix_trunc_optab
1102       || binoptab == vec_pack_sfix_trunc_optab
1103       || binoptab == vec_packu_float_optab
1104       || binoptab == vec_packs_float_optab)
1105     {
1106       /* The mode of the result is different then the mode of the
1107 	 arguments.  */
1108       tmp_mode = insn_data[(int) icode].operand[0].mode;
1109       if (VECTOR_MODE_P (mode)
1110 	  && maybe_ne (GET_MODE_NUNITS (tmp_mode), 2 * GET_MODE_NUNITS (mode)))
1111 	{
1112 	  delete_insns_since (last);
1113 	  return NULL_RTX;
1114 	}
1115     }
1116   else
1117     tmp_mode = mode;
1118 
1119   create_output_operand (&ops[0], target, tmp_mode);
1120   create_input_operand (&ops[1], xop0, mode0);
1121   create_input_operand (&ops[2], xop1, mode1);
1122   pat = maybe_gen_insn (icode, 3, ops);
1123   if (pat)
1124     {
1125       /* If PAT is composed of more than one insn, try to add an appropriate
1126 	 REG_EQUAL note to it.  If we can't because TEMP conflicts with an
1127 	 operand, call expand_binop again, this time without a target.  */
1128       if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1129 	  && ! add_equal_note (pat, ops[0].value,
1130 			       optab_to_code (binoptab),
1131 			       ops[1].value, ops[2].value, mode0))
1132 	{
1133 	  delete_insns_since (last);
1134 	  return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1135 			       unsignedp, methods);
1136 	}
1137 
1138       emit_insn (pat);
1139       return ops[0].value;
1140     }
1141   delete_insns_since (last);
1142   return NULL_RTX;
1143 }
1144 
1145 /* Generate code to perform an operation specified by BINOPTAB
1146    on operands OP0 and OP1, with result having machine-mode MODE.
1147 
1148    UNSIGNEDP is for the case where we have to widen the operands
1149    to perform the operation.  It says to use zero-extension.
1150 
1151    If TARGET is nonzero, the value
1152    is generated there, if it is convenient to do so.
1153    In all cases an rtx is returned for the locus of the value;
1154    this may or may not be TARGET.  */
1155 
1156 rtx
1157 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
1158 	      rtx target, int unsignedp, enum optab_methods methods)
1159 {
1160   enum optab_methods next_methods
1161     = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1162        ? OPTAB_WIDEN : methods);
1163   enum mode_class mclass;
1164   enum insn_code icode;
1165   machine_mode wider_mode;
1166   scalar_int_mode int_mode;
1167   rtx libfunc;
1168   rtx temp;
1169   rtx_insn *entry_last = get_last_insn ();
1170   rtx_insn *last;
1171 
1172   mclass = GET_MODE_CLASS (mode);
1173 
1174   /* If subtracting an integer constant, convert this into an addition of
1175      the negated constant.  */
1176 
1177   if (binoptab == sub_optab && CONST_INT_P (op1))
1178     {
1179       op1 = negate_rtx (mode, op1);
1180       binoptab = add_optab;
1181     }
1182   /* For shifts, constant invalid op1 might be expanded from different
1183      mode than MODE.  As those are invalid, force them to a register
1184      to avoid further problems during expansion.  */
1185   else if (CONST_INT_P (op1)
1186 	   && shift_optab_p (binoptab)
1187 	   && UINTVAL (op1) >= GET_MODE_BITSIZE (GET_MODE_INNER (mode)))
1188     {
1189       op1 = gen_int_mode (INTVAL (op1), GET_MODE_INNER (mode));
1190       op1 = force_reg (GET_MODE_INNER (mode), op1);
1191     }
1192 
1193   /* Record where to delete back to if we backtrack.  */
1194   last = get_last_insn ();
1195 
1196   /* If we can do it with a three-operand insn, do so.  */
1197 
1198   if (methods != OPTAB_MUST_WIDEN)
1199     {
1200       if (convert_optab_p (binoptab))
1201 	{
1202 	  machine_mode from_mode = widened_mode (mode, op0, op1);
1203 	  icode = find_widening_optab_handler (binoptab, mode, from_mode);
1204 	}
1205       else
1206 	icode = optab_handler (binoptab, mode);
1207       if (icode != CODE_FOR_nothing)
1208 	{
1209 	  temp = expand_binop_directly (icode, mode, binoptab, op0, op1,
1210 					target, unsignedp, methods, last);
1211 	  if (temp)
1212 	    return temp;
1213 	}
1214     }
1215 
1216   /* If we were trying to rotate, and that didn't work, try rotating
1217      the other direction before falling back to shifts and bitwise-or.  */
1218   if (((binoptab == rotl_optab
1219 	&& (icode = optab_handler (rotr_optab, mode)) != CODE_FOR_nothing)
1220        || (binoptab == rotr_optab
1221 	   && (icode = optab_handler (rotl_optab, mode)) != CODE_FOR_nothing))
1222       && is_int_mode (mode, &int_mode))
1223     {
1224       optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1225       rtx newop1;
1226       unsigned int bits = GET_MODE_PRECISION (int_mode);
1227 
1228       if (CONST_INT_P (op1))
1229 	newop1 = gen_int_shift_amount (int_mode, bits - INTVAL (op1));
1230       else if (targetm.shift_truncation_mask (int_mode) == bits - 1)
1231         newop1 = negate_rtx (GET_MODE (op1), op1);
1232       else
1233         newop1 = expand_binop (GET_MODE (op1), sub_optab,
1234 			       gen_int_mode (bits, GET_MODE (op1)), op1,
1235 			       NULL_RTX, unsignedp, OPTAB_DIRECT);
1236 
1237       temp = expand_binop_directly (icode, int_mode, otheroptab, op0, newop1,
1238 				    target, unsignedp, methods, last);
1239       if (temp)
1240 	return temp;
1241     }
1242 
1243   /* If this is a multiply, see if we can do a widening operation that
1244      takes operands of this mode and makes a wider mode.  */
1245 
1246   if (binoptab == smul_optab
1247       && GET_MODE_2XWIDER_MODE (mode).exists (&wider_mode)
1248       && (convert_optab_handler ((unsignedp
1249 				  ? umul_widen_optab
1250 				  : smul_widen_optab),
1251 				 wider_mode, mode) != CODE_FOR_nothing))
1252     {
1253       /* *_widen_optab needs to determine operand mode, make sure at least
1254 	 one operand has non-VOID mode.  */
1255       if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
1256 	op0 = force_reg (mode, op0);
1257       temp = expand_binop (wider_mode,
1258 			   unsignedp ? umul_widen_optab : smul_widen_optab,
1259 			   op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1260 
1261       if (temp != 0)
1262 	{
1263 	  if (GET_MODE_CLASS (mode) == MODE_INT
1264 	      && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1265 	    return gen_lowpart (mode, temp);
1266 	  else
1267 	    return convert_to_mode (mode, temp, unsignedp);
1268 	}
1269     }
1270 
1271   /* If this is a vector shift by a scalar, see if we can do a vector
1272      shift by a vector.  If so, broadcast the scalar into a vector.  */
1273   if (mclass == MODE_VECTOR_INT)
1274     {
1275       optab otheroptab = unknown_optab;
1276 
1277       if (binoptab == ashl_optab)
1278 	otheroptab = vashl_optab;
1279       else if (binoptab == ashr_optab)
1280 	otheroptab = vashr_optab;
1281       else if (binoptab == lshr_optab)
1282 	otheroptab = vlshr_optab;
1283       else if (binoptab == rotl_optab)
1284 	otheroptab = vrotl_optab;
1285       else if (binoptab == rotr_optab)
1286 	otheroptab = vrotr_optab;
1287 
1288       if (otheroptab
1289 	  && (icode = optab_handler (otheroptab, mode)) != CODE_FOR_nothing)
1290 	{
1291 	  /* The scalar may have been extended to be too wide.  Truncate
1292 	     it back to the proper size to fit in the broadcast vector.  */
1293 	  scalar_mode inner_mode = GET_MODE_INNER (mode);
1294 	  if (!CONST_INT_P (op1)
1295 	      && (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (op1)))
1296 		  > GET_MODE_BITSIZE (inner_mode)))
1297 	    op1 = force_reg (inner_mode,
1298 			     simplify_gen_unary (TRUNCATE, inner_mode, op1,
1299 						 GET_MODE (op1)));
1300 	  rtx vop1 = expand_vector_broadcast (mode, op1);
1301 	  if (vop1)
1302 	    {
1303 	      temp = expand_binop_directly (icode, mode, otheroptab, op0, vop1,
1304 					    target, unsignedp, methods, last);
1305 	      if (temp)
1306 		return temp;
1307 	    }
1308 	}
1309     }
1310 
1311   /* Look for a wider mode of the same class for which we think we
1312      can open-code the operation.  Check for a widening multiply at the
1313      wider mode as well.  */
1314 
1315   if (CLASS_HAS_WIDER_MODES_P (mclass)
1316       && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1317     FOR_EACH_WIDER_MODE (wider_mode, mode)
1318       {
1319 	machine_mode next_mode;
1320 	if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1321 	    || (binoptab == smul_optab
1322 		&& GET_MODE_WIDER_MODE (wider_mode).exists (&next_mode)
1323 		&& (find_widening_optab_handler ((unsignedp
1324 						  ? umul_widen_optab
1325 						  : smul_widen_optab),
1326 						 next_mode, mode)
1327 		    != CODE_FOR_nothing)))
1328 	  {
1329 	    rtx xop0 = op0, xop1 = op1;
1330 	    int no_extend = 0;
1331 
1332 	    /* For certain integer operations, we need not actually extend
1333 	       the narrow operands, as long as we will truncate
1334 	       the results to the same narrowness.  */
1335 
1336 	    if ((binoptab == ior_optab || binoptab == and_optab
1337 		 || binoptab == xor_optab
1338 		 || binoptab == add_optab || binoptab == sub_optab
1339 		 || binoptab == smul_optab || binoptab == ashl_optab)
1340 		&& mclass == MODE_INT)
1341 	      {
1342 		no_extend = 1;
1343 		xop0 = avoid_expensive_constant (mode, binoptab, 0,
1344 						 xop0, unsignedp);
1345 		if (binoptab != ashl_optab)
1346 		  xop1 = avoid_expensive_constant (mode, binoptab, 1,
1347 						   xop1, unsignedp);
1348 	      }
1349 
1350 	    xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1351 
1352 	    /* The second operand of a shift must always be extended.  */
1353 	    xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1354 				  no_extend && binoptab != ashl_optab);
1355 
1356 	    temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1357 				 unsignedp, OPTAB_DIRECT);
1358 	    if (temp)
1359 	      {
1360 		if (mclass != MODE_INT
1361                     || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1362 		  {
1363 		    if (target == 0)
1364 		      target = gen_reg_rtx (mode);
1365 		    convert_move (target, temp, 0);
1366 		    return target;
1367 		  }
1368 		else
1369 		  return gen_lowpart (mode, temp);
1370 	      }
1371 	    else
1372 	      delete_insns_since (last);
1373 	  }
1374       }
1375 
1376   /* If operation is commutative,
1377      try to make the first operand a register.
1378      Even better, try to make it the same as the target.
1379      Also try to make the last operand a constant.  */
1380   if (commutative_optab_p (binoptab)
1381       && swap_commutative_operands_with_target (target, op0, op1))
1382     std::swap (op0, op1);
1383 
1384   /* These can be done a word at a time.  */
1385   if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1386       && is_int_mode (mode, &int_mode)
1387       && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
1388       && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1389     {
1390       int i;
1391       rtx_insn *insns;
1392 
1393       /* If TARGET is the same as one of the operands, the REG_EQUAL note
1394 	 won't be accurate, so use a new target.  */
1395       if (target == 0
1396 	  || target == op0
1397 	  || target == op1
1398 	  || !valid_multiword_target_p (target))
1399 	target = gen_reg_rtx (int_mode);
1400 
1401       start_sequence ();
1402 
1403       /* Do the actual arithmetic.  */
1404       machine_mode op0_mode = GET_MODE (op0);
1405       machine_mode op1_mode = GET_MODE (op1);
1406       if (op0_mode == VOIDmode)
1407 	op0_mode = int_mode;
1408       if (op1_mode == VOIDmode)
1409 	op1_mode = int_mode;
1410       for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
1411 	{
1412 	  rtx target_piece = operand_subword (target, i, 1, int_mode);
1413 	  rtx x = expand_binop (word_mode, binoptab,
1414 				operand_subword_force (op0, i, op0_mode),
1415 				operand_subword_force (op1, i, op1_mode),
1416 				target_piece, unsignedp, next_methods);
1417 
1418 	  if (x == 0)
1419 	    break;
1420 
1421 	  if (target_piece != x)
1422 	    emit_move_insn (target_piece, x);
1423 	}
1424 
1425       insns = get_insns ();
1426       end_sequence ();
1427 
1428       if (i == GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD)
1429 	{
1430 	  emit_insn (insns);
1431 	  return target;
1432 	}
1433     }
1434 
1435   /* Synthesize double word shifts from single word shifts.  */
1436   if ((binoptab == lshr_optab || binoptab == ashl_optab
1437        || binoptab == ashr_optab)
1438       && is_int_mode (mode, &int_mode)
1439       && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1440       && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
1441       && GET_MODE_PRECISION (int_mode) == GET_MODE_BITSIZE (int_mode)
1442       && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1443       && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1444       && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1445     {
1446       unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1447       scalar_int_mode op1_mode;
1448 
1449       double_shift_mask = targetm.shift_truncation_mask (int_mode);
1450       shift_mask = targetm.shift_truncation_mask (word_mode);
1451       op1_mode = (GET_MODE (op1) != VOIDmode
1452 		  ? as_a <scalar_int_mode> (GET_MODE (op1))
1453 		  : word_mode);
1454 
1455       /* Apply the truncation to constant shifts.  */
1456       if (double_shift_mask > 0 && CONST_INT_P (op1))
1457 	op1 = gen_int_mode (INTVAL (op1) & double_shift_mask, op1_mode);
1458 
1459       if (op1 == CONST0_RTX (op1_mode))
1460 	return op0;
1461 
1462       /* Make sure that this is a combination that expand_doubleword_shift
1463 	 can handle.  See the comments there for details.  */
1464       if (double_shift_mask == 0
1465 	  || (shift_mask == BITS_PER_WORD - 1
1466 	      && double_shift_mask == BITS_PER_WORD * 2 - 1))
1467 	{
1468 	  rtx_insn *insns;
1469 	  rtx into_target, outof_target;
1470 	  rtx into_input, outof_input;
1471 	  int left_shift, outof_word;
1472 
1473 	  /* If TARGET is the same as one of the operands, the REG_EQUAL note
1474 	     won't be accurate, so use a new target.  */
1475 	  if (target == 0
1476 	      || target == op0
1477 	      || target == op1
1478 	      || !valid_multiword_target_p (target))
1479 	    target = gen_reg_rtx (int_mode);
1480 
1481 	  start_sequence ();
1482 
1483 	  /* OUTOF_* is the word we are shifting bits away from, and
1484 	     INTO_* is the word that we are shifting bits towards, thus
1485 	     they differ depending on the direction of the shift and
1486 	     WORDS_BIG_ENDIAN.  */
1487 
1488 	  left_shift = binoptab == ashl_optab;
1489 	  outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1490 
1491 	  outof_target = operand_subword (target, outof_word, 1, int_mode);
1492 	  into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1493 
1494 	  outof_input = operand_subword_force (op0, outof_word, int_mode);
1495 	  into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1496 
1497 	  if (expand_doubleword_shift (op1_mode, binoptab,
1498 				       outof_input, into_input, op1,
1499 				       outof_target, into_target,
1500 				       unsignedp, next_methods, shift_mask))
1501 	    {
1502 	      insns = get_insns ();
1503 	      end_sequence ();
1504 
1505 	      emit_insn (insns);
1506 	      return target;
1507 	    }
1508 	  end_sequence ();
1509 	}
1510     }
1511 
1512   /* Synthesize double word rotates from single word shifts.  */
1513   if ((binoptab == rotl_optab || binoptab == rotr_optab)
1514       && is_int_mode (mode, &int_mode)
1515       && CONST_INT_P (op1)
1516       && GET_MODE_PRECISION (int_mode) == 2 * BITS_PER_WORD
1517       && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1518       && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1519     {
1520       rtx_insn *insns;
1521       rtx into_target, outof_target;
1522       rtx into_input, outof_input;
1523       rtx inter;
1524       int shift_count, left_shift, outof_word;
1525 
1526       /* If TARGET is the same as one of the operands, the REG_EQUAL note
1527 	 won't be accurate, so use a new target. Do this also if target is not
1528 	 a REG, first because having a register instead may open optimization
1529 	 opportunities, and second because if target and op0 happen to be MEMs
1530 	 designating the same location, we would risk clobbering it too early
1531 	 in the code sequence we generate below.  */
1532       if (target == 0
1533 	  || target == op0
1534 	  || target == op1
1535 	  || !REG_P (target)
1536 	  || !valid_multiword_target_p (target))
1537 	target = gen_reg_rtx (int_mode);
1538 
1539       start_sequence ();
1540 
1541       shift_count = INTVAL (op1);
1542 
1543       /* OUTOF_* is the word we are shifting bits away from, and
1544 	 INTO_* is the word that we are shifting bits towards, thus
1545 	 they differ depending on the direction of the shift and
1546 	 WORDS_BIG_ENDIAN.  */
1547 
1548       left_shift = (binoptab == rotl_optab);
1549       outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1550 
1551       outof_target = operand_subword (target, outof_word, 1, int_mode);
1552       into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1553 
1554       outof_input = operand_subword_force (op0, outof_word, int_mode);
1555       into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1556 
1557       if (shift_count == BITS_PER_WORD)
1558 	{
1559 	  /* This is just a word swap.  */
1560 	  emit_move_insn (outof_target, into_input);
1561 	  emit_move_insn (into_target, outof_input);
1562 	  inter = const0_rtx;
1563 	}
1564       else
1565 	{
1566 	  rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1567 	  HOST_WIDE_INT first_shift_count, second_shift_count;
1568 	  optab reverse_unsigned_shift, unsigned_shift;
1569 
1570 	  reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1571 				    ? lshr_optab : ashl_optab);
1572 
1573 	  unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1574 			    ? ashl_optab : lshr_optab);
1575 
1576 	  if (shift_count > BITS_PER_WORD)
1577 	    {
1578 	      first_shift_count = shift_count - BITS_PER_WORD;
1579 	      second_shift_count = 2 * BITS_PER_WORD - shift_count;
1580 	    }
1581 	  else
1582 	    {
1583 	      first_shift_count = BITS_PER_WORD - shift_count;
1584 	      second_shift_count = shift_count;
1585 	    }
1586 	  rtx first_shift_count_rtx
1587 	    = gen_int_shift_amount (word_mode, first_shift_count);
1588 	  rtx second_shift_count_rtx
1589 	    = gen_int_shift_amount (word_mode, second_shift_count);
1590 
1591 	  into_temp1 = expand_binop (word_mode, unsigned_shift,
1592 				     outof_input, first_shift_count_rtx,
1593 				     NULL_RTX, unsignedp, next_methods);
1594 	  into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1595 				     into_input, second_shift_count_rtx,
1596 				     NULL_RTX, unsignedp, next_methods);
1597 
1598 	  if (into_temp1 != 0 && into_temp2 != 0)
1599 	    inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1600 				  into_target, unsignedp, next_methods);
1601 	  else
1602 	    inter = 0;
1603 
1604 	  if (inter != 0 && inter != into_target)
1605 	    emit_move_insn (into_target, inter);
1606 
1607 	  outof_temp1 = expand_binop (word_mode, unsigned_shift,
1608 				      into_input, first_shift_count_rtx,
1609 				      NULL_RTX, unsignedp, next_methods);
1610 	  outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1611 				      outof_input, second_shift_count_rtx,
1612 				      NULL_RTX, unsignedp, next_methods);
1613 
1614 	  if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1615 	    inter = expand_binop (word_mode, ior_optab,
1616 				  outof_temp1, outof_temp2,
1617 				  outof_target, unsignedp, next_methods);
1618 
1619 	  if (inter != 0 && inter != outof_target)
1620 	    emit_move_insn (outof_target, inter);
1621 	}
1622 
1623       insns = get_insns ();
1624       end_sequence ();
1625 
1626       if (inter != 0)
1627 	{
1628 	  emit_insn (insns);
1629 	  return target;
1630 	}
1631     }
1632 
1633   /* These can be done a word at a time by propagating carries.  */
1634   if ((binoptab == add_optab || binoptab == sub_optab)
1635       && is_int_mode (mode, &int_mode)
1636       && GET_MODE_SIZE (int_mode) >= 2 * UNITS_PER_WORD
1637       && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1638     {
1639       unsigned int i;
1640       optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1641       const unsigned int nwords = GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD;
1642       rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1643       rtx xop0, xop1, xtarget;
1644 
1645       /* We can handle either a 1 or -1 value for the carry.  If STORE_FLAG
1646 	 value is one of those, use it.  Otherwise, use 1 since it is the
1647 	 one easiest to get.  */
1648 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1649       int normalizep = STORE_FLAG_VALUE;
1650 #else
1651       int normalizep = 1;
1652 #endif
1653 
1654       /* Prepare the operands.  */
1655       xop0 = force_reg (int_mode, op0);
1656       xop1 = force_reg (int_mode, op1);
1657 
1658       xtarget = gen_reg_rtx (int_mode);
1659 
1660       if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1661 	target = xtarget;
1662 
1663       /* Indicate for flow that the entire target reg is being set.  */
1664       if (REG_P (target))
1665 	emit_clobber (xtarget);
1666 
1667       /* Do the actual arithmetic.  */
1668       for (i = 0; i < nwords; i++)
1669 	{
1670 	  int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1671 	  rtx target_piece = operand_subword (xtarget, index, 1, int_mode);
1672 	  rtx op0_piece = operand_subword_force (xop0, index, int_mode);
1673 	  rtx op1_piece = operand_subword_force (xop1, index, int_mode);
1674 	  rtx x;
1675 
1676 	  /* Main add/subtract of the input operands.  */
1677 	  x = expand_binop (word_mode, binoptab,
1678 			    op0_piece, op1_piece,
1679 			    target_piece, unsignedp, next_methods);
1680 	  if (x == 0)
1681 	    break;
1682 
1683 	  if (i + 1 < nwords)
1684 	    {
1685 	      /* Store carry from main add/subtract.  */
1686 	      carry_out = gen_reg_rtx (word_mode);
1687 	      carry_out = emit_store_flag_force (carry_out,
1688 						 (binoptab == add_optab
1689 						  ? LT : GT),
1690 						 x, op0_piece,
1691 						 word_mode, 1, normalizep);
1692 	    }
1693 
1694 	  if (i > 0)
1695 	    {
1696 	      rtx newx;
1697 
1698 	      /* Add/subtract previous carry to main result.  */
1699 	      newx = expand_binop (word_mode,
1700 				   normalizep == 1 ? binoptab : otheroptab,
1701 				   x, carry_in,
1702 				   NULL_RTX, 1, next_methods);
1703 
1704 	      if (i + 1 < nwords)
1705 		{
1706 		  /* Get out carry from adding/subtracting carry in.  */
1707 		  rtx carry_tmp = gen_reg_rtx (word_mode);
1708 		  carry_tmp = emit_store_flag_force (carry_tmp,
1709 						     (binoptab == add_optab
1710 						      ? LT : GT),
1711 						     newx, x,
1712 						     word_mode, 1, normalizep);
1713 
1714 		  /* Logical-ior the two poss. carry together.  */
1715 		  carry_out = expand_binop (word_mode, ior_optab,
1716 					    carry_out, carry_tmp,
1717 					    carry_out, 0, next_methods);
1718 		  if (carry_out == 0)
1719 		    break;
1720 		}
1721 	      emit_move_insn (target_piece, newx);
1722 	    }
1723 	  else
1724 	    {
1725 	      if (x != target_piece)
1726 		emit_move_insn (target_piece, x);
1727 	    }
1728 
1729 	  carry_in = carry_out;
1730 	}
1731 
1732       if (i == GET_MODE_BITSIZE (int_mode) / (unsigned) BITS_PER_WORD)
1733 	{
1734 	  if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing
1735 	      || ! rtx_equal_p (target, xtarget))
1736 	    {
1737 	      rtx_insn *temp = emit_move_insn (target, xtarget);
1738 
1739 	      set_dst_reg_note (temp, REG_EQUAL,
1740 				gen_rtx_fmt_ee (optab_to_code (binoptab),
1741 						int_mode, copy_rtx (xop0),
1742 						copy_rtx (xop1)),
1743 				target);
1744 	    }
1745 	  else
1746 	    target = xtarget;
1747 
1748 	  return target;
1749 	}
1750 
1751       else
1752 	delete_insns_since (last);
1753     }
1754 
1755   /* Attempt to synthesize double word multiplies using a sequence of word
1756      mode multiplications.  We first attempt to generate a sequence using a
1757      more efficient unsigned widening multiply, and if that fails we then
1758      try using a signed widening multiply.  */
1759 
1760   if (binoptab == smul_optab
1761       && is_int_mode (mode, &int_mode)
1762       && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
1763       && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
1764       && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
1765     {
1766       rtx product = NULL_RTX;
1767       if (convert_optab_handler (umul_widen_optab, int_mode, word_mode)
1768 	  != CODE_FOR_nothing)
1769 	{
1770 	  product = expand_doubleword_mult (int_mode, op0, op1, target,
1771 					    true, methods);
1772 	  if (!product)
1773 	    delete_insns_since (last);
1774 	}
1775 
1776       if (product == NULL_RTX
1777 	  && (convert_optab_handler (smul_widen_optab, int_mode, word_mode)
1778 	      != CODE_FOR_nothing))
1779 	{
1780 	  product = expand_doubleword_mult (int_mode, op0, op1, target,
1781 					    false, methods);
1782 	  if (!product)
1783 	    delete_insns_since (last);
1784 	}
1785 
1786       if (product != NULL_RTX)
1787 	{
1788 	  if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
1789 	    {
1790 	      rtx_insn *move = emit_move_insn (target ? target : product,
1791 					       product);
1792 	      set_dst_reg_note (move,
1793 				REG_EQUAL,
1794 				gen_rtx_fmt_ee (MULT, int_mode,
1795 						copy_rtx (op0),
1796 						copy_rtx (op1)),
1797 				target ? target : product);
1798 	    }
1799 	  return product;
1800 	}
1801     }
1802 
1803   /* It can't be open-coded in this mode.
1804      Use a library call if one is available and caller says that's ok.  */
1805 
1806   libfunc = optab_libfunc (binoptab, mode);
1807   if (libfunc
1808       && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1809     {
1810       rtx_insn *insns;
1811       rtx op1x = op1;
1812       machine_mode op1_mode = mode;
1813       rtx value;
1814 
1815       start_sequence ();
1816 
1817       if (shift_optab_p (binoptab))
1818 	{
1819 	  op1_mode = targetm.libgcc_shift_count_mode ();
1820 	  /* Specify unsigned here,
1821 	     since negative shift counts are meaningless.  */
1822 	  op1x = convert_to_mode (op1_mode, op1, 1);
1823 	}
1824 
1825       if (GET_MODE (op0) != VOIDmode
1826 	  && GET_MODE (op0) != mode)
1827 	op0 = convert_to_mode (mode, op0, unsignedp);
1828 
1829       /* Pass 1 for NO_QUEUE so we don't lose any increments
1830 	 if the libcall is cse'd or moved.  */
1831       value = emit_library_call_value (libfunc,
1832 				       NULL_RTX, LCT_CONST, mode,
1833 				       op0, mode, op1x, op1_mode);
1834 
1835       insns = get_insns ();
1836       end_sequence ();
1837 
1838       bool trapv = trapv_binoptab_p (binoptab);
1839       target = gen_reg_rtx (mode);
1840       emit_libcall_block_1 (insns, target, value,
1841 			    trapv ? NULL_RTX
1842 			    : gen_rtx_fmt_ee (optab_to_code (binoptab),
1843 					      mode, op0, op1), trapv);
1844 
1845       return target;
1846     }
1847 
1848   delete_insns_since (last);
1849 
1850   /* It can't be done in this mode.  Can we do it in a wider mode?  */
1851 
1852   if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1853 	 || methods == OPTAB_MUST_WIDEN))
1854     {
1855       /* Caller says, don't even try.  */
1856       delete_insns_since (entry_last);
1857       return 0;
1858     }
1859 
1860   /* Compute the value of METHODS to pass to recursive calls.
1861      Don't allow widening to be tried recursively.  */
1862 
1863   methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1864 
1865   /* Look for a wider mode of the same class for which it appears we can do
1866      the operation.  */
1867 
1868   if (CLASS_HAS_WIDER_MODES_P (mclass))
1869     {
1870       /* This code doesn't make sense for conversion optabs, since we
1871 	 wouldn't then want to extend the operands to be the same size
1872 	 as the result.  */
1873       gcc_assert (!convert_optab_p (binoptab));
1874       FOR_EACH_WIDER_MODE (wider_mode, mode)
1875 	{
1876 	  if (optab_handler (binoptab, wider_mode)
1877 	      || (methods == OPTAB_LIB
1878 		  && optab_libfunc (binoptab, wider_mode)))
1879 	    {
1880 	      rtx xop0 = op0, xop1 = op1;
1881 	      int no_extend = 0;
1882 
1883 	      /* For certain integer operations, we need not actually extend
1884 		 the narrow operands, as long as we will truncate
1885 		 the results to the same narrowness.  */
1886 
1887 	      if ((binoptab == ior_optab || binoptab == and_optab
1888 		   || binoptab == xor_optab
1889 		   || binoptab == add_optab || binoptab == sub_optab
1890 		   || binoptab == smul_optab || binoptab == ashl_optab)
1891 		  && mclass == MODE_INT)
1892 		no_extend = 1;
1893 
1894 	      xop0 = widen_operand (xop0, wider_mode, mode,
1895 				    unsignedp, no_extend);
1896 
1897 	      /* The second operand of a shift must always be extended.  */
1898 	      xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1899 				    no_extend && binoptab != ashl_optab);
1900 
1901 	      temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1902 				   unsignedp, methods);
1903 	      if (temp)
1904 		{
1905 		  if (mclass != MODE_INT
1906 		      || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1907 		    {
1908 		      if (target == 0)
1909 			target = gen_reg_rtx (mode);
1910 		      convert_move (target, temp, 0);
1911 		      return target;
1912 		    }
1913 		  else
1914 		    return gen_lowpart (mode, temp);
1915 		}
1916 	      else
1917 		delete_insns_since (last);
1918 	    }
1919 	}
1920     }
1921 
1922   delete_insns_since (entry_last);
1923   return 0;
1924 }
1925 
1926 /* Expand a binary operator which has both signed and unsigned forms.
1927    UOPTAB is the optab for unsigned operations, and SOPTAB is for
1928    signed operations.
1929 
1930    If we widen unsigned operands, we may use a signed wider operation instead
1931    of an unsigned wider operation, since the result would be the same.  */
1932 
1933 rtx
1934 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
1935 		   rtx op0, rtx op1, rtx target, int unsignedp,
1936 		   enum optab_methods methods)
1937 {
1938   rtx temp;
1939   optab direct_optab = unsignedp ? uoptab : soptab;
1940   bool save_enable;
1941 
1942   /* Do it without widening, if possible.  */
1943   temp = expand_binop (mode, direct_optab, op0, op1, target,
1944 		       unsignedp, OPTAB_DIRECT);
1945   if (temp || methods == OPTAB_DIRECT)
1946     return temp;
1947 
1948   /* Try widening to a signed int.  Disable any direct use of any
1949      signed insn in the current mode.  */
1950   save_enable = swap_optab_enable (soptab, mode, false);
1951 
1952   temp = expand_binop (mode, soptab, op0, op1, target,
1953 		       unsignedp, OPTAB_WIDEN);
1954 
1955   /* For unsigned operands, try widening to an unsigned int.  */
1956   if (!temp && unsignedp)
1957     temp = expand_binop (mode, uoptab, op0, op1, target,
1958 			 unsignedp, OPTAB_WIDEN);
1959   if (temp || methods == OPTAB_WIDEN)
1960     goto egress;
1961 
1962   /* Use the right width libcall if that exists.  */
1963   temp = expand_binop (mode, direct_optab, op0, op1, target,
1964 		       unsignedp, OPTAB_LIB);
1965   if (temp || methods == OPTAB_LIB)
1966     goto egress;
1967 
1968   /* Must widen and use a libcall, use either signed or unsigned.  */
1969   temp = expand_binop (mode, soptab, op0, op1, target,
1970 		       unsignedp, methods);
1971   if (!temp && unsignedp)
1972     temp = expand_binop (mode, uoptab, op0, op1, target,
1973 			 unsignedp, methods);
1974 
1975  egress:
1976   /* Undo the fiddling above.  */
1977   if (save_enable)
1978     swap_optab_enable (soptab, mode, true);
1979   return temp;
1980 }
1981 
1982 /* Generate code to perform an operation specified by UNOPPTAB
1983    on operand OP0, with two results to TARG0 and TARG1.
1984    We assume that the order of the operands for the instruction
1985    is TARG0, TARG1, OP0.
1986 
1987    Either TARG0 or TARG1 may be zero, but what that means is that
1988    the result is not actually wanted.  We will generate it into
1989    a dummy pseudo-reg and discard it.  They may not both be zero.
1990 
1991    Returns 1 if this operation can be performed; 0 if not.  */
1992 
1993 int
1994 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
1995 		    int unsignedp)
1996 {
1997   machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1998   enum mode_class mclass;
1999   machine_mode wider_mode;
2000   rtx_insn *entry_last = get_last_insn ();
2001   rtx_insn *last;
2002 
2003   mclass = GET_MODE_CLASS (mode);
2004 
2005   if (!targ0)
2006     targ0 = gen_reg_rtx (mode);
2007   if (!targ1)
2008     targ1 = gen_reg_rtx (mode);
2009 
2010   /* Record where to go back to if we fail.  */
2011   last = get_last_insn ();
2012 
2013   if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2014     {
2015       struct expand_operand ops[3];
2016       enum insn_code icode = optab_handler (unoptab, mode);
2017 
2018       create_fixed_operand (&ops[0], targ0);
2019       create_fixed_operand (&ops[1], targ1);
2020       create_convert_operand_from (&ops[2], op0, mode, unsignedp);
2021       if (maybe_expand_insn (icode, 3, ops))
2022 	return 1;
2023     }
2024 
2025   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2026 
2027   if (CLASS_HAS_WIDER_MODES_P (mclass))
2028     {
2029       FOR_EACH_WIDER_MODE (wider_mode, mode)
2030 	{
2031 	  if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2032 	    {
2033 	      rtx t0 = gen_reg_rtx (wider_mode);
2034 	      rtx t1 = gen_reg_rtx (wider_mode);
2035 	      rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2036 
2037 	      if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2038 		{
2039 		  convert_move (targ0, t0, unsignedp);
2040 		  convert_move (targ1, t1, unsignedp);
2041 		  return 1;
2042 		}
2043 	      else
2044 		delete_insns_since (last);
2045 	    }
2046 	}
2047     }
2048 
2049   delete_insns_since (entry_last);
2050   return 0;
2051 }
2052 
2053 /* Generate code to perform an operation specified by BINOPTAB
2054    on operands OP0 and OP1, with two results to TARG1 and TARG2.
2055    We assume that the order of the operands for the instruction
2056    is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2057    [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2058 
2059    Either TARG0 or TARG1 may be zero, but what that means is that
2060    the result is not actually wanted.  We will generate it into
2061    a dummy pseudo-reg and discard it.  They may not both be zero.
2062 
2063    Returns 1 if this operation can be performed; 0 if not.  */
2064 
2065 int
2066 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2067 		     int unsignedp)
2068 {
2069   machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2070   enum mode_class mclass;
2071   machine_mode wider_mode;
2072   rtx_insn *entry_last = get_last_insn ();
2073   rtx_insn *last;
2074 
2075   mclass = GET_MODE_CLASS (mode);
2076 
2077   if (!targ0)
2078     targ0 = gen_reg_rtx (mode);
2079   if (!targ1)
2080     targ1 = gen_reg_rtx (mode);
2081 
2082   /* Record where to go back to if we fail.  */
2083   last = get_last_insn ();
2084 
2085   if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2086     {
2087       struct expand_operand ops[4];
2088       enum insn_code icode = optab_handler (binoptab, mode);
2089       machine_mode mode0 = insn_data[icode].operand[1].mode;
2090       machine_mode mode1 = insn_data[icode].operand[2].mode;
2091       rtx xop0 = op0, xop1 = op1;
2092 
2093       /* If we are optimizing, force expensive constants into a register.  */
2094       xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2095       xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2096 
2097       create_fixed_operand (&ops[0], targ0);
2098       create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2099       create_convert_operand_from (&ops[2], op1, mode, unsignedp);
2100       create_fixed_operand (&ops[3], targ1);
2101       if (maybe_expand_insn (icode, 4, ops))
2102 	return 1;
2103       delete_insns_since (last);
2104     }
2105 
2106   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2107 
2108   if (CLASS_HAS_WIDER_MODES_P (mclass))
2109     {
2110       FOR_EACH_WIDER_MODE (wider_mode, mode)
2111 	{
2112 	  if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2113 	    {
2114 	      rtx t0 = gen_reg_rtx (wider_mode);
2115 	      rtx t1 = gen_reg_rtx (wider_mode);
2116 	      rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2117 	      rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2118 
2119 	      if (expand_twoval_binop (binoptab, cop0, cop1,
2120 				       t0, t1, unsignedp))
2121 		{
2122 		  convert_move (targ0, t0, unsignedp);
2123 		  convert_move (targ1, t1, unsignedp);
2124 		  return 1;
2125 		}
2126 	      else
2127 		delete_insns_since (last);
2128 	    }
2129 	}
2130     }
2131 
2132   delete_insns_since (entry_last);
2133   return 0;
2134 }
2135 
2136 /* Expand the two-valued library call indicated by BINOPTAB, but
2137    preserve only one of the values.  If TARG0 is non-NULL, the first
2138    value is placed into TARG0; otherwise the second value is placed
2139    into TARG1.  Exactly one of TARG0 and TARG1 must be non-NULL.  The
2140    value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2141    This routine assumes that the value returned by the library call is
2142    as if the return value was of an integral mode twice as wide as the
2143    mode of OP0.  Returns 1 if the call was successful.  */
2144 
2145 bool
2146 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2147 			     rtx targ0, rtx targ1, enum rtx_code code)
2148 {
2149   machine_mode mode;
2150   machine_mode libval_mode;
2151   rtx libval;
2152   rtx_insn *insns;
2153   rtx libfunc;
2154 
2155   /* Exactly one of TARG0 or TARG1 should be non-NULL.  */
2156   gcc_assert (!targ0 != !targ1);
2157 
2158   mode = GET_MODE (op0);
2159   libfunc = optab_libfunc (binoptab, mode);
2160   if (!libfunc)
2161     return false;
2162 
2163   /* The value returned by the library function will have twice as
2164      many bits as the nominal MODE.  */
2165   libval_mode = smallest_int_mode_for_size (2 * GET_MODE_BITSIZE (mode));
2166   start_sequence ();
2167   libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2168 				    libval_mode,
2169 				    op0, mode,
2170 				    op1, mode);
2171   /* Get the part of VAL containing the value that we want.  */
2172   libval = simplify_gen_subreg (mode, libval, libval_mode,
2173 				targ0 ? 0 : GET_MODE_SIZE (mode));
2174   insns = get_insns ();
2175   end_sequence ();
2176   /* Move the into the desired location.  */
2177   emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2178 		      gen_rtx_fmt_ee (code, mode, op0, op1));
2179 
2180   return true;
2181 }
2182 
2183 
2184 /* Wrapper around expand_unop which takes an rtx code to specify
2185    the operation to perform, not an optab pointer.  All other
2186    arguments are the same.  */
2187 rtx
2188 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
2189 		    rtx target, int unsignedp)
2190 {
2191   optab unop = code_to_optab (code);
2192   gcc_assert (unop);
2193 
2194   return expand_unop (mode, unop, op0, target, unsignedp);
2195 }
2196 
2197 /* Try calculating
2198 	(clz:narrow x)
2199    as
2200 	(clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2201 
2202    A similar operation can be used for clrsb.  UNOPTAB says which operation
2203    we are trying to expand.  */
2204 static rtx
2205 widen_leading (scalar_int_mode mode, rtx op0, rtx target, optab unoptab)
2206 {
2207   opt_scalar_int_mode wider_mode_iter;
2208   FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2209     {
2210       scalar_int_mode wider_mode = wider_mode_iter.require ();
2211       if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2212 	{
2213 	  rtx xop0, temp;
2214 	  rtx_insn *last;
2215 
2216 	  last = get_last_insn ();
2217 
2218 	  if (target == 0)
2219 	    target = gen_reg_rtx (mode);
2220 	  xop0 = widen_operand (op0, wider_mode, mode,
2221 				unoptab != clrsb_optab, false);
2222 	  temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2223 			      unoptab != clrsb_optab);
2224 	  if (temp != 0)
2225 	    temp = expand_binop
2226 	      (wider_mode, sub_optab, temp,
2227 	       gen_int_mode (GET_MODE_PRECISION (wider_mode)
2228 			     - GET_MODE_PRECISION (mode),
2229 			     wider_mode),
2230 	       target, true, OPTAB_DIRECT);
2231 	  if (temp == 0)
2232 	    delete_insns_since (last);
2233 
2234 	  return temp;
2235 	}
2236     }
2237   return 0;
2238 }
2239 
2240 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2241    quantities, choosing which based on whether the high word is nonzero.  */
2242 static rtx
2243 expand_doubleword_clz (scalar_int_mode mode, rtx op0, rtx target)
2244 {
2245   rtx xop0 = force_reg (mode, op0);
2246   rtx subhi = gen_highpart (word_mode, xop0);
2247   rtx sublo = gen_lowpart (word_mode, xop0);
2248   rtx_code_label *hi0_label = gen_label_rtx ();
2249   rtx_code_label *after_label = gen_label_rtx ();
2250   rtx_insn *seq;
2251   rtx temp, result;
2252 
2253   /* If we were not given a target, use a word_mode register, not a
2254      'mode' register.  The result will fit, and nobody is expecting
2255      anything bigger (the return type of __builtin_clz* is int).  */
2256   if (!target)
2257     target = gen_reg_rtx (word_mode);
2258 
2259   /* In any case, write to a word_mode scratch in both branches of the
2260      conditional, so we can ensure there is a single move insn setting
2261      'target' to tag a REG_EQUAL note on.  */
2262   result = gen_reg_rtx (word_mode);
2263 
2264   start_sequence ();
2265 
2266   /* If the high word is not equal to zero,
2267      then clz of the full value is clz of the high word.  */
2268   emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2269 			   word_mode, true, hi0_label);
2270 
2271   temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2272   if (!temp)
2273     goto fail;
2274 
2275   if (temp != result)
2276     convert_move (result, temp, true);
2277 
2278   emit_jump_insn (targetm.gen_jump (after_label));
2279   emit_barrier ();
2280 
2281   /* Else clz of the full value is clz of the low word plus the number
2282      of bits in the high word.  */
2283   emit_label (hi0_label);
2284 
2285   temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2286   if (!temp)
2287     goto fail;
2288   temp = expand_binop (word_mode, add_optab, temp,
2289 		       gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode),
2290 		       result, true, OPTAB_DIRECT);
2291   if (!temp)
2292     goto fail;
2293   if (temp != result)
2294     convert_move (result, temp, true);
2295 
2296   emit_label (after_label);
2297   convert_move (target, result, true);
2298 
2299   seq = get_insns ();
2300   end_sequence ();
2301 
2302   add_equal_note (seq, target, CLZ, xop0, NULL_RTX, mode);
2303   emit_insn (seq);
2304   return target;
2305 
2306  fail:
2307   end_sequence ();
2308   return 0;
2309 }
2310 
2311 /* Try calculating popcount of a double-word quantity as two popcount's of
2312    word-sized quantities and summing up the results.  */
2313 static rtx
2314 expand_doubleword_popcount (scalar_int_mode mode, rtx op0, rtx target)
2315 {
2316   rtx t0, t1, t;
2317   rtx_insn *seq;
2318 
2319   start_sequence ();
2320 
2321   t0 = expand_unop_direct (word_mode, popcount_optab,
2322 			   operand_subword_force (op0, 0, mode), NULL_RTX,
2323 			   true);
2324   t1 = expand_unop_direct (word_mode, popcount_optab,
2325 			   operand_subword_force (op0, 1, mode), NULL_RTX,
2326 			   true);
2327   if (!t0 || !t1)
2328     {
2329       end_sequence ();
2330       return NULL_RTX;
2331     }
2332 
2333   /* If we were not given a target, use a word_mode register, not a
2334      'mode' register.  The result will fit, and nobody is expecting
2335      anything bigger (the return type of __builtin_popcount* is int).  */
2336   if (!target)
2337     target = gen_reg_rtx (word_mode);
2338 
2339   t = expand_binop (word_mode, add_optab, t0, t1, target, 0, OPTAB_DIRECT);
2340 
2341   seq = get_insns ();
2342   end_sequence ();
2343 
2344   add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode);
2345   emit_insn (seq);
2346   return t;
2347 }
2348 
2349 /* Try calculating
2350 	(parity:wide x)
2351    as
2352 	(parity:narrow (low (x) ^ high (x))) */
2353 static rtx
2354 expand_doubleword_parity (scalar_int_mode mode, rtx op0, rtx target)
2355 {
2356   rtx t = expand_binop (word_mode, xor_optab,
2357 			operand_subword_force (op0, 0, mode),
2358 			operand_subword_force (op0, 1, mode),
2359 			NULL_RTX, 0, OPTAB_DIRECT);
2360   return expand_unop (word_mode, parity_optab, t, target, true);
2361 }
2362 
2363 /* Try calculating
2364 	(bswap:narrow x)
2365    as
2366 	(lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))).  */
2367 static rtx
2368 widen_bswap (scalar_int_mode mode, rtx op0, rtx target)
2369 {
2370   rtx x;
2371   rtx_insn *last;
2372   opt_scalar_int_mode wider_mode_iter;
2373 
2374   FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2375     if (optab_handler (bswap_optab, wider_mode_iter.require ())
2376 	!= CODE_FOR_nothing)
2377       break;
2378 
2379   if (!wider_mode_iter.exists ())
2380     return NULL_RTX;
2381 
2382   scalar_int_mode wider_mode = wider_mode_iter.require ();
2383   last = get_last_insn ();
2384 
2385   x = widen_operand (op0, wider_mode, mode, true, true);
2386   x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2387 
2388   gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2389 	      && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2390   if (x != 0)
2391     x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2392 		      GET_MODE_BITSIZE (wider_mode)
2393 		      - GET_MODE_BITSIZE (mode),
2394 		      NULL_RTX, true);
2395 
2396   if (x != 0)
2397     {
2398       if (target == 0)
2399 	target = gen_reg_rtx (mode);
2400       emit_move_insn (target, gen_lowpart (mode, x));
2401     }
2402   else
2403     delete_insns_since (last);
2404 
2405   return target;
2406 }
2407 
2408 /* Try calculating bswap as two bswaps of two word-sized operands.  */
2409 
2410 static rtx
2411 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2412 {
2413   rtx t0, t1;
2414 
2415   t1 = expand_unop (word_mode, bswap_optab,
2416 		    operand_subword_force (op, 0, mode), NULL_RTX, true);
2417   t0 = expand_unop (word_mode, bswap_optab,
2418 		    operand_subword_force (op, 1, mode), NULL_RTX, true);
2419 
2420   if (target == 0 || !valid_multiword_target_p (target))
2421     target = gen_reg_rtx (mode);
2422   if (REG_P (target))
2423     emit_clobber (target);
2424   emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2425   emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2426 
2427   return target;
2428 }
2429 
2430 /* Try calculating (parity x) as (and (popcount x) 1), where
2431    popcount can also be done in a wider mode.  */
2432 static rtx
2433 expand_parity (scalar_int_mode mode, rtx op0, rtx target)
2434 {
2435   enum mode_class mclass = GET_MODE_CLASS (mode);
2436   opt_scalar_int_mode wider_mode_iter;
2437   FOR_EACH_MODE_FROM (wider_mode_iter, mode)
2438     {
2439       scalar_int_mode wider_mode = wider_mode_iter.require ();
2440       if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2441 	{
2442 	  rtx xop0, temp;
2443 	  rtx_insn *last;
2444 
2445 	  last = get_last_insn ();
2446 
2447 	  if (target == 0 || GET_MODE (target) != wider_mode)
2448 	    target = gen_reg_rtx (wider_mode);
2449 
2450 	  xop0 = widen_operand (op0, wider_mode, mode, true, false);
2451 	  temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2452 			      true);
2453 	  if (temp != 0)
2454 	    temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2455 				 target, true, OPTAB_DIRECT);
2456 
2457 	  if (temp)
2458 	    {
2459 	      if (mclass != MODE_INT
2460 		  || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2461 		return convert_to_mode (mode, temp, 0);
2462 	      else
2463 		return gen_lowpart (mode, temp);
2464 	    }
2465 	  else
2466 	    delete_insns_since (last);
2467 	}
2468     }
2469   return 0;
2470 }
2471 
2472 /* Try calculating ctz(x) as K - clz(x & -x) ,
2473    where K is GET_MODE_PRECISION(mode) - 1.
2474 
2475    Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2476    don't have to worry about what the hardware does in that case.  (If
2477    the clz instruction produces the usual value at 0, which is K, the
2478    result of this code sequence will be -1; expand_ffs, below, relies
2479    on this.  It might be nice to have it be K instead, for consistency
2480    with the (very few) processors that provide a ctz with a defined
2481    value, but that would take one more instruction, and it would be
2482    less convenient for expand_ffs anyway.  */
2483 
2484 static rtx
2485 expand_ctz (scalar_int_mode mode, rtx op0, rtx target)
2486 {
2487   rtx_insn *seq;
2488   rtx temp;
2489 
2490   if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2491     return 0;
2492 
2493   start_sequence ();
2494 
2495   temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2496   if (temp)
2497     temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2498 			 true, OPTAB_DIRECT);
2499   if (temp)
2500     temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2501   if (temp)
2502     temp = expand_binop (mode, sub_optab,
2503 			 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2504 			 temp, target,
2505 			 true, OPTAB_DIRECT);
2506   if (temp == 0)
2507     {
2508       end_sequence ();
2509       return 0;
2510     }
2511 
2512   seq = get_insns ();
2513   end_sequence ();
2514 
2515   add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode);
2516   emit_insn (seq);
2517   return temp;
2518 }
2519 
2520 
2521 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2522    else with the sequence used by expand_clz.
2523 
2524    The ffs builtin promises to return zero for a zero value and ctz/clz
2525    may have an undefined value in that case.  If they do not give us a
2526    convenient value, we have to generate a test and branch.  */
2527 static rtx
2528 expand_ffs (scalar_int_mode mode, rtx op0, rtx target)
2529 {
2530   HOST_WIDE_INT val = 0;
2531   bool defined_at_zero = false;
2532   rtx temp;
2533   rtx_insn *seq;
2534 
2535   if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2536     {
2537       start_sequence ();
2538 
2539       temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2540       if (!temp)
2541 	goto fail;
2542 
2543       defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2544     }
2545   else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2546     {
2547       start_sequence ();
2548       temp = expand_ctz (mode, op0, 0);
2549       if (!temp)
2550 	goto fail;
2551 
2552       if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2553 	{
2554 	  defined_at_zero = true;
2555 	  val = (GET_MODE_PRECISION (mode) - 1) - val;
2556 	}
2557     }
2558   else
2559     return 0;
2560 
2561   if (defined_at_zero && val == -1)
2562     /* No correction needed at zero.  */;
2563   else
2564     {
2565       /* We don't try to do anything clever with the situation found
2566 	 on some processors (eg Alpha) where ctz(0:mode) ==
2567 	 bitsize(mode).  If someone can think of a way to send N to -1
2568 	 and leave alone all values in the range 0..N-1 (where N is a
2569 	 power of two), cheaper than this test-and-branch, please add it.
2570 
2571 	 The test-and-branch is done after the operation itself, in case
2572 	 the operation sets condition codes that can be recycled for this.
2573 	 (This is true on i386, for instance.)  */
2574 
2575       rtx_code_label *nonzero_label = gen_label_rtx ();
2576       emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2577 			       mode, true, nonzero_label);
2578 
2579       convert_move (temp, GEN_INT (-1), false);
2580       emit_label (nonzero_label);
2581     }
2582 
2583   /* temp now has a value in the range -1..bitsize-1.  ffs is supposed
2584      to produce a value in the range 0..bitsize.  */
2585   temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
2586 		       target, false, OPTAB_DIRECT);
2587   if (!temp)
2588     goto fail;
2589 
2590   seq = get_insns ();
2591   end_sequence ();
2592 
2593   add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode);
2594   emit_insn (seq);
2595   return temp;
2596 
2597  fail:
2598   end_sequence ();
2599   return 0;
2600 }
2601 
2602 /* Extract the OMODE lowpart from VAL, which has IMODE.  Under certain
2603    conditions, VAL may already be a SUBREG against which we cannot generate
2604    a further SUBREG.  In this case, we expect forcing the value into a
2605    register will work around the situation.  */
2606 
2607 static rtx
2608 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
2609 			   machine_mode imode)
2610 {
2611   rtx ret;
2612   ret = lowpart_subreg (omode, val, imode);
2613   if (ret == NULL)
2614     {
2615       val = force_reg (imode, val);
2616       ret = lowpart_subreg (omode, val, imode);
2617       gcc_assert (ret != NULL);
2618     }
2619   return ret;
2620 }
2621 
2622 /* Expand a floating point absolute value or negation operation via a
2623    logical operation on the sign bit.  */
2624 
2625 static rtx
2626 expand_absneg_bit (enum rtx_code code, scalar_float_mode mode,
2627 		   rtx op0, rtx target)
2628 {
2629   const struct real_format *fmt;
2630   int bitpos, word, nwords, i;
2631   scalar_int_mode imode;
2632   rtx temp;
2633   rtx_insn *insns;
2634 
2635   /* The format has to have a simple sign bit.  */
2636   fmt = REAL_MODE_FORMAT (mode);
2637   if (fmt == NULL)
2638     return NULL_RTX;
2639 
2640   bitpos = fmt->signbit_rw;
2641   if (bitpos < 0)
2642     return NULL_RTX;
2643 
2644   /* Don't create negative zeros if the format doesn't support them.  */
2645   if (code == NEG && !fmt->has_signed_zero)
2646     return NULL_RTX;
2647 
2648   if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2649     {
2650       if (!int_mode_for_mode (mode).exists (&imode))
2651 	return NULL_RTX;
2652       word = 0;
2653       nwords = 1;
2654     }
2655   else
2656     {
2657       imode = word_mode;
2658 
2659       if (FLOAT_WORDS_BIG_ENDIAN)
2660 	word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2661       else
2662 	word = bitpos / BITS_PER_WORD;
2663       bitpos = bitpos % BITS_PER_WORD;
2664       nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2665     }
2666 
2667   wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
2668   if (code == ABS)
2669     mask = ~mask;
2670 
2671   if (target == 0
2672       || target == op0
2673       || (nwords > 1 && !valid_multiword_target_p (target)))
2674     target = gen_reg_rtx (mode);
2675 
2676   if (nwords > 1)
2677     {
2678       start_sequence ();
2679 
2680       for (i = 0; i < nwords; ++i)
2681 	{
2682 	  rtx targ_piece = operand_subword (target, i, 1, mode);
2683 	  rtx op0_piece = operand_subword_force (op0, i, mode);
2684 
2685 	  if (i == word)
2686 	    {
2687 	      temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2688 				   op0_piece,
2689 				   immed_wide_int_const (mask, imode),
2690 				   targ_piece, 1, OPTAB_LIB_WIDEN);
2691 	      if (temp != targ_piece)
2692 		emit_move_insn (targ_piece, temp);
2693 	    }
2694 	  else
2695 	    emit_move_insn (targ_piece, op0_piece);
2696 	}
2697 
2698       insns = get_insns ();
2699       end_sequence ();
2700 
2701       emit_insn (insns);
2702     }
2703   else
2704     {
2705       temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2706 			   gen_lowpart (imode, op0),
2707 			   immed_wide_int_const (mask, imode),
2708 		           gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2709       target = lowpart_subreg_maybe_copy (mode, temp, imode);
2710 
2711       set_dst_reg_note (get_last_insn (), REG_EQUAL,
2712 			gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
2713 			target);
2714     }
2715 
2716   return target;
2717 }
2718 
2719 /* As expand_unop, but will fail rather than attempt the operation in a
2720    different mode or with a libcall.  */
2721 static rtx
2722 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
2723 		    int unsignedp)
2724 {
2725   if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2726     {
2727       struct expand_operand ops[2];
2728       enum insn_code icode = optab_handler (unoptab, mode);
2729       rtx_insn *last = get_last_insn ();
2730       rtx_insn *pat;
2731 
2732       create_output_operand (&ops[0], target, mode);
2733       create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2734       pat = maybe_gen_insn (icode, 2, ops);
2735       if (pat)
2736 	{
2737 	  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2738 	      && ! add_equal_note (pat, ops[0].value,
2739 				   optab_to_code (unoptab),
2740 				   ops[1].value, NULL_RTX, mode))
2741 	    {
2742 	      delete_insns_since (last);
2743 	      return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2744 	    }
2745 
2746 	  emit_insn (pat);
2747 
2748 	  return ops[0].value;
2749 	}
2750     }
2751   return 0;
2752 }
2753 
2754 /* Generate code to perform an operation specified by UNOPTAB
2755    on operand OP0, with result having machine-mode MODE.
2756 
2757    UNSIGNEDP is for the case where we have to widen the operands
2758    to perform the operation.  It says to use zero-extension.
2759 
2760    If TARGET is nonzero, the value
2761    is generated there, if it is convenient to do so.
2762    In all cases an rtx is returned for the locus of the value;
2763    this may or may not be TARGET.  */
2764 
2765 rtx
2766 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
2767 	     int unsignedp)
2768 {
2769   enum mode_class mclass = GET_MODE_CLASS (mode);
2770   machine_mode wider_mode;
2771   scalar_int_mode int_mode;
2772   scalar_float_mode float_mode;
2773   rtx temp;
2774   rtx libfunc;
2775 
2776   temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
2777   if (temp)
2778     return temp;
2779 
2780   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
2781 
2782   /* Widening (or narrowing) clz needs special treatment.  */
2783   if (unoptab == clz_optab)
2784     {
2785       if (is_a <scalar_int_mode> (mode, &int_mode))
2786 	{
2787 	  temp = widen_leading (int_mode, op0, target, unoptab);
2788 	  if (temp)
2789 	    return temp;
2790 
2791 	  if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2792 	      && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2793 	    {
2794 	      temp = expand_doubleword_clz (int_mode, op0, target);
2795 	      if (temp)
2796 		return temp;
2797 	    }
2798 	}
2799 
2800       goto try_libcall;
2801     }
2802 
2803   if (unoptab == clrsb_optab)
2804     {
2805       if (is_a <scalar_int_mode> (mode, &int_mode))
2806 	{
2807 	  temp = widen_leading (int_mode, op0, target, unoptab);
2808 	  if (temp)
2809 	    return temp;
2810 	}
2811       goto try_libcall;
2812     }
2813 
2814   if (unoptab == popcount_optab
2815       && is_a <scalar_int_mode> (mode, &int_mode)
2816       && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2817       && optab_handler (unoptab, word_mode) != CODE_FOR_nothing
2818       && optimize_insn_for_speed_p ())
2819     {
2820       temp = expand_doubleword_popcount (int_mode, op0, target);
2821       if (temp)
2822 	return temp;
2823     }
2824 
2825   if (unoptab == parity_optab
2826       && is_a <scalar_int_mode> (mode, &int_mode)
2827       && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2828       && (optab_handler (unoptab, word_mode) != CODE_FOR_nothing
2829 	  || optab_handler (popcount_optab, word_mode) != CODE_FOR_nothing)
2830       && optimize_insn_for_speed_p ())
2831     {
2832       temp = expand_doubleword_parity (int_mode, op0, target);
2833       if (temp)
2834 	return temp;
2835     }
2836 
2837   /* Widening (or narrowing) bswap needs special treatment.  */
2838   if (unoptab == bswap_optab)
2839     {
2840       /* HImode is special because in this mode BSWAP is equivalent to ROTATE
2841 	 or ROTATERT.  First try these directly; if this fails, then try the
2842 	 obvious pair of shifts with allowed widening, as this will probably
2843 	 be always more efficient than the other fallback methods.  */
2844       if (mode == HImode)
2845 	{
2846 	  rtx_insn *last;
2847 	  rtx temp1, temp2;
2848 
2849 	  if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
2850 	    {
2851 	      temp = expand_binop (mode, rotl_optab, op0,
2852 				   gen_int_shift_amount (mode, 8),
2853 				   target, unsignedp, OPTAB_DIRECT);
2854 	      if (temp)
2855 		return temp;
2856 	     }
2857 
2858 	  if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
2859 	    {
2860 	      temp = expand_binop (mode, rotr_optab, op0,
2861 				   gen_int_shift_amount (mode, 8),
2862 				   target, unsignedp, OPTAB_DIRECT);
2863 	      if (temp)
2864 		return temp;
2865 	    }
2866 
2867 	  last = get_last_insn ();
2868 
2869 	  temp1 = expand_binop (mode, ashl_optab, op0,
2870 				gen_int_shift_amount (mode, 8), NULL_RTX,
2871 			        unsignedp, OPTAB_WIDEN);
2872 	  temp2 = expand_binop (mode, lshr_optab, op0,
2873 				gen_int_shift_amount (mode, 8), NULL_RTX,
2874 			        unsignedp, OPTAB_WIDEN);
2875 	  if (temp1 && temp2)
2876 	    {
2877 	      temp = expand_binop (mode, ior_optab, temp1, temp2, target,
2878 				   unsignedp, OPTAB_WIDEN);
2879 	      if (temp)
2880 		return temp;
2881 	    }
2882 
2883 	  delete_insns_since (last);
2884 	}
2885 
2886       if (is_a <scalar_int_mode> (mode, &int_mode))
2887 	{
2888 	  temp = widen_bswap (int_mode, op0, target);
2889 	  if (temp)
2890 	    return temp;
2891 
2892 	  if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2893 	      && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2894 	    {
2895 	      temp = expand_doubleword_bswap (mode, op0, target);
2896 	      if (temp)
2897 		return temp;
2898 	    }
2899 	}
2900 
2901       goto try_libcall;
2902     }
2903 
2904   if (CLASS_HAS_WIDER_MODES_P (mclass))
2905     FOR_EACH_WIDER_MODE (wider_mode, mode)
2906       {
2907 	if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2908 	  {
2909 	    rtx xop0 = op0;
2910 	    rtx_insn *last = get_last_insn ();
2911 
2912 	    /* For certain operations, we need not actually extend
2913 	       the narrow operand, as long as we will truncate the
2914 	       results to the same narrowness.  */
2915 
2916 	    xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2917 				  (unoptab == neg_optab
2918 				   || unoptab == one_cmpl_optab)
2919 				  && mclass == MODE_INT);
2920 
2921 	    temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2922 				unsignedp);
2923 
2924 	    if (temp)
2925 	      {
2926 		if (mclass != MODE_INT
2927 		    || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2928 		  {
2929 		    if (target == 0)
2930 		      target = gen_reg_rtx (mode);
2931 		    convert_move (target, temp, 0);
2932 		    return target;
2933 		  }
2934 		else
2935 		  return gen_lowpart (mode, temp);
2936 	      }
2937 	    else
2938 	      delete_insns_since (last);
2939 	  }
2940       }
2941 
2942   /* These can be done a word at a time.  */
2943   if (unoptab == one_cmpl_optab
2944       && is_int_mode (mode, &int_mode)
2945       && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
2946       && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2947     {
2948       int i;
2949       rtx_insn *insns;
2950 
2951       if (target == 0 || target == op0 || !valid_multiword_target_p (target))
2952 	target = gen_reg_rtx (int_mode);
2953 
2954       start_sequence ();
2955 
2956       /* Do the actual arithmetic.  */
2957       for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
2958 	{
2959 	  rtx target_piece = operand_subword (target, i, 1, int_mode);
2960 	  rtx x = expand_unop (word_mode, unoptab,
2961 			       operand_subword_force (op0, i, int_mode),
2962 			       target_piece, unsignedp);
2963 
2964 	  if (target_piece != x)
2965 	    emit_move_insn (target_piece, x);
2966 	}
2967 
2968       insns = get_insns ();
2969       end_sequence ();
2970 
2971       emit_insn (insns);
2972       return target;
2973     }
2974 
2975   if (optab_to_code (unoptab) == NEG)
2976     {
2977       /* Try negating floating point values by flipping the sign bit.  */
2978       if (is_a <scalar_float_mode> (mode, &float_mode))
2979 	{
2980 	  temp = expand_absneg_bit (NEG, float_mode, op0, target);
2981 	  if (temp)
2982 	    return temp;
2983 	}
2984 
2985       /* If there is no negation pattern, and we have no negative zero,
2986 	 try subtracting from zero.  */
2987       if (!HONOR_SIGNED_ZEROS (mode))
2988 	{
2989 	  temp = expand_binop (mode, (unoptab == negv_optab
2990 				      ? subv_optab : sub_optab),
2991 			       CONST0_RTX (mode), op0, target,
2992 			       unsignedp, OPTAB_DIRECT);
2993 	  if (temp)
2994 	    return temp;
2995 	}
2996     }
2997 
2998   /* Try calculating parity (x) as popcount (x) % 2.  */
2999   if (unoptab == parity_optab && is_a <scalar_int_mode> (mode, &int_mode))
3000     {
3001       temp = expand_parity (int_mode, op0, target);
3002       if (temp)
3003 	return temp;
3004     }
3005 
3006   /* Try implementing ffs (x) in terms of clz (x).  */
3007   if (unoptab == ffs_optab && is_a <scalar_int_mode> (mode, &int_mode))
3008     {
3009       temp = expand_ffs (int_mode, op0, target);
3010       if (temp)
3011 	return temp;
3012     }
3013 
3014   /* Try implementing ctz (x) in terms of clz (x).  */
3015   if (unoptab == ctz_optab && is_a <scalar_int_mode> (mode, &int_mode))
3016     {
3017       temp = expand_ctz (int_mode, op0, target);
3018       if (temp)
3019 	return temp;
3020     }
3021 
3022  try_libcall:
3023   /* Now try a library call in this mode.  */
3024   libfunc = optab_libfunc (unoptab, mode);
3025   if (libfunc)
3026     {
3027       rtx_insn *insns;
3028       rtx value;
3029       rtx eq_value;
3030       machine_mode outmode = mode;
3031 
3032       /* All of these functions return small values.  Thus we choose to
3033 	 have them return something that isn't a double-word.  */
3034       if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3035 	  || unoptab == clrsb_optab || unoptab == popcount_optab
3036 	  || unoptab == parity_optab)
3037 	outmode
3038 	  = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
3039 					  optab_libfunc (unoptab, mode)));
3040 
3041       start_sequence ();
3042 
3043       /* Pass 1 for NO_QUEUE so we don't lose any increments
3044 	 if the libcall is cse'd or moved.  */
3045       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
3046 				       op0, mode);
3047       insns = get_insns ();
3048       end_sequence ();
3049 
3050       target = gen_reg_rtx (outmode);
3051       bool trapv = trapv_unoptab_p (unoptab);
3052       if (trapv)
3053 	eq_value = NULL_RTX;
3054       else
3055 	{
3056 	  eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
3057 	  if (GET_MODE_UNIT_SIZE (outmode) < GET_MODE_UNIT_SIZE (mode))
3058 	    eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
3059 	  else if (GET_MODE_UNIT_SIZE (outmode) > GET_MODE_UNIT_SIZE (mode))
3060 	    eq_value = simplify_gen_unary (ZERO_EXTEND,
3061 					   outmode, eq_value, mode);
3062 	}
3063       emit_libcall_block_1 (insns, target, value, eq_value, trapv);
3064 
3065       return target;
3066     }
3067 
3068   /* It can't be done in this mode.  Can we do it in a wider mode?  */
3069 
3070   if (CLASS_HAS_WIDER_MODES_P (mclass))
3071     {
3072       FOR_EACH_WIDER_MODE (wider_mode, mode)
3073 	{
3074 	  if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
3075 	      || optab_libfunc (unoptab, wider_mode))
3076 	    {
3077 	      rtx xop0 = op0;
3078 	      rtx_insn *last = get_last_insn ();
3079 
3080 	      /* For certain operations, we need not actually extend
3081 		 the narrow operand, as long as we will truncate the
3082 		 results to the same narrowness.  */
3083 	      xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3084 				    (unoptab == neg_optab
3085 				     || unoptab == one_cmpl_optab
3086 				     || unoptab == bswap_optab)
3087 				    && mclass == MODE_INT);
3088 
3089 	      temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3090 				  unsignedp);
3091 
3092 	      /* If we are generating clz using wider mode, adjust the
3093 		 result.  Similarly for clrsb.  */
3094 	      if ((unoptab == clz_optab || unoptab == clrsb_optab)
3095 		  && temp != 0)
3096 		{
3097 		  scalar_int_mode wider_int_mode
3098 		    = as_a <scalar_int_mode> (wider_mode);
3099 		  int_mode = as_a <scalar_int_mode> (mode);
3100 		  temp = expand_binop
3101 		    (wider_mode, sub_optab, temp,
3102 		     gen_int_mode (GET_MODE_PRECISION (wider_int_mode)
3103 				   - GET_MODE_PRECISION (int_mode),
3104 				   wider_int_mode),
3105 		     target, true, OPTAB_DIRECT);
3106 		}
3107 
3108 	      /* Likewise for bswap.  */
3109 	      if (unoptab == bswap_optab && temp != 0)
3110 		{
3111 		  scalar_int_mode wider_int_mode
3112 		    = as_a <scalar_int_mode> (wider_mode);
3113 		  int_mode = as_a <scalar_int_mode> (mode);
3114 		  gcc_assert (GET_MODE_PRECISION (wider_int_mode)
3115 			      == GET_MODE_BITSIZE (wider_int_mode)
3116 			      && GET_MODE_PRECISION (int_mode)
3117 				 == GET_MODE_BITSIZE (int_mode));
3118 
3119 		  temp = expand_shift (RSHIFT_EXPR, wider_int_mode, temp,
3120 				       GET_MODE_BITSIZE (wider_int_mode)
3121 				       - GET_MODE_BITSIZE (int_mode),
3122 				       NULL_RTX, true);
3123 		}
3124 
3125 	      if (temp)
3126 		{
3127 		  if (mclass != MODE_INT)
3128 		    {
3129 		      if (target == 0)
3130 			target = gen_reg_rtx (mode);
3131 		      convert_move (target, temp, 0);
3132 		      return target;
3133 		    }
3134 		  else
3135 		    return gen_lowpart (mode, temp);
3136 		}
3137 	      else
3138 		delete_insns_since (last);
3139 	    }
3140 	}
3141     }
3142 
3143   /* One final attempt at implementing negation via subtraction,
3144      this time allowing widening of the operand.  */
3145   if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
3146     {
3147       rtx temp;
3148       temp = expand_binop (mode,
3149                            unoptab == negv_optab ? subv_optab : sub_optab,
3150                            CONST0_RTX (mode), op0,
3151                            target, unsignedp, OPTAB_LIB_WIDEN);
3152       if (temp)
3153         return temp;
3154     }
3155 
3156   return 0;
3157 }
3158 
3159 /* Emit code to compute the absolute value of OP0, with result to
3160    TARGET if convenient.  (TARGET may be 0.)  The return value says
3161    where the result actually is to be found.
3162 
3163    MODE is the mode of the operand; the mode of the result is
3164    different but can be deduced from MODE.
3165 
3166  */
3167 
3168 rtx
3169 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
3170 		   int result_unsignedp)
3171 {
3172   rtx temp;
3173 
3174   if (GET_MODE_CLASS (mode) != MODE_INT
3175       || ! flag_trapv)
3176     result_unsignedp = 1;
3177 
3178   /* First try to do it with a special abs instruction.  */
3179   temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3180                       op0, target, 0);
3181   if (temp != 0)
3182     return temp;
3183 
3184   /* For floating point modes, try clearing the sign bit.  */
3185   scalar_float_mode float_mode;
3186   if (is_a <scalar_float_mode> (mode, &float_mode))
3187     {
3188       temp = expand_absneg_bit (ABS, float_mode, op0, target);
3189       if (temp)
3190 	return temp;
3191     }
3192 
3193   /* If we have a MAX insn, we can do this as MAX (x, -x).  */
3194   if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3195       && !HONOR_SIGNED_ZEROS (mode))
3196     {
3197       rtx_insn *last = get_last_insn ();
3198 
3199       temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3200 			  op0, NULL_RTX, 0);
3201       if (temp != 0)
3202 	temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3203 			     OPTAB_WIDEN);
3204 
3205       if (temp != 0)
3206 	return temp;
3207 
3208       delete_insns_since (last);
3209     }
3210 
3211   /* If this machine has expensive jumps, we can do integer absolute
3212      value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3213      where W is the width of MODE.  */
3214 
3215   scalar_int_mode int_mode;
3216   if (is_int_mode (mode, &int_mode)
3217       && BRANCH_COST (optimize_insn_for_speed_p (),
3218 	      	      false) >= 2)
3219     {
3220       rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3221 				   GET_MODE_PRECISION (int_mode) - 1,
3222 				   NULL_RTX, 0);
3223 
3224       temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3225 			   OPTAB_LIB_WIDEN);
3226       if (temp != 0)
3227 	temp = expand_binop (int_mode,
3228 			     result_unsignedp ? sub_optab : subv_optab,
3229                              temp, extended, target, 0, OPTAB_LIB_WIDEN);
3230 
3231       if (temp != 0)
3232 	return temp;
3233     }
3234 
3235   return NULL_RTX;
3236 }
3237 
3238 rtx
3239 expand_abs (machine_mode mode, rtx op0, rtx target,
3240 	    int result_unsignedp, int safe)
3241 {
3242   rtx temp;
3243   rtx_code_label *op1;
3244 
3245   if (GET_MODE_CLASS (mode) != MODE_INT
3246       || ! flag_trapv)
3247     result_unsignedp = 1;
3248 
3249   temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3250   if (temp != 0)
3251     return temp;
3252 
3253   /* If that does not win, use conditional jump and negate.  */
3254 
3255   /* It is safe to use the target if it is the same
3256      as the source if this is also a pseudo register */
3257   if (op0 == target && REG_P (op0)
3258       && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3259     safe = 1;
3260 
3261   op1 = gen_label_rtx ();
3262   if (target == 0 || ! safe
3263       || GET_MODE (target) != mode
3264       || (MEM_P (target) && MEM_VOLATILE_P (target))
3265       || (REG_P (target)
3266 	  && REGNO (target) < FIRST_PSEUDO_REGISTER))
3267     target = gen_reg_rtx (mode);
3268 
3269   emit_move_insn (target, op0);
3270   NO_DEFER_POP;
3271 
3272   do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3273 			   NULL_RTX, NULL, op1,
3274 			   profile_probability::uninitialized ());
3275 
3276   op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3277                      target, target, 0);
3278   if (op0 != target)
3279     emit_move_insn (target, op0);
3280   emit_label (op1);
3281   OK_DEFER_POP;
3282   return target;
3283 }
3284 
3285 /* Emit code to compute the one's complement absolute value of OP0
3286    (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3287    (TARGET may be NULL_RTX.)  The return value says where the result
3288    actually is to be found.
3289 
3290    MODE is the mode of the operand; the mode of the result is
3291    different but can be deduced from MODE.  */
3292 
3293 rtx
3294 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
3295 {
3296   rtx temp;
3297 
3298   /* Not applicable for floating point modes.  */
3299   if (FLOAT_MODE_P (mode))
3300     return NULL_RTX;
3301 
3302   /* If we have a MAX insn, we can do this as MAX (x, ~x).  */
3303   if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3304     {
3305       rtx_insn *last = get_last_insn ();
3306 
3307       temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3308       if (temp != 0)
3309 	temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3310 			     OPTAB_WIDEN);
3311 
3312       if (temp != 0)
3313 	return temp;
3314 
3315       delete_insns_since (last);
3316     }
3317 
3318   /* If this machine has expensive jumps, we can do one's complement
3319      absolute value of X as (((signed) x >> (W-1)) ^ x).  */
3320 
3321   scalar_int_mode int_mode;
3322   if (is_int_mode (mode, &int_mode)
3323       && BRANCH_COST (optimize_insn_for_speed_p (),
3324 	             false) >= 2)
3325     {
3326       rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3327 				   GET_MODE_PRECISION (int_mode) - 1,
3328 				   NULL_RTX, 0);
3329 
3330       temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3331 			   OPTAB_LIB_WIDEN);
3332 
3333       if (temp != 0)
3334 	return temp;
3335     }
3336 
3337   return NULL_RTX;
3338 }
3339 
3340 /* A subroutine of expand_copysign, perform the copysign operation using the
3341    abs and neg primitives advertised to exist on the target.  The assumption
3342    is that we have a split register file, and leaving op0 in fp registers,
3343    and not playing with subregs so much, will help the register allocator.  */
3344 
3345 static rtx
3346 expand_copysign_absneg (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3347 		        int bitpos, bool op0_is_abs)
3348 {
3349   scalar_int_mode imode;
3350   enum insn_code icode;
3351   rtx sign;
3352   rtx_code_label *label;
3353 
3354   if (target == op1)
3355     target = NULL_RTX;
3356 
3357   /* Check if the back end provides an insn that handles signbit for the
3358      argument's mode. */
3359   icode = optab_handler (signbit_optab, mode);
3360   if (icode != CODE_FOR_nothing)
3361     {
3362       imode = as_a <scalar_int_mode> (insn_data[(int) icode].operand[0].mode);
3363       sign = gen_reg_rtx (imode);
3364       emit_unop_insn (icode, sign, op1, UNKNOWN);
3365     }
3366   else
3367     {
3368       if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3369 	{
3370 	  if (!int_mode_for_mode (mode).exists (&imode))
3371 	    return NULL_RTX;
3372 	  op1 = gen_lowpart (imode, op1);
3373 	}
3374       else
3375 	{
3376 	  int word;
3377 
3378 	  imode = word_mode;
3379 	  if (FLOAT_WORDS_BIG_ENDIAN)
3380 	    word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3381 	  else
3382 	    word = bitpos / BITS_PER_WORD;
3383 	  bitpos = bitpos % BITS_PER_WORD;
3384 	  op1 = operand_subword_force (op1, word, mode);
3385 	}
3386 
3387       wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3388       sign = expand_binop (imode, and_optab, op1,
3389 			   immed_wide_int_const (mask, imode),
3390 			   NULL_RTX, 1, OPTAB_LIB_WIDEN);
3391     }
3392 
3393   if (!op0_is_abs)
3394     {
3395       op0 = expand_unop (mode, abs_optab, op0, target, 0);
3396       if (op0 == NULL)
3397 	return NULL_RTX;
3398       target = op0;
3399     }
3400   else
3401     {
3402       if (target == NULL_RTX)
3403         target = copy_to_reg (op0);
3404       else
3405 	emit_move_insn (target, op0);
3406     }
3407 
3408   label = gen_label_rtx ();
3409   emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3410 
3411   if (CONST_DOUBLE_AS_FLOAT_P (op0))
3412     op0 = simplify_unary_operation (NEG, mode, op0, mode);
3413   else
3414     op0 = expand_unop (mode, neg_optab, op0, target, 0);
3415   if (op0 != target)
3416     emit_move_insn (target, op0);
3417 
3418   emit_label (label);
3419 
3420   return target;
3421 }
3422 
3423 
3424 /* A subroutine of expand_copysign, perform the entire copysign operation
3425    with integer bitmasks.  BITPOS is the position of the sign bit; OP0_IS_ABS
3426    is true if op0 is known to have its sign bit clear.  */
3427 
3428 static rtx
3429 expand_copysign_bit (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3430 		     int bitpos, bool op0_is_abs)
3431 {
3432   scalar_int_mode imode;
3433   int word, nwords, i;
3434   rtx temp;
3435   rtx_insn *insns;
3436 
3437   if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3438     {
3439       if (!int_mode_for_mode (mode).exists (&imode))
3440 	return NULL_RTX;
3441       word = 0;
3442       nwords = 1;
3443     }
3444   else
3445     {
3446       imode = word_mode;
3447 
3448       if (FLOAT_WORDS_BIG_ENDIAN)
3449 	word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3450       else
3451 	word = bitpos / BITS_PER_WORD;
3452       bitpos = bitpos % BITS_PER_WORD;
3453       nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3454     }
3455 
3456   wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3457 
3458   if (target == 0
3459       || target == op0
3460       || target == op1
3461       || (nwords > 1 && !valid_multiword_target_p (target)))
3462     target = gen_reg_rtx (mode);
3463 
3464   if (nwords > 1)
3465     {
3466       start_sequence ();
3467 
3468       for (i = 0; i < nwords; ++i)
3469 	{
3470 	  rtx targ_piece = operand_subword (target, i, 1, mode);
3471 	  rtx op0_piece = operand_subword_force (op0, i, mode);
3472 
3473 	  if (i == word)
3474 	    {
3475 	      if (!op0_is_abs)
3476 		op0_piece
3477 		  = expand_binop (imode, and_optab, op0_piece,
3478 				  immed_wide_int_const (~mask, imode),
3479 				  NULL_RTX, 1, OPTAB_LIB_WIDEN);
3480 	      op1 = expand_binop (imode, and_optab,
3481 				  operand_subword_force (op1, i, mode),
3482 				  immed_wide_int_const (mask, imode),
3483 				  NULL_RTX, 1, OPTAB_LIB_WIDEN);
3484 
3485 	      temp = expand_binop (imode, ior_optab, op0_piece, op1,
3486 				   targ_piece, 1, OPTAB_LIB_WIDEN);
3487 	      if (temp != targ_piece)
3488 		emit_move_insn (targ_piece, temp);
3489 	    }
3490 	  else
3491 	    emit_move_insn (targ_piece, op0_piece);
3492 	}
3493 
3494       insns = get_insns ();
3495       end_sequence ();
3496 
3497       emit_insn (insns);
3498     }
3499   else
3500     {
3501       op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3502 		          immed_wide_int_const (mask, imode),
3503 		          NULL_RTX, 1, OPTAB_LIB_WIDEN);
3504 
3505       op0 = gen_lowpart (imode, op0);
3506       if (!op0_is_abs)
3507 	op0 = expand_binop (imode, and_optab, op0,
3508 			    immed_wide_int_const (~mask, imode),
3509 			    NULL_RTX, 1, OPTAB_LIB_WIDEN);
3510 
3511       temp = expand_binop (imode, ior_optab, op0, op1,
3512 			   gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3513       target = lowpart_subreg_maybe_copy (mode, temp, imode);
3514     }
3515 
3516   return target;
3517 }
3518 
3519 /* Expand the C99 copysign operation.  OP0 and OP1 must be the same
3520    scalar floating point mode.  Return NULL if we do not know how to
3521    expand the operation inline.  */
3522 
3523 rtx
3524 expand_copysign (rtx op0, rtx op1, rtx target)
3525 {
3526   scalar_float_mode mode;
3527   const struct real_format *fmt;
3528   bool op0_is_abs;
3529   rtx temp;
3530 
3531   mode = as_a <scalar_float_mode> (GET_MODE (op0));
3532   gcc_assert (GET_MODE (op1) == mode);
3533 
3534   /* First try to do it with a special instruction.  */
3535   temp = expand_binop (mode, copysign_optab, op0, op1,
3536 		       target, 0, OPTAB_DIRECT);
3537   if (temp)
3538     return temp;
3539 
3540   fmt = REAL_MODE_FORMAT (mode);
3541   if (fmt == NULL || !fmt->has_signed_zero)
3542     return NULL_RTX;
3543 
3544   op0_is_abs = false;
3545   if (CONST_DOUBLE_AS_FLOAT_P (op0))
3546     {
3547       if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3548 	op0 = simplify_unary_operation (ABS, mode, op0, mode);
3549       op0_is_abs = true;
3550     }
3551 
3552   if (fmt->signbit_ro >= 0
3553       && (CONST_DOUBLE_AS_FLOAT_P (op0)
3554 	  || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3555 	      && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3556     {
3557       temp = expand_copysign_absneg (mode, op0, op1, target,
3558 				     fmt->signbit_ro, op0_is_abs);
3559       if (temp)
3560 	return temp;
3561     }
3562 
3563   if (fmt->signbit_rw < 0)
3564     return NULL_RTX;
3565   return expand_copysign_bit (mode, op0, op1, target,
3566 			      fmt->signbit_rw, op0_is_abs);
3567 }
3568 
3569 /* Generate an instruction whose insn-code is INSN_CODE,
3570    with two operands: an output TARGET and an input OP0.
3571    TARGET *must* be nonzero, and the output is always stored there.
3572    CODE is an rtx code such that (CODE OP0) is an rtx that describes
3573    the value that is stored into TARGET.
3574 
3575    Return false if expansion failed.  */
3576 
3577 bool
3578 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3579 		      enum rtx_code code)
3580 {
3581   struct expand_operand ops[2];
3582   rtx_insn *pat;
3583 
3584   create_output_operand (&ops[0], target, GET_MODE (target));
3585   create_input_operand (&ops[1], op0, GET_MODE (op0));
3586   pat = maybe_gen_insn (icode, 2, ops);
3587   if (!pat)
3588     return false;
3589 
3590   if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3591       && code != UNKNOWN)
3592     add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX,
3593 		    GET_MODE (op0));
3594 
3595   emit_insn (pat);
3596 
3597   if (ops[0].value != target)
3598     emit_move_insn (target, ops[0].value);
3599   return true;
3600 }
3601 /* Generate an instruction whose insn-code is INSN_CODE,
3602    with two operands: an output TARGET and an input OP0.
3603    TARGET *must* be nonzero, and the output is always stored there.
3604    CODE is an rtx code such that (CODE OP0) is an rtx that describes
3605    the value that is stored into TARGET.  */
3606 
3607 void
3608 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3609 {
3610   bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3611   gcc_assert (ok);
3612 }
3613 
3614 struct no_conflict_data
3615 {
3616   rtx target;
3617   rtx_insn *first, *insn;
3618   bool must_stay;
3619 };
3620 
3621 /* Called via note_stores by emit_libcall_block.  Set P->must_stay if
3622    the currently examined clobber / store has to stay in the list of
3623    insns that constitute the actual libcall block.  */
3624 static void
3625 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3626 {
3627   struct no_conflict_data *p= (struct no_conflict_data *) p0;
3628 
3629   /* If this inns directly contributes to setting the target, it must stay.  */
3630   if (reg_overlap_mentioned_p (p->target, dest))
3631     p->must_stay = true;
3632   /* If we haven't committed to keeping any other insns in the list yet,
3633      there is nothing more to check.  */
3634   else if (p->insn == p->first)
3635     return;
3636   /* If this insn sets / clobbers a register that feeds one of the insns
3637      already in the list, this insn has to stay too.  */
3638   else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3639 	   || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3640 	   || reg_used_between_p (dest, p->first, p->insn)
3641 	   /* Likewise if this insn depends on a register set by a previous
3642 	      insn in the list, or if it sets a result (presumably a hard
3643 	      register) that is set or clobbered by a previous insn.
3644 	      N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3645 	      SET_DEST perform the former check on the address, and the latter
3646 	      check on the MEM.  */
3647 	   || (GET_CODE (set) == SET
3648 	       && (modified_in_p (SET_SRC (set), p->first)
3649 		   || modified_in_p (SET_DEST (set), p->first)
3650 		   || modified_between_p (SET_SRC (set), p->first, p->insn)
3651 		   || modified_between_p (SET_DEST (set), p->first, p->insn))))
3652     p->must_stay = true;
3653 }
3654 
3655 
3656 /* Emit code to make a call to a constant function or a library call.
3657 
3658    INSNS is a list containing all insns emitted in the call.
3659    These insns leave the result in RESULT.  Our block is to copy RESULT
3660    to TARGET, which is logically equivalent to EQUIV.
3661 
3662    We first emit any insns that set a pseudo on the assumption that these are
3663    loading constants into registers; doing so allows them to be safely cse'ed
3664    between blocks.  Then we emit all the other insns in the block, followed by
3665    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
3666    note with an operand of EQUIV.  */
3667 
3668 static void
3669 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
3670 		      bool equiv_may_trap)
3671 {
3672   rtx final_dest = target;
3673   rtx_insn *next, *last, *insn;
3674 
3675   /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3676      into a MEM later.  Protect the libcall block from this change.  */
3677   if (! REG_P (target) || REG_USERVAR_P (target))
3678     target = gen_reg_rtx (GET_MODE (target));
3679 
3680   /* If we're using non-call exceptions, a libcall corresponding to an
3681      operation that may trap may also trap.  */
3682   /* ??? See the comment in front of make_reg_eh_region_note.  */
3683   if (cfun->can_throw_non_call_exceptions
3684       && (equiv_may_trap || may_trap_p (equiv)))
3685     {
3686       for (insn = insns; insn; insn = NEXT_INSN (insn))
3687 	if (CALL_P (insn))
3688 	  {
3689 	    rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3690 	    if (note)
3691 	      {
3692 		int lp_nr = INTVAL (XEXP (note, 0));
3693 		if (lp_nr == 0 || lp_nr == INT_MIN)
3694 		  remove_note (insn, note);
3695 	      }
3696 	  }
3697     }
3698   else
3699     {
3700       /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3701 	 reg note to indicate that this call cannot throw or execute a nonlocal
3702 	 goto (unless there is already a REG_EH_REGION note, in which case
3703 	 we update it).  */
3704       for (insn = insns; insn; insn = NEXT_INSN (insn))
3705 	if (CALL_P (insn))
3706 	  make_reg_eh_region_note_nothrow_nononlocal (insn);
3707     }
3708 
3709   /* First emit all insns that set pseudos.  Remove them from the list as
3710      we go.  Avoid insns that set pseudos which were referenced in previous
3711      insns.  These can be generated by move_by_pieces, for example,
3712      to update an address.  Similarly, avoid insns that reference things
3713      set in previous insns.  */
3714 
3715   for (insn = insns; insn; insn = next)
3716     {
3717       rtx set = single_set (insn);
3718 
3719       next = NEXT_INSN (insn);
3720 
3721       if (set != 0 && REG_P (SET_DEST (set))
3722 	  && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3723 	{
3724 	  struct no_conflict_data data;
3725 
3726 	  data.target = const0_rtx;
3727 	  data.first = insns;
3728 	  data.insn = insn;
3729 	  data.must_stay = 0;
3730 	  note_stores (PATTERN (insn), no_conflict_move_test, &data);
3731 	  if (! data.must_stay)
3732 	    {
3733 	      if (PREV_INSN (insn))
3734 		SET_NEXT_INSN (PREV_INSN (insn)) = next;
3735 	      else
3736 		insns = next;
3737 
3738 	      if (next)
3739 		SET_PREV_INSN (next) = PREV_INSN (insn);
3740 
3741 	      add_insn (insn);
3742 	    }
3743 	}
3744 
3745       /* Some ports use a loop to copy large arguments onto the stack.
3746 	 Don't move anything outside such a loop.  */
3747       if (LABEL_P (insn))
3748 	break;
3749     }
3750 
3751   /* Write the remaining insns followed by the final copy.  */
3752   for (insn = insns; insn; insn = next)
3753     {
3754       next = NEXT_INSN (insn);
3755 
3756       add_insn (insn);
3757     }
3758 
3759   last = emit_move_insn (target, result);
3760   if (equiv)
3761     set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
3762 
3763   if (final_dest != target)
3764     emit_move_insn (final_dest, target);
3765 }
3766 
3767 void
3768 emit_libcall_block (rtx_insn *insns, rtx target, rtx result, rtx equiv)
3769 {
3770   emit_libcall_block_1 (insns, target, result, equiv, false);
3771 }
3772 
3773 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3774    PURPOSE describes how this comparison will be used.  CODE is the rtx
3775    comparison code we will be using.
3776 
3777    ??? Actually, CODE is slightly weaker than that.  A target is still
3778    required to implement all of the normal bcc operations, but not
3779    required to implement all (or any) of the unordered bcc operations.  */
3780 
3781 int
3782 can_compare_p (enum rtx_code code, machine_mode mode,
3783 	       enum can_compare_purpose purpose)
3784 {
3785   rtx test;
3786   test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
3787   do
3788     {
3789       enum insn_code icode;
3790 
3791       if (purpose == ccp_jump
3792           && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
3793           && insn_operand_matches (icode, 0, test))
3794         return 1;
3795       if (purpose == ccp_store_flag
3796           && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
3797           && insn_operand_matches (icode, 1, test))
3798         return 1;
3799       if (purpose == ccp_cmov
3800 	  && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
3801 	return 1;
3802 
3803       mode = GET_MODE_WIDER_MODE (mode).else_void ();
3804       PUT_MODE (test, mode);
3805     }
3806   while (mode != VOIDmode);
3807 
3808   return 0;
3809 }
3810 
3811 /* This function is called when we are going to emit a compare instruction that
3812    compares the values found in X and Y, using the rtl operator COMPARISON.
3813 
3814    If they have mode BLKmode, then SIZE specifies the size of both operands.
3815 
3816    UNSIGNEDP nonzero says that the operands are unsigned;
3817    this matters if they need to be widened (as given by METHODS).
3818 
3819    *PTEST is where the resulting comparison RTX is returned or NULL_RTX
3820    if we failed to produce one.
3821 
3822    *PMODE is the mode of the inputs (in case they are const_int).
3823 
3824    This function performs all the setup necessary so that the caller only has
3825    to emit a single comparison insn.  This setup can involve doing a BLKmode
3826    comparison or emitting a library call to perform the comparison if no insn
3827    is available to handle it.
3828    The values which are passed in through pointers can be modified; the caller
3829    should perform the comparison on the modified values.  Constant
3830    comparisons must have already been folded.  */
3831 
3832 static void
3833 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3834 		  int unsignedp, enum optab_methods methods,
3835 		  rtx *ptest, machine_mode *pmode)
3836 {
3837   machine_mode mode = *pmode;
3838   rtx libfunc, test;
3839   machine_mode cmp_mode;
3840   enum mode_class mclass;
3841 
3842   /* The other methods are not needed.  */
3843   gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
3844 	      || methods == OPTAB_LIB_WIDEN);
3845 
3846   if (CONST_SCALAR_INT_P (y))
3847     canonicalize_comparison (mode, &comparison, &y);
3848 
3849   /* If we are optimizing, force expensive constants into a register.  */
3850   if (CONSTANT_P (x) && optimize
3851       && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ())
3852           > COSTS_N_INSNS (1)))
3853     x = force_reg (mode, x);
3854 
3855   if (CONSTANT_P (y) && optimize
3856       && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ())
3857           > COSTS_N_INSNS (1)))
3858     y = force_reg (mode, y);
3859 
3860 #if HAVE_cc0
3861   /* Make sure if we have a canonical comparison.  The RTL
3862      documentation states that canonical comparisons are required only
3863      for targets which have cc0.  */
3864   gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3865 #endif
3866 
3867   /* Don't let both operands fail to indicate the mode.  */
3868   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3869     x = force_reg (mode, x);
3870   if (mode == VOIDmode)
3871     mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
3872 
3873   /* Handle all BLKmode compares.  */
3874 
3875   if (mode == BLKmode)
3876     {
3877       machine_mode result_mode;
3878       enum insn_code cmp_code;
3879       rtx result;
3880       rtx opalign
3881 	= GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3882 
3883       gcc_assert (size);
3884 
3885       /* Try to use a memory block compare insn - either cmpstr
3886 	 or cmpmem will do.  */
3887       opt_scalar_int_mode cmp_mode_iter;
3888       FOR_EACH_MODE_IN_CLASS (cmp_mode_iter, MODE_INT)
3889 	{
3890 	  scalar_int_mode cmp_mode = cmp_mode_iter.require ();
3891 	  cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
3892 	  if (cmp_code == CODE_FOR_nothing)
3893 	    cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
3894 	  if (cmp_code == CODE_FOR_nothing)
3895 	    cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
3896 	  if (cmp_code == CODE_FOR_nothing)
3897 	    continue;
3898 
3899 	  /* Must make sure the size fits the insn's mode.  */
3900 	  if (CONST_INT_P (size)
3901 	      ? UINTVAL (size) > GET_MODE_MASK (cmp_mode)
3902 	      : (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (size)))
3903 		 > GET_MODE_BITSIZE (cmp_mode)))
3904 	    continue;
3905 
3906 	  result_mode = insn_data[cmp_code].operand[0].mode;
3907 	  result = gen_reg_rtx (result_mode);
3908 	  size = convert_to_mode (cmp_mode, size, 1);
3909 	  emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3910 
3911           *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
3912           *pmode = result_mode;
3913 	  return;
3914 	}
3915 
3916       if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
3917 	goto fail;
3918 
3919       /* Otherwise call a library function.  */
3920       result = emit_block_comp_via_libcall (x, y, size);
3921 
3922       x = result;
3923       y = const0_rtx;
3924       mode = TYPE_MODE (integer_type_node);
3925       methods = OPTAB_LIB_WIDEN;
3926       unsignedp = false;
3927     }
3928 
3929   /* Don't allow operands to the compare to trap, as that can put the
3930      compare and branch in different basic blocks.  */
3931   if (cfun->can_throw_non_call_exceptions)
3932     {
3933       if (may_trap_p (x))
3934 	x = copy_to_reg (x);
3935       if (may_trap_p (y))
3936 	y = copy_to_reg (y);
3937     }
3938 
3939   if (GET_MODE_CLASS (mode) == MODE_CC)
3940     {
3941       enum insn_code icode = optab_handler (cbranch_optab, CCmode);
3942       test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3943       gcc_assert (icode != CODE_FOR_nothing
3944                   && insn_operand_matches (icode, 0, test));
3945       *ptest = test;
3946       return;
3947     }
3948 
3949   mclass = GET_MODE_CLASS (mode);
3950   test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3951   FOR_EACH_MODE_FROM (cmp_mode, mode)
3952     {
3953       enum insn_code icode;
3954       icode = optab_handler (cbranch_optab, cmp_mode);
3955       if (icode != CODE_FOR_nothing
3956 	  && insn_operand_matches (icode, 0, test))
3957 	{
3958 	  rtx_insn *last = get_last_insn ();
3959 	  rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
3960 	  rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
3961 	  if (op0 && op1
3962 	      && insn_operand_matches (icode, 1, op0)
3963 	      && insn_operand_matches (icode, 2, op1))
3964 	    {
3965 	      XEXP (test, 0) = op0;
3966 	      XEXP (test, 1) = op1;
3967 	      *ptest = test;
3968 	      *pmode = cmp_mode;
3969 	      return;
3970 	    }
3971 	  delete_insns_since (last);
3972 	}
3973 
3974       if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
3975 	break;
3976     }
3977 
3978   if (methods != OPTAB_LIB_WIDEN)
3979     goto fail;
3980 
3981   if (SCALAR_FLOAT_MODE_P (mode))
3982     {
3983       /* Small trick if UNORDERED isn't implemented by the hardware.  */
3984       if (comparison == UNORDERED && rtx_equal_p (x, y))
3985 	{
3986 	  prepare_cmp_insn (x, y, UNLT, NULL_RTX, unsignedp, OPTAB_WIDEN,
3987 			    ptest, pmode);
3988 	  if (*ptest)
3989 	    return;
3990 	}
3991 
3992       prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
3993     }
3994   else
3995     {
3996       rtx result;
3997       machine_mode ret_mode;
3998 
3999       /* Handle a libcall just for the mode we are using.  */
4000       libfunc = optab_libfunc (cmp_optab, mode);
4001       gcc_assert (libfunc);
4002 
4003       /* If we want unsigned, and this mode has a distinct unsigned
4004 	 comparison routine, use that.  */
4005       if (unsignedp)
4006 	{
4007 	  rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
4008 	  if (ulibfunc)
4009 	    libfunc = ulibfunc;
4010 	}
4011 
4012       ret_mode = targetm.libgcc_cmp_return_mode ();
4013       result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4014 					ret_mode, x, mode, y, mode);
4015 
4016       /* There are two kinds of comparison routines. Biased routines
4017 	 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4018 	 of gcc expect that the comparison operation is equivalent
4019 	 to the modified comparison. For signed comparisons compare the
4020 	 result against 1 in the biased case, and zero in the unbiased
4021 	 case. For unsigned comparisons always compare against 1 after
4022 	 biasing the unbiased result by adding 1. This gives us a way to
4023 	 represent LTU.
4024 	 The comparisons in the fixed-point helper library are always
4025 	 biased.  */
4026       x = result;
4027       y = const1_rtx;
4028 
4029       if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
4030 	{
4031 	  if (unsignedp)
4032 	    x = plus_constant (ret_mode, result, 1);
4033 	  else
4034 	    y = const0_rtx;
4035 	}
4036 
4037       *pmode = ret_mode;
4038       prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
4039 			ptest, pmode);
4040     }
4041 
4042   return;
4043 
4044  fail:
4045   *ptest = NULL_RTX;
4046 }
4047 
4048 /* Before emitting an insn with code ICODE, make sure that X, which is going
4049    to be used for operand OPNUM of the insn, is converted from mode MODE to
4050    WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4051    that it is accepted by the operand predicate.  Return the new value.  */
4052 
4053 rtx
4054 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
4055 		 machine_mode wider_mode, int unsignedp)
4056 {
4057   if (mode != wider_mode)
4058     x = convert_modes (wider_mode, mode, x, unsignedp);
4059 
4060   if (!insn_operand_matches (icode, opnum, x))
4061     {
4062       machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
4063       if (reload_completed)
4064 	return NULL_RTX;
4065       if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
4066 	return NULL_RTX;
4067       x = copy_to_mode_reg (op_mode, x);
4068     }
4069 
4070   return x;
4071 }
4072 
4073 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4074    we can do the branch.  */
4075 
4076 static void
4077 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
4078 			  profile_probability prob)
4079 {
4080   machine_mode optab_mode;
4081   enum mode_class mclass;
4082   enum insn_code icode;
4083   rtx_insn *insn;
4084 
4085   mclass = GET_MODE_CLASS (mode);
4086   optab_mode = (mclass == MODE_CC) ? CCmode : mode;
4087   icode = optab_handler (cbranch_optab, optab_mode);
4088 
4089   gcc_assert (icode != CODE_FOR_nothing);
4090   gcc_assert (insn_operand_matches (icode, 0, test));
4091   insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
4092                                           XEXP (test, 1), label));
4093   if (prob.initialized_p ()
4094       && profile_status_for_fn (cfun) != PROFILE_ABSENT
4095       && insn
4096       && JUMP_P (insn)
4097       && any_condjump_p (insn)
4098       && !find_reg_note (insn, REG_BR_PROB, 0))
4099     add_reg_br_prob_note (insn, prob);
4100 }
4101 
4102 /* Generate code to compare X with Y so that the condition codes are
4103    set and to jump to LABEL if the condition is true.  If X is a
4104    constant and Y is not a constant, then the comparison is swapped to
4105    ensure that the comparison RTL has the canonical form.
4106 
4107    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4108    need to be widened.  UNSIGNEDP is also used to select the proper
4109    branch condition code.
4110 
4111    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4112 
4113    MODE is the mode of the inputs (in case they are const_int).
4114 
4115    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4116    It will be potentially converted into an unsigned variant based on
4117    UNSIGNEDP to select a proper jump instruction.
4118 
4119    PROB is the probability of jumping to LABEL.  */
4120 
4121 void
4122 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4123 			 machine_mode mode, int unsignedp, rtx label,
4124                          profile_probability prob)
4125 {
4126   rtx op0 = x, op1 = y;
4127   rtx test;
4128 
4129   /* Swap operands and condition to ensure canonical RTL.  */
4130   if (swap_commutative_operands_p (x, y)
4131       && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4132     {
4133       op0 = y, op1 = x;
4134       comparison = swap_condition (comparison);
4135     }
4136 
4137   /* If OP0 is still a constant, then both X and Y must be constants
4138      or the opposite comparison is not supported.  Force X into a register
4139      to create canonical RTL.  */
4140   if (CONSTANT_P (op0))
4141     op0 = force_reg (mode, op0);
4142 
4143   if (unsignedp)
4144     comparison = unsigned_condition (comparison);
4145 
4146   prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4147 		    &test, &mode);
4148   emit_cmp_and_jump_insn_1 (test, mode, label, prob);
4149 }
4150 
4151 
4152 /* Emit a library call comparison between floating point X and Y.
4153    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
4154 
4155 static void
4156 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4157 		       rtx *ptest, machine_mode *pmode)
4158 {
4159   enum rtx_code swapped = swap_condition (comparison);
4160   enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4161   machine_mode orig_mode = GET_MODE (x);
4162   machine_mode mode;
4163   rtx true_rtx, false_rtx;
4164   rtx value, target, equiv;
4165   rtx_insn *insns;
4166   rtx libfunc = 0;
4167   bool reversed_p = false;
4168   scalar_int_mode cmp_mode = targetm.libgcc_cmp_return_mode ();
4169 
4170   FOR_EACH_MODE_FROM (mode, orig_mode)
4171     {
4172       if (code_to_optab (comparison)
4173 	  && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
4174 	break;
4175 
4176       if (code_to_optab (swapped)
4177 	  && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
4178 	{
4179 	  std::swap (x, y);
4180 	  comparison = swapped;
4181 	  break;
4182 	}
4183 
4184       if (code_to_optab (reversed)
4185 	  && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4186 	{
4187 	  comparison = reversed;
4188 	  reversed_p = true;
4189 	  break;
4190 	}
4191     }
4192 
4193   gcc_assert (mode != VOIDmode);
4194 
4195   if (mode != orig_mode)
4196     {
4197       x = convert_to_mode (mode, x, 0);
4198       y = convert_to_mode (mode, y, 0);
4199     }
4200 
4201   /* Attach a REG_EQUAL note describing the semantics of the libcall to
4202      the RTL.  The allows the RTL optimizers to delete the libcall if the
4203      condition can be determined at compile-time.  */
4204   if (comparison == UNORDERED
4205       || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4206     {
4207       true_rtx = const_true_rtx;
4208       false_rtx = const0_rtx;
4209     }
4210   else
4211     {
4212       switch (comparison)
4213         {
4214         case EQ:
4215           true_rtx = const0_rtx;
4216           false_rtx = const_true_rtx;
4217           break;
4218 
4219         case NE:
4220           true_rtx = const_true_rtx;
4221           false_rtx = const0_rtx;
4222           break;
4223 
4224         case GT:
4225           true_rtx = const1_rtx;
4226           false_rtx = const0_rtx;
4227           break;
4228 
4229         case GE:
4230           true_rtx = const0_rtx;
4231           false_rtx = constm1_rtx;
4232           break;
4233 
4234         case LT:
4235           true_rtx = constm1_rtx;
4236           false_rtx = const0_rtx;
4237           break;
4238 
4239         case LE:
4240           true_rtx = const0_rtx;
4241           false_rtx = const1_rtx;
4242           break;
4243 
4244         default:
4245           gcc_unreachable ();
4246         }
4247     }
4248 
4249   if (comparison == UNORDERED)
4250     {
4251       rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4252       equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4253       equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4254 				    temp, const_true_rtx, equiv);
4255     }
4256   else
4257     {
4258       equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4259       if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4260         equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4261                                       equiv, true_rtx, false_rtx);
4262     }
4263 
4264   start_sequence ();
4265   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4266 				   cmp_mode, x, mode, y, mode);
4267   insns = get_insns ();
4268   end_sequence ();
4269 
4270   target = gen_reg_rtx (cmp_mode);
4271   emit_libcall_block (insns, target, value, equiv);
4272 
4273   if (comparison == UNORDERED
4274       || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4275       || reversed_p)
4276     *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4277   else
4278     *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4279 
4280   *pmode = cmp_mode;
4281 }
4282 
4283 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
4284 
4285 void
4286 emit_indirect_jump (rtx loc)
4287 {
4288   if (!targetm.have_indirect_jump ())
4289     sorry ("indirect jumps are not available on this target");
4290   else
4291     {
4292       struct expand_operand ops[1];
4293       create_address_operand (&ops[0], loc);
4294       expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
4295       emit_barrier ();
4296     }
4297 }
4298 
4299 
4300 /* Emit a conditional move instruction if the machine supports one for that
4301    condition and machine mode.
4302 
4303    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4304    the mode to use should they be constants.  If it is VOIDmode, they cannot
4305    both be constants.
4306 
4307    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4308    should be stored there.  MODE is the mode to use should they be constants.
4309    If it is VOIDmode, they cannot both be constants.
4310 
4311    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4312    is not supported.  */
4313 
4314 rtx
4315 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4316 		       machine_mode cmode, rtx op2, rtx op3,
4317 		       machine_mode mode, int unsignedp)
4318 {
4319   rtx comparison;
4320   rtx_insn *last;
4321   enum insn_code icode;
4322   enum rtx_code reversed;
4323 
4324   /* If the two source operands are identical, that's just a move.  */
4325 
4326   if (rtx_equal_p (op2, op3))
4327     {
4328       if (!target)
4329 	target = gen_reg_rtx (mode);
4330 
4331       emit_move_insn (target, op3);
4332       return target;
4333     }
4334 
4335   /* If one operand is constant, make it the second one.  Only do this
4336      if the other operand is not constant as well.  */
4337 
4338   if (swap_commutative_operands_p (op0, op1))
4339     {
4340       std::swap (op0, op1);
4341       code = swap_condition (code);
4342     }
4343 
4344   /* get_condition will prefer to generate LT and GT even if the old
4345      comparison was against zero, so undo that canonicalization here since
4346      comparisons against zero are cheaper.  */
4347   if (code == LT && op1 == const1_rtx)
4348     code = LE, op1 = const0_rtx;
4349   else if (code == GT && op1 == constm1_rtx)
4350     code = GE, op1 = const0_rtx;
4351 
4352   if (cmode == VOIDmode)
4353     cmode = GET_MODE (op0);
4354 
4355   enum rtx_code orig_code = code;
4356   bool swapped = false;
4357   if (swap_commutative_operands_p (op2, op3)
4358       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4359           != UNKNOWN))
4360     {
4361       std::swap (op2, op3);
4362       code = reversed;
4363       swapped = true;
4364     }
4365 
4366   if (mode == VOIDmode)
4367     mode = GET_MODE (op2);
4368 
4369   icode = direct_optab_handler (movcc_optab, mode);
4370 
4371   if (icode == CODE_FOR_nothing)
4372     return NULL_RTX;
4373 
4374   if (!target)
4375     target = gen_reg_rtx (mode);
4376 
4377   for (int pass = 0; ; pass++)
4378     {
4379       code = unsignedp ? unsigned_condition (code) : code;
4380       comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4381 
4382       /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4383 	 punt and let the caller figure out how best to deal with this
4384 	 situation.  */
4385       if (COMPARISON_P (comparison))
4386 	{
4387 	  saved_pending_stack_adjust save;
4388 	  save_pending_stack_adjust (&save);
4389 	  last = get_last_insn ();
4390 	  do_pending_stack_adjust ();
4391 	  machine_mode cmpmode = cmode;
4392 	  prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4393 			    GET_CODE (comparison), NULL_RTX, unsignedp,
4394 			    OPTAB_WIDEN, &comparison, &cmpmode);
4395 	  if (comparison)
4396 	    {
4397 	      struct expand_operand ops[4];
4398 
4399 	      create_output_operand (&ops[0], target, mode);
4400 	      create_fixed_operand (&ops[1], comparison);
4401 	      create_input_operand (&ops[2], op2, mode);
4402 	      create_input_operand (&ops[3], op3, mode);
4403 	      if (maybe_expand_insn (icode, 4, ops))
4404 		{
4405 		  if (ops[0].value != target)
4406 		    convert_move (target, ops[0].value, false);
4407 		  return target;
4408 		}
4409 	    }
4410 	  delete_insns_since (last);
4411 	  restore_pending_stack_adjust (&save);
4412 	}
4413 
4414       if (pass == 1)
4415 	return NULL_RTX;
4416 
4417       /* If the preferred op2/op3 order is not usable, retry with other
4418 	 operand order, perhaps it will expand successfully.  */
4419       if (swapped)
4420 	code = orig_code;
4421       else if ((reversed = reversed_comparison_code_parts (orig_code, op0, op1,
4422 							   NULL))
4423 	       != UNKNOWN)
4424 	code = reversed;
4425       else
4426 	return NULL_RTX;
4427       std::swap (op2, op3);
4428     }
4429 }
4430 
4431 
4432 /* Emit a conditional negate or bitwise complement using the
4433    negcc or notcc optabs if available.  Return NULL_RTX if such operations
4434    are not available.  Otherwise return the RTX holding the result.
4435    TARGET is the desired destination of the result.  COMP is the comparison
4436    on which to negate.  If COND is true move into TARGET the negation
4437    or bitwise complement of OP1.  Otherwise move OP2 into TARGET.
4438    CODE is either NEG or NOT.  MODE is the machine mode in which the
4439    operation is performed.  */
4440 
4441 rtx
4442 emit_conditional_neg_or_complement (rtx target, rtx_code code,
4443 				     machine_mode mode, rtx cond, rtx op1,
4444 				     rtx op2)
4445 {
4446   optab op = unknown_optab;
4447   if (code == NEG)
4448     op = negcc_optab;
4449   else if (code == NOT)
4450     op = notcc_optab;
4451   else
4452     gcc_unreachable ();
4453 
4454   insn_code icode = direct_optab_handler (op, mode);
4455 
4456   if (icode == CODE_FOR_nothing)
4457     return NULL_RTX;
4458 
4459   if (!target)
4460     target = gen_reg_rtx (mode);
4461 
4462   rtx_insn *last = get_last_insn ();
4463   struct expand_operand ops[4];
4464 
4465   create_output_operand (&ops[0], target, mode);
4466   create_fixed_operand (&ops[1], cond);
4467   create_input_operand (&ops[2], op1, mode);
4468   create_input_operand (&ops[3], op2, mode);
4469 
4470   if (maybe_expand_insn (icode, 4, ops))
4471     {
4472       if (ops[0].value != target)
4473 	convert_move (target, ops[0].value, false);
4474 
4475       return target;
4476     }
4477   delete_insns_since (last);
4478   return NULL_RTX;
4479 }
4480 
4481 /* Emit a conditional addition instruction if the machine supports one for that
4482    condition and machine mode.
4483 
4484    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4485    the mode to use should they be constants.  If it is VOIDmode, they cannot
4486    both be constants.
4487 
4488    OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4489    should be stored there.  MODE is the mode to use should they be constants.
4490    If it is VOIDmode, they cannot both be constants.
4491 
4492    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4493    is not supported.  */
4494 
4495 rtx
4496 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4497 		      machine_mode cmode, rtx op2, rtx op3,
4498 		      machine_mode mode, int unsignedp)
4499 {
4500   rtx comparison;
4501   rtx_insn *last;
4502   enum insn_code icode;
4503 
4504   /* If one operand is constant, make it the second one.  Only do this
4505      if the other operand is not constant as well.  */
4506 
4507   if (swap_commutative_operands_p (op0, op1))
4508     {
4509       std::swap (op0, op1);
4510       code = swap_condition (code);
4511     }
4512 
4513   /* get_condition will prefer to generate LT and GT even if the old
4514      comparison was against zero, so undo that canonicalization here since
4515      comparisons against zero are cheaper.  */
4516   if (code == LT && op1 == const1_rtx)
4517     code = LE, op1 = const0_rtx;
4518   else if (code == GT && op1 == constm1_rtx)
4519     code = GE, op1 = const0_rtx;
4520 
4521   if (cmode == VOIDmode)
4522     cmode = GET_MODE (op0);
4523 
4524   if (mode == VOIDmode)
4525     mode = GET_MODE (op2);
4526 
4527   icode = optab_handler (addcc_optab, mode);
4528 
4529   if (icode == CODE_FOR_nothing)
4530     return 0;
4531 
4532   if (!target)
4533     target = gen_reg_rtx (mode);
4534 
4535   code = unsignedp ? unsigned_condition (code) : code;
4536   comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4537 
4538   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4539      return NULL and let the caller figure out how best to deal with this
4540      situation.  */
4541   if (!COMPARISON_P (comparison))
4542     return NULL_RTX;
4543 
4544   do_pending_stack_adjust ();
4545   last = get_last_insn ();
4546   prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4547                     GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4548                     &comparison, &cmode);
4549   if (comparison)
4550     {
4551       struct expand_operand ops[4];
4552 
4553       create_output_operand (&ops[0], target, mode);
4554       create_fixed_operand (&ops[1], comparison);
4555       create_input_operand (&ops[2], op2, mode);
4556       create_input_operand (&ops[3], op3, mode);
4557       if (maybe_expand_insn (icode, 4, ops))
4558 	{
4559 	  if (ops[0].value != target)
4560 	    convert_move (target, ops[0].value, false);
4561 	  return target;
4562 	}
4563     }
4564   delete_insns_since (last);
4565   return NULL_RTX;
4566 }
4567 
4568 /* These functions attempt to generate an insn body, rather than
4569    emitting the insn, but if the gen function already emits them, we
4570    make no attempt to turn them back into naked patterns.  */
4571 
4572 /* Generate and return an insn body to add Y to X.  */
4573 
4574 rtx_insn *
4575 gen_add2_insn (rtx x, rtx y)
4576 {
4577   enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
4578 
4579   gcc_assert (insn_operand_matches (icode, 0, x));
4580   gcc_assert (insn_operand_matches (icode, 1, x));
4581   gcc_assert (insn_operand_matches (icode, 2, y));
4582 
4583   return GEN_FCN (icode) (x, x, y);
4584 }
4585 
4586 /* Generate and return an insn body to add r1 and c,
4587    storing the result in r0.  */
4588 
4589 rtx_insn *
4590 gen_add3_insn (rtx r0, rtx r1, rtx c)
4591 {
4592   enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
4593 
4594   if (icode == CODE_FOR_nothing
4595       || !insn_operand_matches (icode, 0, r0)
4596       || !insn_operand_matches (icode, 1, r1)
4597       || !insn_operand_matches (icode, 2, c))
4598     return NULL;
4599 
4600   return GEN_FCN (icode) (r0, r1, c);
4601 }
4602 
4603 int
4604 have_add2_insn (rtx x, rtx y)
4605 {
4606   enum insn_code icode;
4607 
4608   gcc_assert (GET_MODE (x) != VOIDmode);
4609 
4610   icode = optab_handler (add_optab, GET_MODE (x));
4611 
4612   if (icode == CODE_FOR_nothing)
4613     return 0;
4614 
4615   if (!insn_operand_matches (icode, 0, x)
4616       || !insn_operand_matches (icode, 1, x)
4617       || !insn_operand_matches (icode, 2, y))
4618     return 0;
4619 
4620   return 1;
4621 }
4622 
4623 /* Generate and return an insn body to add Y to X.  */
4624 
4625 rtx_insn *
4626 gen_addptr3_insn (rtx x, rtx y, rtx z)
4627 {
4628   enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
4629 
4630   gcc_assert (insn_operand_matches (icode, 0, x));
4631   gcc_assert (insn_operand_matches (icode, 1, y));
4632   gcc_assert (insn_operand_matches (icode, 2, z));
4633 
4634   return GEN_FCN (icode) (x, y, z);
4635 }
4636 
4637 /* Return true if the target implements an addptr pattern and X, Y,
4638    and Z are valid for the pattern predicates.  */
4639 
4640 int
4641 have_addptr3_insn (rtx x, rtx y, rtx z)
4642 {
4643   enum insn_code icode;
4644 
4645   gcc_assert (GET_MODE (x) != VOIDmode);
4646 
4647   icode = optab_handler (addptr3_optab, GET_MODE (x));
4648 
4649   if (icode == CODE_FOR_nothing)
4650     return 0;
4651 
4652   if (!insn_operand_matches (icode, 0, x)
4653       || !insn_operand_matches (icode, 1, y)
4654       || !insn_operand_matches (icode, 2, z))
4655     return 0;
4656 
4657   return 1;
4658 }
4659 
4660 /* Generate and return an insn body to subtract Y from X.  */
4661 
4662 rtx_insn *
4663 gen_sub2_insn (rtx x, rtx y)
4664 {
4665   enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
4666 
4667   gcc_assert (insn_operand_matches (icode, 0, x));
4668   gcc_assert (insn_operand_matches (icode, 1, x));
4669   gcc_assert (insn_operand_matches (icode, 2, y));
4670 
4671   return GEN_FCN (icode) (x, x, y);
4672 }
4673 
4674 /* Generate and return an insn body to subtract r1 and c,
4675    storing the result in r0.  */
4676 
4677 rtx_insn *
4678 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4679 {
4680   enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
4681 
4682   if (icode == CODE_FOR_nothing
4683       || !insn_operand_matches (icode, 0, r0)
4684       || !insn_operand_matches (icode, 1, r1)
4685       || !insn_operand_matches (icode, 2, c))
4686     return NULL;
4687 
4688   return GEN_FCN (icode) (r0, r1, c);
4689 }
4690 
4691 int
4692 have_sub2_insn (rtx x, rtx y)
4693 {
4694   enum insn_code icode;
4695 
4696   gcc_assert (GET_MODE (x) != VOIDmode);
4697 
4698   icode = optab_handler (sub_optab, GET_MODE (x));
4699 
4700   if (icode == CODE_FOR_nothing)
4701     return 0;
4702 
4703   if (!insn_operand_matches (icode, 0, x)
4704       || !insn_operand_matches (icode, 1, x)
4705       || !insn_operand_matches (icode, 2, y))
4706     return 0;
4707 
4708   return 1;
4709 }
4710 
4711 /* Generate the body of an insn to extend Y (with mode MFROM)
4712    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
4713 
4714 rtx_insn *
4715 gen_extend_insn (rtx x, rtx y, machine_mode mto,
4716 		 machine_mode mfrom, int unsignedp)
4717 {
4718   enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4719   return GEN_FCN (icode) (x, y);
4720 }
4721 
4722 /* Generate code to convert FROM to floating point
4723    and store in TO.  FROM must be fixed point and not VOIDmode.
4724    UNSIGNEDP nonzero means regard FROM as unsigned.
4725    Normally this is done by correcting the final value
4726    if it is negative.  */
4727 
4728 void
4729 expand_float (rtx to, rtx from, int unsignedp)
4730 {
4731   enum insn_code icode;
4732   rtx target = to;
4733   scalar_mode from_mode, to_mode;
4734   machine_mode fmode, imode;
4735   bool can_do_signed = false;
4736 
4737   /* Crash now, because we won't be able to decide which mode to use.  */
4738   gcc_assert (GET_MODE (from) != VOIDmode);
4739 
4740   /* Look for an insn to do the conversion.  Do it in the specified
4741      modes if possible; otherwise convert either input, output or both to
4742      wider mode.  If the integer mode is wider than the mode of FROM,
4743      we can do the conversion signed even if the input is unsigned.  */
4744 
4745   FOR_EACH_MODE_FROM (fmode, GET_MODE (to))
4746     FOR_EACH_MODE_FROM (imode, GET_MODE (from))
4747       {
4748 	int doing_unsigned = unsignedp;
4749 
4750 	if (fmode != GET_MODE (to)
4751 	    && (significand_size (fmode)
4752 		< GET_MODE_UNIT_PRECISION (GET_MODE (from))))
4753 	  continue;
4754 
4755 	icode = can_float_p (fmode, imode, unsignedp);
4756 	if (icode == CODE_FOR_nothing && unsignedp)
4757 	  {
4758 	    enum insn_code scode = can_float_p (fmode, imode, 0);
4759 	    if (scode != CODE_FOR_nothing)
4760 	      can_do_signed = true;
4761 	    if (imode != GET_MODE (from))
4762 	      icode = scode, doing_unsigned = 0;
4763 	  }
4764 
4765 	if (icode != CODE_FOR_nothing)
4766 	  {
4767 	    if (imode != GET_MODE (from))
4768 	      from = convert_to_mode (imode, from, unsignedp);
4769 
4770 	    if (fmode != GET_MODE (to))
4771 	      target = gen_reg_rtx (fmode);
4772 
4773 	    emit_unop_insn (icode, target, from,
4774 			    doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4775 
4776 	    if (target != to)
4777 	      convert_move (to, target, 0);
4778 	    return;
4779 	  }
4780       }
4781 
4782   /* Unsigned integer, and no way to convert directly.  Convert as signed,
4783      then unconditionally adjust the result.  */
4784   if (unsignedp
4785       && can_do_signed
4786       && is_a <scalar_mode> (GET_MODE (to), &to_mode)
4787       && is_a <scalar_mode> (GET_MODE (from), &from_mode))
4788     {
4789       opt_scalar_mode fmode_iter;
4790       rtx_code_label *label = gen_label_rtx ();
4791       rtx temp;
4792       REAL_VALUE_TYPE offset;
4793 
4794       /* Look for a usable floating mode FMODE wider than the source and at
4795 	 least as wide as the target.  Using FMODE will avoid rounding woes
4796 	 with unsigned values greater than the signed maximum value.  */
4797 
4798       FOR_EACH_MODE_FROM (fmode_iter, to_mode)
4799 	{
4800 	  scalar_mode fmode = fmode_iter.require ();
4801 	  if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode)
4802 	      && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing)
4803 	    break;
4804 	}
4805 
4806       if (!fmode_iter.exists (&fmode))
4807 	{
4808 	  /* There is no such mode.  Pretend the target is wide enough.  */
4809 	  fmode = to_mode;
4810 
4811 	  /* Avoid double-rounding when TO is narrower than FROM.  */
4812 	  if ((significand_size (fmode) + 1)
4813 	      < GET_MODE_PRECISION (from_mode))
4814 	    {
4815 	      rtx temp1;
4816 	      rtx_code_label *neglabel = gen_label_rtx ();
4817 
4818 	      /* Don't use TARGET if it isn't a register, is a hard register,
4819 		 or is the wrong mode.  */
4820 	      if (!REG_P (target)
4821 		  || REGNO (target) < FIRST_PSEUDO_REGISTER
4822 		  || GET_MODE (target) != fmode)
4823 		target = gen_reg_rtx (fmode);
4824 
4825 	      imode = from_mode;
4826 	      do_pending_stack_adjust ();
4827 
4828 	      /* Test whether the sign bit is set.  */
4829 	      emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4830 				       0, neglabel);
4831 
4832 	      /* The sign bit is not set.  Convert as signed.  */
4833 	      expand_float (target, from, 0);
4834 	      emit_jump_insn (targetm.gen_jump (label));
4835 	      emit_barrier ();
4836 
4837 	      /* The sign bit is set.
4838 		 Convert to a usable (positive signed) value by shifting right
4839 		 one bit, while remembering if a nonzero bit was shifted
4840 		 out; i.e., compute  (from & 1) | (from >> 1).  */
4841 
4842 	      emit_label (neglabel);
4843 	      temp = expand_binop (imode, and_optab, from, const1_rtx,
4844 				   NULL_RTX, 1, OPTAB_LIB_WIDEN);
4845 	      temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
4846 	      temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4847 				   OPTAB_LIB_WIDEN);
4848 	      expand_float (target, temp, 0);
4849 
4850 	      /* Multiply by 2 to undo the shift above.  */
4851 	      temp = expand_binop (fmode, add_optab, target, target,
4852 				   target, 0, OPTAB_LIB_WIDEN);
4853 	      if (temp != target)
4854 		emit_move_insn (target, temp);
4855 
4856 	      do_pending_stack_adjust ();
4857 	      emit_label (label);
4858 	      goto done;
4859 	    }
4860 	}
4861 
4862       /* If we are about to do some arithmetic to correct for an
4863 	 unsigned operand, do it in a pseudo-register.  */
4864 
4865       if (to_mode != fmode
4866 	  || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4867 	target = gen_reg_rtx (fmode);
4868 
4869       /* Convert as signed integer to floating.  */
4870       expand_float (target, from, 0);
4871 
4872       /* If FROM is negative (and therefore TO is negative),
4873 	 correct its value by 2**bitwidth.  */
4874 
4875       do_pending_stack_adjust ();
4876       emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, from_mode,
4877 			       0, label);
4878 
4879 
4880       real_2expN (&offset, GET_MODE_PRECISION (from_mode), fmode);
4881       temp = expand_binop (fmode, add_optab, target,
4882 			   const_double_from_real_value (offset, fmode),
4883 			   target, 0, OPTAB_LIB_WIDEN);
4884       if (temp != target)
4885 	emit_move_insn (target, temp);
4886 
4887       do_pending_stack_adjust ();
4888       emit_label (label);
4889       goto done;
4890     }
4891 
4892   /* No hardware instruction available; call a library routine.  */
4893     {
4894       rtx libfunc;
4895       rtx_insn *insns;
4896       rtx value;
4897       convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4898 
4899       if (is_narrower_int_mode (GET_MODE (from), SImode))
4900 	from = convert_to_mode (SImode, from, unsignedp);
4901 
4902       libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4903       gcc_assert (libfunc);
4904 
4905       start_sequence ();
4906 
4907       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4908 				       GET_MODE (to), from, GET_MODE (from));
4909       insns = get_insns ();
4910       end_sequence ();
4911 
4912       emit_libcall_block (insns, target, value,
4913 			  gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
4914 					 GET_MODE (to), from));
4915     }
4916 
4917  done:
4918 
4919   /* Copy result to requested destination
4920      if we have been computing in a temp location.  */
4921 
4922   if (target != to)
4923     {
4924       if (GET_MODE (target) == GET_MODE (to))
4925 	emit_move_insn (to, target);
4926       else
4927 	convert_move (to, target, 0);
4928     }
4929 }
4930 
4931 /* Generate code to convert FROM to fixed point and store in TO.  FROM
4932    must be floating point.  */
4933 
4934 void
4935 expand_fix (rtx to, rtx from, int unsignedp)
4936 {
4937   enum insn_code icode;
4938   rtx target = to;
4939   machine_mode fmode, imode;
4940   opt_scalar_mode fmode_iter;
4941   bool must_trunc = false;
4942 
4943   /* We first try to find a pair of modes, one real and one integer, at
4944      least as wide as FROM and TO, respectively, in which we can open-code
4945      this conversion.  If the integer mode is wider than the mode of TO,
4946      we can do the conversion either signed or unsigned.  */
4947 
4948   FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
4949     FOR_EACH_MODE_FROM (imode, GET_MODE (to))
4950       {
4951 	int doing_unsigned = unsignedp;
4952 
4953 	icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4954 	if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4955 	  icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4956 
4957 	if (icode != CODE_FOR_nothing)
4958 	  {
4959 	    rtx_insn *last = get_last_insn ();
4960 	    if (fmode != GET_MODE (from))
4961 	      from = convert_to_mode (fmode, from, 0);
4962 
4963 	    if (must_trunc)
4964 	      {
4965 		rtx temp = gen_reg_rtx (GET_MODE (from));
4966 		from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4967 				    temp, 0);
4968 	      }
4969 
4970 	    if (imode != GET_MODE (to))
4971 	      target = gen_reg_rtx (imode);
4972 
4973 	    if (maybe_emit_unop_insn (icode, target, from,
4974 				      doing_unsigned ? UNSIGNED_FIX : FIX))
4975 	      {
4976 		if (target != to)
4977 		  convert_move (to, target, unsignedp);
4978 		return;
4979 	      }
4980 	    delete_insns_since (last);
4981 	  }
4982       }
4983 
4984   /* For an unsigned conversion, there is one more way to do it.
4985      If we have a signed conversion, we generate code that compares
4986      the real value to the largest representable positive number.  If if
4987      is smaller, the conversion is done normally.  Otherwise, subtract
4988      one plus the highest signed number, convert, and add it back.
4989 
4990      We only need to check all real modes, since we know we didn't find
4991      anything with a wider integer mode.
4992 
4993      This code used to extend FP value into mode wider than the destination.
4994      This is needed for decimal float modes which cannot accurately
4995      represent one plus the highest signed number of the same size, but
4996      not for binary modes.  Consider, for instance conversion from SFmode
4997      into DImode.
4998 
4999      The hot path through the code is dealing with inputs smaller than 2^63
5000      and doing just the conversion, so there is no bits to lose.
5001 
5002      In the other path we know the value is positive in the range 2^63..2^64-1
5003      inclusive.  (as for other input overflow happens and result is undefined)
5004      So we know that the most important bit set in mantissa corresponds to
5005      2^63.  The subtraction of 2^63 should not generate any rounding as it
5006      simply clears out that bit.  The rest is trivial.  */
5007 
5008   scalar_int_mode to_mode;
5009   if (unsignedp
5010       && is_a <scalar_int_mode> (GET_MODE (to), &to_mode)
5011       && HWI_COMPUTABLE_MODE_P (to_mode))
5012     FOR_EACH_MODE_FROM (fmode_iter, as_a <scalar_mode> (GET_MODE (from)))
5013       {
5014 	scalar_mode fmode = fmode_iter.require ();
5015 	if (CODE_FOR_nothing != can_fix_p (to_mode, fmode,
5016 					   0, &must_trunc)
5017 	    && (!DECIMAL_FLOAT_MODE_P (fmode)
5018 		|| (GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode))))
5019 	  {
5020 	    int bitsize;
5021 	    REAL_VALUE_TYPE offset;
5022 	    rtx limit;
5023 	    rtx_code_label *lab1, *lab2;
5024 	    rtx_insn *insn;
5025 
5026 	    bitsize = GET_MODE_PRECISION (to_mode);
5027 	    real_2expN (&offset, bitsize - 1, fmode);
5028 	    limit = const_double_from_real_value (offset, fmode);
5029 	    lab1 = gen_label_rtx ();
5030 	    lab2 = gen_label_rtx ();
5031 
5032 	    if (fmode != GET_MODE (from))
5033 	      from = convert_to_mode (fmode, from, 0);
5034 
5035 	    /* See if we need to do the subtraction.  */
5036 	    do_pending_stack_adjust ();
5037 	    emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX,
5038 				     GET_MODE (from), 0, lab1);
5039 
5040 	    /* If not, do the signed "fix" and branch around fixup code.  */
5041 	    expand_fix (to, from, 0);
5042 	    emit_jump_insn (targetm.gen_jump (lab2));
5043 	    emit_barrier ();
5044 
5045 	    /* Otherwise, subtract 2**(N-1), convert to signed number,
5046 	       then add 2**(N-1).  Do the addition using XOR since this
5047 	       will often generate better code.  */
5048 	    emit_label (lab1);
5049 	    target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5050 				   NULL_RTX, 0, OPTAB_LIB_WIDEN);
5051 	    expand_fix (to, target, 0);
5052 	    target = expand_binop (to_mode, xor_optab, to,
5053 				   gen_int_mode
5054 				   (HOST_WIDE_INT_1 << (bitsize - 1),
5055 				    to_mode),
5056 				   to, 1, OPTAB_LIB_WIDEN);
5057 
5058 	    if (target != to)
5059 	      emit_move_insn (to, target);
5060 
5061 	    emit_label (lab2);
5062 
5063 	    if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing)
5064 	      {
5065 		/* Make a place for a REG_NOTE and add it.  */
5066 		insn = emit_move_insn (to, to);
5067 		set_dst_reg_note (insn, REG_EQUAL,
5068 				  gen_rtx_fmt_e (UNSIGNED_FIX, to_mode,
5069 						 copy_rtx (from)),
5070 				  to);
5071 	      }
5072 
5073 	    return;
5074 	  }
5075       }
5076 
5077   /* We can't do it with an insn, so use a library call.  But first ensure
5078      that the mode of TO is at least as wide as SImode, since those are the
5079      only library calls we know about.  */
5080 
5081   if (is_narrower_int_mode (GET_MODE (to), SImode))
5082     {
5083       target = gen_reg_rtx (SImode);
5084 
5085       expand_fix (target, from, unsignedp);
5086     }
5087   else
5088     {
5089       rtx_insn *insns;
5090       rtx value;
5091       rtx libfunc;
5092 
5093       convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5094       libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5095       gcc_assert (libfunc);
5096 
5097       start_sequence ();
5098 
5099       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5100 				       GET_MODE (to), from, GET_MODE (from));
5101       insns = get_insns ();
5102       end_sequence ();
5103 
5104       emit_libcall_block (insns, target, value,
5105 			  gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5106 					 GET_MODE (to), from));
5107     }
5108 
5109   if (target != to)
5110     {
5111       if (GET_MODE (to) == GET_MODE (target))
5112         emit_move_insn (to, target);
5113       else
5114         convert_move (to, target, 0);
5115     }
5116 }
5117 
5118 
5119 /* Promote integer arguments for a libcall if necessary.
5120    emit_library_call_value cannot do the promotion because it does not
5121    know if it should do a signed or unsigned promotion.  This is because
5122    there are no tree types defined for libcalls.  */
5123 
5124 static rtx
5125 prepare_libcall_arg (rtx arg, int uintp)
5126 {
5127   scalar_int_mode mode;
5128   machine_mode arg_mode;
5129   if (is_a <scalar_int_mode> (GET_MODE (arg), &mode))
5130     {
5131       /*  If we need to promote the integer function argument we need to do
5132 	  it here instead of inside emit_library_call_value because in
5133 	  emit_library_call_value we don't know if we should do a signed or
5134 	  unsigned promotion.  */
5135 
5136       int unsigned_p = 0;
5137       arg_mode = promote_function_mode (NULL_TREE, mode,
5138 					&unsigned_p, NULL_TREE, 0);
5139       if (arg_mode != mode)
5140 	return convert_to_mode (arg_mode, arg, uintp);
5141     }
5142     return arg;
5143 }
5144 
5145 /* Generate code to convert FROM or TO a fixed-point.
5146    If UINTP is true, either TO or FROM is an unsigned integer.
5147    If SATP is true, we need to saturate the result.  */
5148 
5149 void
5150 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5151 {
5152   machine_mode to_mode = GET_MODE (to);
5153   machine_mode from_mode = GET_MODE (from);
5154   convert_optab tab;
5155   enum rtx_code this_code;
5156   enum insn_code code;
5157   rtx_insn *insns;
5158   rtx value;
5159   rtx libfunc;
5160 
5161   if (to_mode == from_mode)
5162     {
5163       emit_move_insn (to, from);
5164       return;
5165     }
5166 
5167   if (uintp)
5168     {
5169       tab = satp ? satfractuns_optab : fractuns_optab;
5170       this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5171     }
5172   else
5173     {
5174       tab = satp ? satfract_optab : fract_optab;
5175       this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5176     }
5177   code = convert_optab_handler (tab, to_mode, from_mode);
5178   if (code != CODE_FOR_nothing)
5179     {
5180       emit_unop_insn (code, to, from, this_code);
5181       return;
5182     }
5183 
5184   libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5185   gcc_assert (libfunc);
5186 
5187   from = prepare_libcall_arg (from, uintp);
5188   from_mode = GET_MODE (from);
5189 
5190   start_sequence ();
5191   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5192 				   from, from_mode);
5193   insns = get_insns ();
5194   end_sequence ();
5195 
5196   emit_libcall_block (insns, to, value,
5197 		      gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
5198 }
5199 
5200 /* Generate code to convert FROM to fixed point and store in TO.  FROM
5201    must be floating point, TO must be signed.  Use the conversion optab
5202    TAB to do the conversion.  */
5203 
5204 bool
5205 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5206 {
5207   enum insn_code icode;
5208   rtx target = to;
5209   machine_mode fmode, imode;
5210 
5211   /* We first try to find a pair of modes, one real and one integer, at
5212      least as wide as FROM and TO, respectively, in which we can open-code
5213      this conversion.  If the integer mode is wider than the mode of TO,
5214      we can do the conversion either signed or unsigned.  */
5215 
5216   FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
5217     FOR_EACH_MODE_FROM (imode, GET_MODE (to))
5218       {
5219 	icode = convert_optab_handler (tab, imode, fmode);
5220 	if (icode != CODE_FOR_nothing)
5221 	  {
5222 	    rtx_insn *last = get_last_insn ();
5223 	    if (fmode != GET_MODE (from))
5224 	      from = convert_to_mode (fmode, from, 0);
5225 
5226 	    if (imode != GET_MODE (to))
5227 	      target = gen_reg_rtx (imode);
5228 
5229 	    if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5230 	      {
5231 	        delete_insns_since (last);
5232 		continue;
5233 	      }
5234 	    if (target != to)
5235 	      convert_move (to, target, 0);
5236 	    return true;
5237 	  }
5238       }
5239 
5240   return false;
5241 }
5242 
5243 /* Report whether we have an instruction to perform the operation
5244    specified by CODE on operands of mode MODE.  */
5245 int
5246 have_insn_for (enum rtx_code code, machine_mode mode)
5247 {
5248   return (code_to_optab (code)
5249 	  && (optab_handler (code_to_optab (code), mode)
5250 	      != CODE_FOR_nothing));
5251 }
5252 
5253 /* Print information about the current contents of the optabs on
5254    STDERR.  */
5255 
5256 DEBUG_FUNCTION void
5257 debug_optab_libfuncs (void)
5258 {
5259   int i, j, k;
5260 
5261   /* Dump the arithmetic optabs.  */
5262   for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
5263     for (j = 0; j < NUM_MACHINE_MODES; ++j)
5264       {
5265 	rtx l = optab_libfunc ((optab) i, (machine_mode) j);
5266 	if (l)
5267 	  {
5268 	    gcc_assert (GET_CODE (l) == SYMBOL_REF);
5269 	    fprintf (stderr, "%s\t%s:\t%s\n",
5270 		     GET_RTX_NAME (optab_to_code ((optab) i)),
5271 		     GET_MODE_NAME (j),
5272 		     XSTR (l, 0));
5273 	  }
5274       }
5275 
5276   /* Dump the conversion optabs.  */
5277   for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
5278     for (j = 0; j < NUM_MACHINE_MODES; ++j)
5279       for (k = 0; k < NUM_MACHINE_MODES; ++k)
5280 	{
5281 	  rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
5282 					 (machine_mode) k);
5283 	  if (l)
5284 	    {
5285 	      gcc_assert (GET_CODE (l) == SYMBOL_REF);
5286 	      fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5287 		       GET_RTX_NAME (optab_to_code ((optab) i)),
5288 		       GET_MODE_NAME (j),
5289 		       GET_MODE_NAME (k),
5290 		       XSTR (l, 0));
5291 	    }
5292 	}
5293 }
5294 
5295 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5296    CODE.  Return 0 on failure.  */
5297 
5298 rtx_insn *
5299 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
5300 {
5301   machine_mode mode = GET_MODE (op1);
5302   enum insn_code icode;
5303   rtx_insn *insn;
5304   rtx trap_rtx;
5305 
5306   if (mode == VOIDmode)
5307     return 0;
5308 
5309   icode = optab_handler (ctrap_optab, mode);
5310   if (icode == CODE_FOR_nothing)
5311     return 0;
5312 
5313   /* Some targets only accept a zero trap code.  */
5314   if (!insn_operand_matches (icode, 3, tcode))
5315     return 0;
5316 
5317   do_pending_stack_adjust ();
5318   start_sequence ();
5319   prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
5320 		    &trap_rtx, &mode);
5321   if (!trap_rtx)
5322     insn = NULL;
5323   else
5324     insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
5325 			    tcode);
5326 
5327   /* If that failed, then give up.  */
5328   if (insn == 0)
5329     {
5330       end_sequence ();
5331       return 0;
5332     }
5333 
5334   emit_insn (insn);
5335   insn = get_insns ();
5336   end_sequence ();
5337   return insn;
5338 }
5339 
5340 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5341    or unsigned operation code.  */
5342 
5343 enum rtx_code
5344 get_rtx_code (enum tree_code tcode, bool unsignedp)
5345 {
5346   enum rtx_code code;
5347   switch (tcode)
5348     {
5349     case EQ_EXPR:
5350       code = EQ;
5351       break;
5352     case NE_EXPR:
5353       code = NE;
5354       break;
5355     case LT_EXPR:
5356       code = unsignedp ? LTU : LT;
5357       break;
5358     case LE_EXPR:
5359       code = unsignedp ? LEU : LE;
5360       break;
5361     case GT_EXPR:
5362       code = unsignedp ? GTU : GT;
5363       break;
5364     case GE_EXPR:
5365       code = unsignedp ? GEU : GE;
5366       break;
5367 
5368     case UNORDERED_EXPR:
5369       code = UNORDERED;
5370       break;
5371     case ORDERED_EXPR:
5372       code = ORDERED;
5373       break;
5374     case UNLT_EXPR:
5375       code = UNLT;
5376       break;
5377     case UNLE_EXPR:
5378       code = UNLE;
5379       break;
5380     case UNGT_EXPR:
5381       code = UNGT;
5382       break;
5383     case UNGE_EXPR:
5384       code = UNGE;
5385       break;
5386     case UNEQ_EXPR:
5387       code = UNEQ;
5388       break;
5389     case LTGT_EXPR:
5390       code = LTGT;
5391       break;
5392 
5393     case BIT_AND_EXPR:
5394       code = AND;
5395       break;
5396 
5397     case BIT_IOR_EXPR:
5398       code = IOR;
5399       break;
5400 
5401     default:
5402       gcc_unreachable ();
5403     }
5404   return code;
5405 }
5406 
5407 /* Return a comparison rtx of mode CMP_MODE for COND.  Use UNSIGNEDP to
5408    select signed or unsigned operators.  OPNO holds the index of the
5409    first comparison operand for insn ICODE.  Do not generate the
5410    compare instruction itself.  */
5411 
5412 static rtx
5413 vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
5414 		    tree t_op0, tree t_op1, bool unsignedp,
5415 		    enum insn_code icode, unsigned int opno)
5416 {
5417   struct expand_operand ops[2];
5418   rtx rtx_op0, rtx_op1;
5419   machine_mode m0, m1;
5420   enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
5421 
5422   gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
5423 
5424   /* Expand operands.  For vector types with scalar modes, e.g. where int64x1_t
5425      has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
5426      cases, use the original mode.  */
5427   rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
5428 			 EXPAND_STACK_PARM);
5429   m0 = GET_MODE (rtx_op0);
5430   if (m0 == VOIDmode)
5431     m0 = TYPE_MODE (TREE_TYPE (t_op0));
5432 
5433   rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
5434 			 EXPAND_STACK_PARM);
5435   m1 = GET_MODE (rtx_op1);
5436   if (m1 == VOIDmode)
5437     m1 = TYPE_MODE (TREE_TYPE (t_op1));
5438 
5439   create_input_operand (&ops[0], rtx_op0, m0);
5440   create_input_operand (&ops[1], rtx_op1, m1);
5441   if (!maybe_legitimize_operands (icode, opno, 2, ops))
5442     gcc_unreachable ();
5443   return gen_rtx_fmt_ee (rcode, cmp_mode, ops[0].value, ops[1].value);
5444 }
5445 
5446 /* Check if vec_perm mask SEL is a constant equivalent to a shift of
5447    the first vec_perm operand, assuming the second operand is a constant
5448    vector of zeros.  Return the shift distance in bits if so, or NULL_RTX
5449    if the vec_perm is not a shift.  MODE is the mode of the value being
5450    shifted.  */
5451 static rtx
5452 shift_amt_for_vec_perm_mask (machine_mode mode, const vec_perm_indices &sel)
5453 {
5454   unsigned int bitsize = GET_MODE_UNIT_BITSIZE (mode);
5455   poly_int64 first = sel[0];
5456   if (maybe_ge (sel[0], GET_MODE_NUNITS (mode)))
5457     return NULL_RTX;
5458 
5459   if (!sel.series_p (0, 1, first, 1))
5460     {
5461       unsigned int nelt;
5462       if (!GET_MODE_NUNITS (mode).is_constant (&nelt))
5463 	return NULL_RTX;
5464       for (unsigned int i = 1; i < nelt; i++)
5465 	{
5466 	  poly_int64 expected = i + first;
5467 	  /* Indices into the second vector are all equivalent.  */
5468 	  if (maybe_lt (sel[i], nelt)
5469 	      ? maybe_ne (sel[i], expected)
5470 	      : maybe_lt (expected, nelt))
5471 	    return NULL_RTX;
5472 	}
5473     }
5474 
5475   return gen_int_shift_amount (mode, first * bitsize);
5476 }
5477 
5478 /* A subroutine of expand_vec_perm_var for expanding one vec_perm insn.  */
5479 
5480 static rtx
5481 expand_vec_perm_1 (enum insn_code icode, rtx target,
5482 		   rtx v0, rtx v1, rtx sel)
5483 {
5484   machine_mode tmode = GET_MODE (target);
5485   machine_mode smode = GET_MODE (sel);
5486   struct expand_operand ops[4];
5487 
5488   gcc_assert (GET_MODE_CLASS (smode) == MODE_VECTOR_INT
5489 	      || mode_for_int_vector (tmode).require () == smode);
5490   create_output_operand (&ops[0], target, tmode);
5491   create_input_operand (&ops[3], sel, smode);
5492 
5493   /* Make an effort to preserve v0 == v1.  The target expander is able to
5494      rely on this to determine if we're permuting a single input operand.  */
5495   if (rtx_equal_p (v0, v1))
5496     {
5497       if (!insn_operand_matches (icode, 1, v0))
5498         v0 = force_reg (tmode, v0);
5499       gcc_checking_assert (insn_operand_matches (icode, 1, v0));
5500       gcc_checking_assert (insn_operand_matches (icode, 2, v0));
5501 
5502       create_fixed_operand (&ops[1], v0);
5503       create_fixed_operand (&ops[2], v0);
5504     }
5505   else
5506     {
5507       create_input_operand (&ops[1], v0, tmode);
5508       create_input_operand (&ops[2], v1, tmode);
5509     }
5510 
5511   if (maybe_expand_insn (icode, 4, ops))
5512     return ops[0].value;
5513   return NULL_RTX;
5514 }
5515 
5516 /* Implement a permutation of vectors v0 and v1 using the permutation
5517    vector in SEL and return the result.  Use TARGET to hold the result
5518    if nonnull and convenient.
5519 
5520    MODE is the mode of the vectors being permuted (V0 and V1).  SEL_MODE
5521    is the TYPE_MODE associated with SEL, or BLKmode if SEL isn't known
5522    to have a particular mode.  */
5523 
5524 rtx
5525 expand_vec_perm_const (machine_mode mode, rtx v0, rtx v1,
5526 		       const vec_perm_builder &sel, machine_mode sel_mode,
5527 		       rtx target)
5528 {
5529   if (!target || !register_operand (target, mode))
5530     target = gen_reg_rtx (mode);
5531 
5532   /* Set QIMODE to a different vector mode with byte elements.
5533      If no such mode, or if MODE already has byte elements, use VOIDmode.  */
5534   machine_mode qimode;
5535   if (!qimode_for_vec_perm (mode).exists (&qimode))
5536     qimode = VOIDmode;
5537 
5538   rtx_insn *last = get_last_insn ();
5539 
5540   bool single_arg_p = rtx_equal_p (v0, v1);
5541   /* Always specify two input vectors here and leave the target to handle
5542      cases in which the inputs are equal.  Not all backends can cope with
5543      the single-input representation when testing for a double-input
5544      target instruction.  */
5545   vec_perm_indices indices (sel, 2, GET_MODE_NUNITS (mode));
5546 
5547   /* See if this can be handled with a vec_shr.  We only do this if the
5548      second vector is all zeroes.  */
5549   insn_code shift_code = optab_handler (vec_shr_optab, mode);
5550   insn_code shift_code_qi = ((qimode != VOIDmode && qimode != mode)
5551 			     ? optab_handler (vec_shr_optab, qimode)
5552 			     : CODE_FOR_nothing);
5553 
5554   if (v1 == CONST0_RTX (GET_MODE (v1))
5555       && (shift_code != CODE_FOR_nothing
5556 	  || shift_code_qi != CODE_FOR_nothing))
5557     {
5558       rtx shift_amt = shift_amt_for_vec_perm_mask (mode, indices);
5559       if (shift_amt)
5560 	{
5561 	  struct expand_operand ops[3];
5562 	  if (shift_code != CODE_FOR_nothing)
5563 	    {
5564 	      create_output_operand (&ops[0], target, mode);
5565 	      create_input_operand (&ops[1], v0, mode);
5566 	      create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
5567 	      if (maybe_expand_insn (shift_code, 3, ops))
5568 		return ops[0].value;
5569 	    }
5570 	  if (shift_code_qi != CODE_FOR_nothing)
5571 	    {
5572 	      rtx tmp = gen_reg_rtx (qimode);
5573 	      create_output_operand (&ops[0], tmp, qimode);
5574 	      create_input_operand (&ops[1], gen_lowpart (qimode, v0), qimode);
5575 	      create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
5576 	      if (maybe_expand_insn (shift_code_qi, 3, ops))
5577 		return gen_lowpart (mode, ops[0].value);
5578 	    }
5579 	}
5580     }
5581 
5582   if (targetm.vectorize.vec_perm_const != NULL)
5583     {
5584       v0 = force_reg (mode, v0);
5585       if (single_arg_p)
5586 	v1 = v0;
5587       else
5588 	v1 = force_reg (mode, v1);
5589 
5590       if (targetm.vectorize.vec_perm_const (mode, target, v0, v1, indices))
5591 	return target;
5592     }
5593 
5594   /* Fall back to a constant byte-based permutation.  */
5595   vec_perm_indices qimode_indices;
5596   rtx target_qi = NULL_RTX, v0_qi = NULL_RTX, v1_qi = NULL_RTX;
5597   if (qimode != VOIDmode)
5598     {
5599       qimode_indices.new_expanded_vector (indices, GET_MODE_UNIT_SIZE (mode));
5600       target_qi = gen_reg_rtx (qimode);
5601       v0_qi = gen_lowpart (qimode, v0);
5602       v1_qi = gen_lowpart (qimode, v1);
5603       if (targetm.vectorize.vec_perm_const != NULL
5604 	  && targetm.vectorize.vec_perm_const (qimode, target_qi, v0_qi,
5605 					       v1_qi, qimode_indices))
5606 	return gen_lowpart (mode, target_qi);
5607     }
5608 
5609   /* Otherwise expand as a fully variable permuation.  */
5610 
5611   /* The optabs are only defined for selectors with the same width
5612      as the values being permuted.  */
5613   machine_mode required_sel_mode;
5614   if (!mode_for_int_vector (mode).exists (&required_sel_mode)
5615       || !VECTOR_MODE_P (required_sel_mode))
5616     {
5617       delete_insns_since (last);
5618       return NULL_RTX;
5619     }
5620 
5621   /* We know that it is semantically valid to treat SEL as having SEL_MODE.
5622      If that isn't the mode we want then we need to prove that using
5623      REQUIRED_SEL_MODE is OK.  */
5624   if (sel_mode != required_sel_mode)
5625     {
5626       if (!selector_fits_mode_p (required_sel_mode, indices))
5627 	{
5628 	  delete_insns_since (last);
5629 	  return NULL_RTX;
5630 	}
5631       sel_mode = required_sel_mode;
5632     }
5633 
5634   insn_code icode = direct_optab_handler (vec_perm_optab, mode);
5635   if (icode != CODE_FOR_nothing)
5636     {
5637       rtx sel_rtx = vec_perm_indices_to_rtx (sel_mode, indices);
5638       rtx tmp = expand_vec_perm_1 (icode, target, v0, v1, sel_rtx);
5639       if (tmp)
5640 	return tmp;
5641     }
5642 
5643   if (qimode != VOIDmode
5644       && selector_fits_mode_p (qimode, qimode_indices))
5645     {
5646       icode = direct_optab_handler (vec_perm_optab, qimode);
5647       if (icode != CODE_FOR_nothing)
5648 	{
5649 	  rtx sel_qi = vec_perm_indices_to_rtx (qimode, qimode_indices);
5650 	  rtx tmp = expand_vec_perm_1 (icode, target_qi, v0_qi, v1_qi, sel_qi);
5651 	  if (tmp)
5652 	    return gen_lowpart (mode, tmp);
5653 	}
5654     }
5655 
5656   delete_insns_since (last);
5657   return NULL_RTX;
5658 }
5659 
5660 /* Implement a permutation of vectors v0 and v1 using the permutation
5661    vector in SEL and return the result.  Use TARGET to hold the result
5662    if nonnull and convenient.
5663 
5664    MODE is the mode of the vectors being permuted (V0 and V1).
5665    SEL must have the integer equivalent of MODE and is known to be
5666    unsuitable for permutes with a constant permutation vector.  */
5667 
5668 rtx
5669 expand_vec_perm_var (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
5670 {
5671   enum insn_code icode;
5672   unsigned int i, u;
5673   rtx tmp, sel_qi;
5674 
5675   u = GET_MODE_UNIT_SIZE (mode);
5676 
5677   if (!target || GET_MODE (target) != mode)
5678     target = gen_reg_rtx (mode);
5679 
5680   icode = direct_optab_handler (vec_perm_optab, mode);
5681   if (icode != CODE_FOR_nothing)
5682     {
5683       tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5684       if (tmp)
5685 	return tmp;
5686     }
5687 
5688   /* As a special case to aid several targets, lower the element-based
5689      permutation to a byte-based permutation and try again.  */
5690   machine_mode qimode;
5691   if (!qimode_for_vec_perm (mode).exists (&qimode)
5692       || maybe_gt (GET_MODE_NUNITS (qimode), GET_MODE_MASK (QImode) + 1))
5693     return NULL_RTX;
5694   icode = direct_optab_handler (vec_perm_optab, qimode);
5695   if (icode == CODE_FOR_nothing)
5696     return NULL_RTX;
5697 
5698   /* Multiply each element by its byte size.  */
5699   machine_mode selmode = GET_MODE (sel);
5700   if (u == 2)
5701     sel = expand_simple_binop (selmode, PLUS, sel, sel,
5702 			       NULL, 0, OPTAB_DIRECT);
5703   else
5704     sel = expand_simple_binop (selmode, ASHIFT, sel,
5705 			       gen_int_shift_amount (selmode, exact_log2 (u)),
5706 			       NULL, 0, OPTAB_DIRECT);
5707   gcc_assert (sel != NULL);
5708 
5709   /* Broadcast the low byte each element into each of its bytes.
5710      The encoding has U interleaved stepped patterns, one for each
5711      byte of an element.  */
5712   vec_perm_builder const_sel (GET_MODE_SIZE (mode), u, 3);
5713   unsigned int low_byte_in_u = BYTES_BIG_ENDIAN ? u - 1 : 0;
5714   for (i = 0; i < 3; ++i)
5715     for (unsigned int j = 0; j < u; ++j)
5716       const_sel.quick_push (i * u + low_byte_in_u);
5717   sel = gen_lowpart (qimode, sel);
5718   sel = expand_vec_perm_const (qimode, sel, sel, const_sel, qimode, NULL);
5719   gcc_assert (sel != NULL);
5720 
5721   /* Add the byte offset to each byte element.  */
5722   /* Note that the definition of the indicies here is memory ordering,
5723      so there should be no difference between big and little endian.  */
5724   rtx_vector_builder byte_indices (qimode, u, 1);
5725   for (i = 0; i < u; ++i)
5726     byte_indices.quick_push (GEN_INT (i));
5727   tmp = byte_indices.build ();
5728   sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
5729 				sel, 0, OPTAB_DIRECT);
5730   gcc_assert (sel_qi != NULL);
5731 
5732   tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5733   tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5734 			   gen_lowpart (qimode, v1), sel_qi);
5735   if (tmp)
5736     tmp = gen_lowpart (mode, tmp);
5737   return tmp;
5738 }
5739 
5740 /* Generate insns for a VEC_COND_EXPR with mask, given its TYPE and its
5741    three operands.  */
5742 
5743 rtx
5744 expand_vec_cond_mask_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5745 			   rtx target)
5746 {
5747   struct expand_operand ops[4];
5748   machine_mode mode = TYPE_MODE (vec_cond_type);
5749   machine_mode mask_mode = TYPE_MODE (TREE_TYPE (op0));
5750   enum insn_code icode = get_vcond_mask_icode (mode, mask_mode);
5751   rtx mask, rtx_op1, rtx_op2;
5752 
5753   if (icode == CODE_FOR_nothing)
5754     return 0;
5755 
5756   mask = expand_normal (op0);
5757   rtx_op1 = expand_normal (op1);
5758   rtx_op2 = expand_normal (op2);
5759 
5760   mask = force_reg (mask_mode, mask);
5761   rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
5762 
5763   create_output_operand (&ops[0], target, mode);
5764   create_input_operand (&ops[1], rtx_op1, mode);
5765   create_input_operand (&ops[2], rtx_op2, mode);
5766   create_input_operand (&ops[3], mask, mask_mode);
5767   expand_insn (icode, 4, ops);
5768 
5769   return ops[0].value;
5770 }
5771 
5772 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
5773    three operands.  */
5774 
5775 rtx
5776 expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5777 		      rtx target)
5778 {
5779   struct expand_operand ops[6];
5780   enum insn_code icode;
5781   rtx comparison, rtx_op1, rtx_op2;
5782   machine_mode mode = TYPE_MODE (vec_cond_type);
5783   machine_mode cmp_op_mode;
5784   bool unsignedp;
5785   tree op0a, op0b;
5786   enum tree_code tcode;
5787 
5788   if (COMPARISON_CLASS_P (op0))
5789     {
5790       op0a = TREE_OPERAND (op0, 0);
5791       op0b = TREE_OPERAND (op0, 1);
5792       tcode = TREE_CODE (op0);
5793     }
5794   else
5795     {
5796       gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0)));
5797       if (get_vcond_mask_icode (mode, TYPE_MODE (TREE_TYPE (op0)))
5798 	  != CODE_FOR_nothing)
5799 	return expand_vec_cond_mask_expr (vec_cond_type, op0, op1,
5800 					  op2, target);
5801       /* Fake op0 < 0.  */
5802       else
5803 	{
5804 	  gcc_assert (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (op0)))
5805 		      == MODE_VECTOR_INT);
5806 	  op0a = op0;
5807 	  op0b = build_zero_cst (TREE_TYPE (op0));
5808 	  tcode = LT_EXPR;
5809 	}
5810     }
5811   cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
5812   unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5813 
5814 
5815   gcc_assert (known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (cmp_op_mode))
5816 	      && known_eq (GET_MODE_NUNITS (mode),
5817 			   GET_MODE_NUNITS (cmp_op_mode)));
5818 
5819   icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
5820   if (icode == CODE_FOR_nothing)
5821     {
5822       if (tcode == LT_EXPR
5823 	  && op0a == op0
5824 	  && TREE_CODE (op0) == VECTOR_CST)
5825 	{
5826 	  /* A VEC_COND_EXPR condition could be folded from EQ_EXPR/NE_EXPR
5827 	     into a constant when only get_vcond_eq_icode is supported.
5828 	     Verify < 0 and != 0 behave the same and change it to NE_EXPR.  */
5829 	  unsigned HOST_WIDE_INT nelts;
5830 	  if (!VECTOR_CST_NELTS (op0).is_constant (&nelts))
5831 	    {
5832 	      if (VECTOR_CST_STEPPED_P (op0))
5833 		return 0;
5834 	      nelts = vector_cst_encoded_nelts (op0);
5835 	    }
5836 	  for (unsigned int i = 0; i < nelts; ++i)
5837 	    if (tree_int_cst_sgn (vector_cst_elt (op0, i)) == 1)
5838 	      return 0;
5839 	  tcode = NE_EXPR;
5840 	}
5841       if (tcode == EQ_EXPR || tcode == NE_EXPR)
5842 	icode = get_vcond_eq_icode (mode, cmp_op_mode);
5843       if (icode == CODE_FOR_nothing)
5844 	return 0;
5845     }
5846 
5847   comparison = vector_compare_rtx (VOIDmode, tcode, op0a, op0b, unsignedp,
5848 				   icode, 4);
5849   rtx_op1 = expand_normal (op1);
5850   rtx_op2 = expand_normal (op2);
5851 
5852   create_output_operand (&ops[0], target, mode);
5853   create_input_operand (&ops[1], rtx_op1, mode);
5854   create_input_operand (&ops[2], rtx_op2, mode);
5855   create_fixed_operand (&ops[3], comparison);
5856   create_fixed_operand (&ops[4], XEXP (comparison, 0));
5857   create_fixed_operand (&ops[5], XEXP (comparison, 1));
5858   expand_insn (icode, 6, ops);
5859   return ops[0].value;
5860 }
5861 
5862 /* Generate VEC_SERIES_EXPR <OP0, OP1>, returning a value of mode VMODE.
5863    Use TARGET for the result if nonnull and convenient.  */
5864 
5865 rtx
5866 expand_vec_series_expr (machine_mode vmode, rtx op0, rtx op1, rtx target)
5867 {
5868   struct expand_operand ops[3];
5869   enum insn_code icode;
5870   machine_mode emode = GET_MODE_INNER (vmode);
5871 
5872   icode = direct_optab_handler (vec_series_optab, vmode);
5873   gcc_assert (icode != CODE_FOR_nothing);
5874 
5875   create_output_operand (&ops[0], target, vmode);
5876   create_input_operand (&ops[1], op0, emode);
5877   create_input_operand (&ops[2], op1, emode);
5878 
5879   expand_insn (icode, 3, ops);
5880   return ops[0].value;
5881 }
5882 
5883 /* Generate insns for a vector comparison into a mask.  */
5884 
5885 rtx
5886 expand_vec_cmp_expr (tree type, tree exp, rtx target)
5887 {
5888   struct expand_operand ops[4];
5889   enum insn_code icode;
5890   rtx comparison;
5891   machine_mode mask_mode = TYPE_MODE (type);
5892   machine_mode vmode;
5893   bool unsignedp;
5894   tree op0a, op0b;
5895   enum tree_code tcode;
5896 
5897   op0a = TREE_OPERAND (exp, 0);
5898   op0b = TREE_OPERAND (exp, 1);
5899   tcode = TREE_CODE (exp);
5900 
5901   unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5902   vmode = TYPE_MODE (TREE_TYPE (op0a));
5903 
5904   icode = get_vec_cmp_icode (vmode, mask_mode, unsignedp);
5905   if (icode == CODE_FOR_nothing)
5906     {
5907       if (tcode == EQ_EXPR || tcode == NE_EXPR)
5908 	icode = get_vec_cmp_eq_icode (vmode, mask_mode);
5909       if (icode == CODE_FOR_nothing)
5910 	return 0;
5911     }
5912 
5913   comparison = vector_compare_rtx (mask_mode, tcode, op0a, op0b,
5914 				   unsignedp, icode, 2);
5915   create_output_operand (&ops[0], target, mask_mode);
5916   create_fixed_operand (&ops[1], comparison);
5917   create_fixed_operand (&ops[2], XEXP (comparison, 0));
5918   create_fixed_operand (&ops[3], XEXP (comparison, 1));
5919   expand_insn (icode, 4, ops);
5920   return ops[0].value;
5921 }
5922 
5923 /* Expand a highpart multiply.  */
5924 
5925 rtx
5926 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
5927 		      rtx target, bool uns_p)
5928 {
5929   struct expand_operand eops[3];
5930   enum insn_code icode;
5931   int method, i;
5932   machine_mode wmode;
5933   rtx m1, m2;
5934   optab tab1, tab2;
5935 
5936   method = can_mult_highpart_p (mode, uns_p);
5937   switch (method)
5938     {
5939     case 0:
5940       return NULL_RTX;
5941     case 1:
5942       tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
5943       return expand_binop (mode, tab1, op0, op1, target, uns_p,
5944 			   OPTAB_LIB_WIDEN);
5945     case 2:
5946       tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
5947       tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
5948       break;
5949     case 3:
5950       tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
5951       tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
5952       if (BYTES_BIG_ENDIAN)
5953 	std::swap (tab1, tab2);
5954       break;
5955     default:
5956       gcc_unreachable ();
5957     }
5958 
5959   icode = optab_handler (tab1, mode);
5960   wmode = insn_data[icode].operand[0].mode;
5961   gcc_checking_assert (known_eq (2 * GET_MODE_NUNITS (wmode),
5962 				 GET_MODE_NUNITS (mode)));
5963   gcc_checking_assert (known_eq (GET_MODE_SIZE (wmode), GET_MODE_SIZE (mode)));
5964 
5965   create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5966   create_input_operand (&eops[1], op0, mode);
5967   create_input_operand (&eops[2], op1, mode);
5968   expand_insn (icode, 3, eops);
5969   m1 = gen_lowpart (mode, eops[0].value);
5970 
5971   create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5972   create_input_operand (&eops[1], op0, mode);
5973   create_input_operand (&eops[2], op1, mode);
5974   expand_insn (optab_handler (tab2, mode), 3, eops);
5975   m2 = gen_lowpart (mode, eops[0].value);
5976 
5977   vec_perm_builder sel;
5978   if (method == 2)
5979     {
5980       /* The encoding has 2 interleaved stepped patterns.  */
5981       sel.new_vector (GET_MODE_NUNITS (mode), 2, 3);
5982       for (i = 0; i < 6; ++i)
5983 	sel.quick_push (!BYTES_BIG_ENDIAN + (i & ~1)
5984 			+ ((i & 1) ? GET_MODE_NUNITS (mode) : 0));
5985     }
5986   else
5987     {
5988       /* The encoding has a single interleaved stepped pattern.  */
5989       sel.new_vector (GET_MODE_NUNITS (mode), 1, 3);
5990       for (i = 0; i < 3; ++i)
5991 	sel.quick_push (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
5992     }
5993 
5994   return expand_vec_perm_const (mode, m1, m2, sel, BLKmode, target);
5995 }
5996 
5997 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
5998    pattern.  */
5999 
6000 static void
6001 find_cc_set (rtx x, const_rtx pat, void *data)
6002 {
6003   if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
6004       && GET_CODE (pat) == SET)
6005     {
6006       rtx *p_cc_reg = (rtx *) data;
6007       gcc_assert (!*p_cc_reg);
6008       *p_cc_reg = x;
6009     }
6010 }
6011 
6012 /* This is a helper function for the other atomic operations.  This function
6013    emits a loop that contains SEQ that iterates until a compare-and-swap
6014    operation at the end succeeds.  MEM is the memory to be modified.  SEQ is
6015    a set of instructions that takes a value from OLD_REG as an input and
6016    produces a value in NEW_REG as an output.  Before SEQ, OLD_REG will be
6017    set to the current contents of MEM.  After SEQ, a compare-and-swap will
6018    attempt to update MEM with NEW_REG.  The function returns true when the
6019    loop was generated successfully.  */
6020 
6021 static bool
6022 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
6023 {
6024   machine_mode mode = GET_MODE (mem);
6025   rtx_code_label *label;
6026   rtx cmp_reg, success, oldval;
6027 
6028   /* The loop we want to generate looks like
6029 
6030 	cmp_reg = mem;
6031       label:
6032         old_reg = cmp_reg;
6033 	seq;
6034 	(success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
6035 	if (success)
6036 	  goto label;
6037 
6038      Note that we only do the plain load from memory once.  Subsequent
6039      iterations use the value loaded by the compare-and-swap pattern.  */
6040 
6041   label = gen_label_rtx ();
6042   cmp_reg = gen_reg_rtx (mode);
6043 
6044   emit_move_insn (cmp_reg, mem);
6045   emit_label (label);
6046   emit_move_insn (old_reg, cmp_reg);
6047   if (seq)
6048     emit_insn (seq);
6049 
6050   success = NULL_RTX;
6051   oldval = cmp_reg;
6052   if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
6053 				       new_reg, false, MEMMODEL_SYNC_SEQ_CST,
6054 				       MEMMODEL_RELAXED))
6055     return false;
6056 
6057   if (oldval != cmp_reg)
6058     emit_move_insn (cmp_reg, oldval);
6059 
6060   /* Mark this jump predicted not taken.  */
6061   emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
6062 			   GET_MODE (success), 1, label,
6063 			   profile_probability::guessed_never ());
6064   return true;
6065 }
6066 
6067 
6068 /* This function tries to emit an atomic_exchange intruction.  VAL is written
6069    to *MEM using memory model MODEL. The previous contents of *MEM are returned,
6070    using TARGET if possible.  */
6071 
6072 static rtx
6073 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6074 {
6075   machine_mode mode = GET_MODE (mem);
6076   enum insn_code icode;
6077 
6078   /* If the target supports the exchange directly, great.  */
6079   icode = direct_optab_handler (atomic_exchange_optab, mode);
6080   if (icode != CODE_FOR_nothing)
6081     {
6082       struct expand_operand ops[4];
6083 
6084       create_output_operand (&ops[0], target, mode);
6085       create_fixed_operand (&ops[1], mem);
6086       create_input_operand (&ops[2], val, mode);
6087       create_integer_operand (&ops[3], model);
6088       if (maybe_expand_insn (icode, 4, ops))
6089 	return ops[0].value;
6090     }
6091 
6092   return NULL_RTX;
6093 }
6094 
6095 /* This function tries to implement an atomic exchange operation using
6096    __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
6097    The previous contents of *MEM are returned, using TARGET if possible.
6098    Since this instructionn is an acquire barrier only, stronger memory
6099    models may require additional barriers to be emitted.  */
6100 
6101 static rtx
6102 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
6103 				   enum memmodel model)
6104 {
6105   machine_mode mode = GET_MODE (mem);
6106   enum insn_code icode;
6107   rtx_insn *last_insn = get_last_insn ();
6108 
6109   icode = optab_handler (sync_lock_test_and_set_optab, mode);
6110 
6111   /* Legacy sync_lock_test_and_set is an acquire barrier.  If the pattern
6112      exists, and the memory model is stronger than acquire, add a release
6113      barrier before the instruction.  */
6114 
6115   if (is_mm_seq_cst (model) || is_mm_release (model) || is_mm_acq_rel (model))
6116     expand_mem_thread_fence (model);
6117 
6118   if (icode != CODE_FOR_nothing)
6119     {
6120       struct expand_operand ops[3];
6121       create_output_operand (&ops[0], target, mode);
6122       create_fixed_operand (&ops[1], mem);
6123       create_input_operand (&ops[2], val, mode);
6124       if (maybe_expand_insn (icode, 3, ops))
6125 	return ops[0].value;
6126     }
6127 
6128   /* If an external test-and-set libcall is provided, use that instead of
6129      any external compare-and-swap that we might get from the compare-and-
6130      swap-loop expansion later.  */
6131   if (!can_compare_and_swap_p (mode, false))
6132     {
6133       rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
6134       if (libfunc != NULL)
6135 	{
6136 	  rtx addr;
6137 
6138 	  addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6139 	  return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6140 					  mode, addr, ptr_mode,
6141 					  val, mode);
6142 	}
6143     }
6144 
6145   /* If the test_and_set can't be emitted, eliminate any barrier that might
6146      have been emitted.  */
6147   delete_insns_since (last_insn);
6148   return NULL_RTX;
6149 }
6150 
6151 /* This function tries to implement an atomic exchange operation using a
6152    compare_and_swap loop. VAL is written to *MEM.  The previous contents of
6153    *MEM are returned, using TARGET if possible.  No memory model is required
6154    since a compare_and_swap loop is seq-cst.  */
6155 
6156 static rtx
6157 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
6158 {
6159   machine_mode mode = GET_MODE (mem);
6160 
6161   if (can_compare_and_swap_p (mode, true))
6162     {
6163       if (!target || !register_operand (target, mode))
6164 	target = gen_reg_rtx (mode);
6165       if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6166 	return target;
6167     }
6168 
6169   return NULL_RTX;
6170 }
6171 
6172 /* This function tries to implement an atomic test-and-set operation
6173    using the atomic_test_and_set instruction pattern.  A boolean value
6174    is returned from the operation, using TARGET if possible.  */
6175 
6176 static rtx
6177 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
6178 {
6179   machine_mode pat_bool_mode;
6180   struct expand_operand ops[3];
6181 
6182   if (!targetm.have_atomic_test_and_set ())
6183     return NULL_RTX;
6184 
6185   /* While we always get QImode from __atomic_test_and_set, we get
6186      other memory modes from __sync_lock_test_and_set.  Note that we
6187      use no endian adjustment here.  This matches the 4.6 behavior
6188      in the Sparc backend.  */
6189   enum insn_code icode = targetm.code_for_atomic_test_and_set;
6190   gcc_checking_assert (insn_data[icode].operand[1].mode == QImode);
6191   if (GET_MODE (mem) != QImode)
6192     mem = adjust_address_nv (mem, QImode, 0);
6193 
6194   pat_bool_mode = insn_data[icode].operand[0].mode;
6195   create_output_operand (&ops[0], target, pat_bool_mode);
6196   create_fixed_operand (&ops[1], mem);
6197   create_integer_operand (&ops[2], model);
6198 
6199   if (maybe_expand_insn (icode, 3, ops))
6200     return ops[0].value;
6201   return NULL_RTX;
6202 }
6203 
6204 /* This function expands the legacy _sync_lock test_and_set operation which is
6205    generally an atomic exchange.  Some limited targets only allow the
6206    constant 1 to be stored.  This is an ACQUIRE operation.
6207 
6208    TARGET is an optional place to stick the return value.
6209    MEM is where VAL is stored.  */
6210 
6211 rtx
6212 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
6213 {
6214   rtx ret;
6215 
6216   /* Try an atomic_exchange first.  */
6217   ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_SYNC_ACQUIRE);
6218   if (ret)
6219     return ret;
6220 
6221   ret = maybe_emit_sync_lock_test_and_set (target, mem, val,
6222 					   MEMMODEL_SYNC_ACQUIRE);
6223   if (ret)
6224     return ret;
6225 
6226   ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6227   if (ret)
6228     return ret;
6229 
6230   /* If there are no other options, try atomic_test_and_set if the value
6231      being stored is 1.  */
6232   if (val == const1_rtx)
6233     ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_SYNC_ACQUIRE);
6234 
6235   return ret;
6236 }
6237 
6238 /* This function expands the atomic test_and_set operation:
6239    atomically store a boolean TRUE into MEM and return the previous value.
6240 
6241    MEMMODEL is the memory model variant to use.
6242    TARGET is an optional place to stick the return value.  */
6243 
6244 rtx
6245 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
6246 {
6247   machine_mode mode = GET_MODE (mem);
6248   rtx ret, trueval, subtarget;
6249 
6250   ret = maybe_emit_atomic_test_and_set (target, mem, model);
6251   if (ret)
6252     return ret;
6253 
6254   /* Be binary compatible with non-default settings of trueval, and different
6255      cpu revisions.  E.g. one revision may have atomic-test-and-set, but
6256      another only has atomic-exchange.  */
6257   if (targetm.atomic_test_and_set_trueval == 1)
6258     {
6259       trueval = const1_rtx;
6260       subtarget = target ? target : gen_reg_rtx (mode);
6261     }
6262   else
6263     {
6264       trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
6265       subtarget = gen_reg_rtx (mode);
6266     }
6267 
6268   /* Try the atomic-exchange optab...  */
6269   ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
6270 
6271   /* ... then an atomic-compare-and-swap loop ... */
6272   if (!ret)
6273     ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
6274 
6275   /* ... before trying the vaguely defined legacy lock_test_and_set. */
6276   if (!ret)
6277     ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
6278 
6279   /* Recall that the legacy lock_test_and_set optab was allowed to do magic
6280      things with the value 1.  Thus we try again without trueval.  */
6281   if (!ret && targetm.atomic_test_and_set_trueval != 1)
6282     ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
6283 
6284   /* Failing all else, assume a single threaded environment and simply
6285      perform the operation.  */
6286   if (!ret)
6287     {
6288       /* If the result is ignored skip the move to target.  */
6289       if (subtarget != const0_rtx)
6290         emit_move_insn (subtarget, mem);
6291 
6292       emit_move_insn (mem, trueval);
6293       ret = subtarget;
6294     }
6295 
6296   /* Recall that have to return a boolean value; rectify if trueval
6297      is not exactly one.  */
6298   if (targetm.atomic_test_and_set_trueval != 1)
6299     ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
6300 
6301   return ret;
6302 }
6303 
6304 /* This function expands the atomic exchange operation:
6305    atomically store VAL in MEM and return the previous value in MEM.
6306 
6307    MEMMODEL is the memory model variant to use.
6308    TARGET is an optional place to stick the return value.  */
6309 
6310 rtx
6311 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6312 {
6313   machine_mode mode = GET_MODE (mem);
6314   rtx ret;
6315 
6316   /* If loads are not atomic for the required size and we are not called to
6317      provide a __sync builtin, do not do anything so that we stay consistent
6318      with atomic loads of the same size.  */
6319   if (!can_atomic_load_p (mode) && !is_mm_sync (model))
6320     return NULL_RTX;
6321 
6322   ret = maybe_emit_atomic_exchange (target, mem, val, model);
6323 
6324   /* Next try a compare-and-swap loop for the exchange.  */
6325   if (!ret)
6326     ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6327 
6328   return ret;
6329 }
6330 
6331 /* This function expands the atomic compare exchange operation:
6332 
6333    *PTARGET_BOOL is an optional place to store the boolean success/failure.
6334    *PTARGET_OVAL is an optional place to store the old value from memory.
6335    Both target parameters may be NULL or const0_rtx to indicate that we do
6336    not care about that return value.  Both target parameters are updated on
6337    success to the actual location of the corresponding result.
6338 
6339    MEMMODEL is the memory model variant to use.
6340 
6341    The return value of the function is true for success.  */
6342 
6343 bool
6344 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
6345 				rtx mem, rtx expected, rtx desired,
6346 				bool is_weak, enum memmodel succ_model,
6347 				enum memmodel fail_model)
6348 {
6349   machine_mode mode = GET_MODE (mem);
6350   struct expand_operand ops[8];
6351   enum insn_code icode;
6352   rtx target_oval, target_bool = NULL_RTX;
6353   rtx libfunc;
6354 
6355   /* If loads are not atomic for the required size and we are not called to
6356      provide a __sync builtin, do not do anything so that we stay consistent
6357      with atomic loads of the same size.  */
6358   if (!can_atomic_load_p (mode) && !is_mm_sync (succ_model))
6359     return false;
6360 
6361   /* Load expected into a register for the compare and swap.  */
6362   if (MEM_P (expected))
6363     expected = copy_to_reg (expected);
6364 
6365   /* Make sure we always have some place to put the return oldval.
6366      Further, make sure that place is distinct from the input expected,
6367      just in case we need that path down below.  */
6368   if (ptarget_oval && *ptarget_oval == const0_rtx)
6369     ptarget_oval = NULL;
6370 
6371   if (ptarget_oval == NULL
6372       || (target_oval = *ptarget_oval) == NULL
6373       || reg_overlap_mentioned_p (expected, target_oval))
6374     target_oval = gen_reg_rtx (mode);
6375 
6376   icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
6377   if (icode != CODE_FOR_nothing)
6378     {
6379       machine_mode bool_mode = insn_data[icode].operand[0].mode;
6380 
6381       if (ptarget_bool && *ptarget_bool == const0_rtx)
6382 	ptarget_bool = NULL;
6383 
6384       /* Make sure we always have a place for the bool operand.  */
6385       if (ptarget_bool == NULL
6386 	  || (target_bool = *ptarget_bool) == NULL
6387 	  || GET_MODE (target_bool) != bool_mode)
6388 	target_bool = gen_reg_rtx (bool_mode);
6389 
6390       /* Emit the compare_and_swap.  */
6391       create_output_operand (&ops[0], target_bool, bool_mode);
6392       create_output_operand (&ops[1], target_oval, mode);
6393       create_fixed_operand (&ops[2], mem);
6394       create_input_operand (&ops[3], expected, mode);
6395       create_input_operand (&ops[4], desired, mode);
6396       create_integer_operand (&ops[5], is_weak);
6397       create_integer_operand (&ops[6], succ_model);
6398       create_integer_operand (&ops[7], fail_model);
6399       if (maybe_expand_insn (icode, 8, ops))
6400 	{
6401 	  /* Return success/failure.  */
6402 	  target_bool = ops[0].value;
6403 	  target_oval = ops[1].value;
6404 	  goto success;
6405 	}
6406     }
6407 
6408   /* Otherwise fall back to the original __sync_val_compare_and_swap
6409      which is always seq-cst.  */
6410   icode = optab_handler (sync_compare_and_swap_optab, mode);
6411   if (icode != CODE_FOR_nothing)
6412     {
6413       rtx cc_reg;
6414 
6415       create_output_operand (&ops[0], target_oval, mode);
6416       create_fixed_operand (&ops[1], mem);
6417       create_input_operand (&ops[2], expected, mode);
6418       create_input_operand (&ops[3], desired, mode);
6419       if (!maybe_expand_insn (icode, 4, ops))
6420 	return false;
6421 
6422       target_oval = ops[0].value;
6423 
6424       /* If the caller isn't interested in the boolean return value,
6425 	 skip the computation of it.  */
6426       if (ptarget_bool == NULL)
6427 	goto success;
6428 
6429       /* Otherwise, work out if the compare-and-swap succeeded.  */
6430       cc_reg = NULL_RTX;
6431       if (have_insn_for (COMPARE, CCmode))
6432 	note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
6433       if (cc_reg)
6434 	{
6435 	  target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
6436 					       const0_rtx, VOIDmode, 0, 1);
6437 	  goto success;
6438 	}
6439       goto success_bool_from_val;
6440     }
6441 
6442   /* Also check for library support for __sync_val_compare_and_swap.  */
6443   libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
6444   if (libfunc != NULL)
6445     {
6446       rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6447       rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6448 					    mode, addr, ptr_mode,
6449 					    expected, mode, desired, mode);
6450       emit_move_insn (target_oval, target);
6451 
6452       /* Compute the boolean return value only if requested.  */
6453       if (ptarget_bool)
6454 	goto success_bool_from_val;
6455       else
6456 	goto success;
6457     }
6458 
6459   /* Failure.  */
6460   return false;
6461 
6462  success_bool_from_val:
6463    target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
6464 					expected, VOIDmode, 1, 1);
6465  success:
6466   /* Make sure that the oval output winds up where the caller asked.  */
6467   if (ptarget_oval)
6468     *ptarget_oval = target_oval;
6469   if (ptarget_bool)
6470     *ptarget_bool = target_bool;
6471   return true;
6472 }
6473 
6474 /* Generate asm volatile("" : : : "memory") as the memory blockage.  */
6475 
6476 static void
6477 expand_asm_memory_blockage (void)
6478 {
6479   rtx asm_op, clob;
6480 
6481   asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
6482 				 rtvec_alloc (0), rtvec_alloc (0),
6483 				 rtvec_alloc (0), UNKNOWN_LOCATION);
6484   MEM_VOLATILE_P (asm_op) = 1;
6485 
6486   clob = gen_rtx_SCRATCH (VOIDmode);
6487   clob = gen_rtx_MEM (BLKmode, clob);
6488   clob = gen_rtx_CLOBBER (VOIDmode, clob);
6489 
6490   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
6491 }
6492 
6493 /* Do not propagate memory accesses across this point.  */
6494 
6495 static void
6496 expand_memory_blockage (void)
6497 {
6498   if (targetm.have_memory_blockage ())
6499     emit_insn (targetm.gen_memory_blockage ());
6500   else
6501     expand_asm_memory_blockage ();
6502 }
6503 
6504 /* This routine will either emit the mem_thread_fence pattern or issue a
6505    sync_synchronize to generate a fence for memory model MEMMODEL.  */
6506 
6507 void
6508 expand_mem_thread_fence (enum memmodel model)
6509 {
6510   if (is_mm_relaxed (model))
6511     return;
6512   if (targetm.have_mem_thread_fence ())
6513     {
6514       emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
6515       expand_memory_blockage ();
6516     }
6517   else if (targetm.have_memory_barrier ())
6518     emit_insn (targetm.gen_memory_barrier ());
6519   else if (synchronize_libfunc != NULL_RTX)
6520     emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode);
6521   else
6522     expand_memory_blockage ();
6523 }
6524 
6525 /* Emit a signal fence with given memory model.  */
6526 
6527 void
6528 expand_mem_signal_fence (enum memmodel model)
6529 {
6530   /* No machine barrier is required to implement a signal fence, but
6531      a compiler memory barrier must be issued, except for relaxed MM.  */
6532   if (!is_mm_relaxed (model))
6533     expand_memory_blockage ();
6534 }
6535 
6536 /* This function expands the atomic load operation:
6537    return the atomically loaded value in MEM.
6538 
6539    MEMMODEL is the memory model variant to use.
6540    TARGET is an option place to stick the return value.  */
6541 
6542 rtx
6543 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
6544 {
6545   machine_mode mode = GET_MODE (mem);
6546   enum insn_code icode;
6547 
6548   /* If the target supports the load directly, great.  */
6549   icode = direct_optab_handler (atomic_load_optab, mode);
6550   if (icode != CODE_FOR_nothing)
6551     {
6552       struct expand_operand ops[3];
6553       rtx_insn *last = get_last_insn ();
6554       if (is_mm_seq_cst (model))
6555 	expand_memory_blockage ();
6556 
6557       create_output_operand (&ops[0], target, mode);
6558       create_fixed_operand (&ops[1], mem);
6559       create_integer_operand (&ops[2], model);
6560       if (maybe_expand_insn (icode, 3, ops))
6561 	{
6562 	  if (!is_mm_relaxed (model))
6563 	    expand_memory_blockage ();
6564 	  return ops[0].value;
6565 	}
6566       delete_insns_since (last);
6567     }
6568 
6569   /* If the size of the object is greater than word size on this target,
6570      then we assume that a load will not be atomic.  We could try to
6571      emulate a load with a compare-and-swap operation, but the store that
6572      doing this could result in would be incorrect if this is a volatile
6573      atomic load or targetting read-only-mapped memory.  */
6574   if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
6575     /* If there is no atomic load, leave the library call.  */
6576     return NULL_RTX;
6577 
6578   /* Otherwise assume loads are atomic, and emit the proper barriers.  */
6579   if (!target || target == const0_rtx)
6580     target = gen_reg_rtx (mode);
6581 
6582   /* For SEQ_CST, emit a barrier before the load.  */
6583   if (is_mm_seq_cst (model))
6584     expand_mem_thread_fence (model);
6585 
6586   emit_move_insn (target, mem);
6587 
6588   /* Emit the appropriate barrier after the load.  */
6589   expand_mem_thread_fence (model);
6590 
6591   return target;
6592 }
6593 
6594 /* This function expands the atomic store operation:
6595    Atomically store VAL in MEM.
6596    MEMMODEL is the memory model variant to use.
6597    USE_RELEASE is true if __sync_lock_release can be used as a fall back.
6598    function returns const0_rtx if a pattern was emitted.  */
6599 
6600 rtx
6601 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
6602 {
6603   machine_mode mode = GET_MODE (mem);
6604   enum insn_code icode;
6605   struct expand_operand ops[3];
6606 
6607   /* If the target supports the store directly, great.  */
6608   icode = direct_optab_handler (atomic_store_optab, mode);
6609   if (icode != CODE_FOR_nothing)
6610     {
6611       rtx_insn *last = get_last_insn ();
6612       if (!is_mm_relaxed (model))
6613 	expand_memory_blockage ();
6614       create_fixed_operand (&ops[0], mem);
6615       create_input_operand (&ops[1], val, mode);
6616       create_integer_operand (&ops[2], model);
6617       if (maybe_expand_insn (icode, 3, ops))
6618 	{
6619 	  if (is_mm_seq_cst (model))
6620 	    expand_memory_blockage ();
6621 	  return const0_rtx;
6622 	}
6623       delete_insns_since (last);
6624     }
6625 
6626   /* If using __sync_lock_release is a viable alternative, try it.
6627      Note that this will not be set to true if we are expanding a generic
6628      __atomic_store_n.  */
6629   if (use_release)
6630     {
6631       icode = direct_optab_handler (sync_lock_release_optab, mode);
6632       if (icode != CODE_FOR_nothing)
6633 	{
6634 	  create_fixed_operand (&ops[0], mem);
6635 	  create_input_operand (&ops[1], const0_rtx, mode);
6636 	  if (maybe_expand_insn (icode, 2, ops))
6637 	    {
6638 	      /* lock_release is only a release barrier.  */
6639 	      if (is_mm_seq_cst (model))
6640 		expand_mem_thread_fence (model);
6641 	      return const0_rtx;
6642 	    }
6643 	}
6644     }
6645 
6646   /* If the size of the object is greater than word size on this target,
6647      a default store will not be atomic.  */
6648   if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
6649     {
6650       /* If loads are atomic or we are called to provide a __sync builtin,
6651 	 we can try a atomic_exchange and throw away the result.  Otherwise,
6652 	 don't do anything so that we do not create an inconsistency between
6653 	 loads and stores.  */
6654       if (can_atomic_load_p (mode) || is_mm_sync (model))
6655 	{
6656 	  rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
6657 	  if (!target)
6658 	    target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem,
6659 								val);
6660 	  if (target)
6661 	    return const0_rtx;
6662 	}
6663         return NULL_RTX;
6664     }
6665 
6666   /* Otherwise assume stores are atomic, and emit the proper barriers.  */
6667   expand_mem_thread_fence (model);
6668 
6669   emit_move_insn (mem, val);
6670 
6671   /* For SEQ_CST, also emit a barrier after the store.  */
6672   if (is_mm_seq_cst (model))
6673     expand_mem_thread_fence (model);
6674 
6675   return const0_rtx;
6676 }
6677 
6678 
6679 /* Structure containing the pointers and values required to process the
6680    various forms of the atomic_fetch_op and atomic_op_fetch builtins.  */
6681 
6682 struct atomic_op_functions
6683 {
6684   direct_optab mem_fetch_before;
6685   direct_optab mem_fetch_after;
6686   direct_optab mem_no_result;
6687   optab fetch_before;
6688   optab fetch_after;
6689   direct_optab no_result;
6690   enum rtx_code reverse_code;
6691 };
6692 
6693 
6694 /* Fill in structure pointed to by OP with the various optab entries for an
6695    operation of type CODE.  */
6696 
6697 static void
6698 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
6699 {
6700   gcc_assert (op!= NULL);
6701 
6702   /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
6703      in the source code during compilation, and the optab entries are not
6704      computable until runtime.  Fill in the values at runtime.  */
6705   switch (code)
6706     {
6707     case PLUS:
6708       op->mem_fetch_before = atomic_fetch_add_optab;
6709       op->mem_fetch_after = atomic_add_fetch_optab;
6710       op->mem_no_result = atomic_add_optab;
6711       op->fetch_before = sync_old_add_optab;
6712       op->fetch_after = sync_new_add_optab;
6713       op->no_result = sync_add_optab;
6714       op->reverse_code = MINUS;
6715       break;
6716     case MINUS:
6717       op->mem_fetch_before = atomic_fetch_sub_optab;
6718       op->mem_fetch_after = atomic_sub_fetch_optab;
6719       op->mem_no_result = atomic_sub_optab;
6720       op->fetch_before = sync_old_sub_optab;
6721       op->fetch_after = sync_new_sub_optab;
6722       op->no_result = sync_sub_optab;
6723       op->reverse_code = PLUS;
6724       break;
6725     case XOR:
6726       op->mem_fetch_before = atomic_fetch_xor_optab;
6727       op->mem_fetch_after = atomic_xor_fetch_optab;
6728       op->mem_no_result = atomic_xor_optab;
6729       op->fetch_before = sync_old_xor_optab;
6730       op->fetch_after = sync_new_xor_optab;
6731       op->no_result = sync_xor_optab;
6732       op->reverse_code = XOR;
6733       break;
6734     case AND:
6735       op->mem_fetch_before = atomic_fetch_and_optab;
6736       op->mem_fetch_after = atomic_and_fetch_optab;
6737       op->mem_no_result = atomic_and_optab;
6738       op->fetch_before = sync_old_and_optab;
6739       op->fetch_after = sync_new_and_optab;
6740       op->no_result = sync_and_optab;
6741       op->reverse_code = UNKNOWN;
6742       break;
6743     case IOR:
6744       op->mem_fetch_before = atomic_fetch_or_optab;
6745       op->mem_fetch_after = atomic_or_fetch_optab;
6746       op->mem_no_result = atomic_or_optab;
6747       op->fetch_before = sync_old_ior_optab;
6748       op->fetch_after = sync_new_ior_optab;
6749       op->no_result = sync_ior_optab;
6750       op->reverse_code = UNKNOWN;
6751       break;
6752     case NOT:
6753       op->mem_fetch_before = atomic_fetch_nand_optab;
6754       op->mem_fetch_after = atomic_nand_fetch_optab;
6755       op->mem_no_result = atomic_nand_optab;
6756       op->fetch_before = sync_old_nand_optab;
6757       op->fetch_after = sync_new_nand_optab;
6758       op->no_result = sync_nand_optab;
6759       op->reverse_code = UNKNOWN;
6760       break;
6761     default:
6762       gcc_unreachable ();
6763     }
6764 }
6765 
6766 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
6767    using memory order MODEL.  If AFTER is true the operation needs to return
6768    the value of *MEM after the operation, otherwise the previous value.
6769    TARGET is an optional place to place the result.  The result is unused if
6770    it is const0_rtx.
6771    Return the result if there is a better sequence, otherwise NULL_RTX.  */
6772 
6773 static rtx
6774 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6775 			 enum memmodel model, bool after)
6776 {
6777   /* If the value is prefetched, or not used, it may be possible to replace
6778      the sequence with a native exchange operation.  */
6779   if (!after || target == const0_rtx)
6780     {
6781       /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m).  */
6782       if (code == AND && val == const0_rtx)
6783         {
6784 	  if (target == const0_rtx)
6785 	    target = gen_reg_rtx (GET_MODE (mem));
6786 	  return maybe_emit_atomic_exchange (target, mem, val, model);
6787 	}
6788 
6789       /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m).  */
6790       if (code == IOR && val == constm1_rtx)
6791         {
6792 	  if (target == const0_rtx)
6793 	    target = gen_reg_rtx (GET_MODE (mem));
6794 	  return maybe_emit_atomic_exchange (target, mem, val, model);
6795 	}
6796     }
6797 
6798   return NULL_RTX;
6799 }
6800 
6801 /* Try to emit an instruction for a specific operation varaition.
6802    OPTAB contains the OP functions.
6803    TARGET is an optional place to return the result. const0_rtx means unused.
6804    MEM is the memory location to operate on.
6805    VAL is the value to use in the operation.
6806    USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
6807    MODEL is the memory model, if used.
6808    AFTER is true if the returned result is the value after the operation.  */
6809 
6810 static rtx
6811 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
6812 	       rtx val, bool use_memmodel, enum memmodel model, bool after)
6813 {
6814   machine_mode mode = GET_MODE (mem);
6815   struct expand_operand ops[4];
6816   enum insn_code icode;
6817   int op_counter = 0;
6818   int num_ops;
6819 
6820   /* Check to see if there is a result returned.  */
6821   if (target == const0_rtx)
6822     {
6823       if (use_memmodel)
6824         {
6825 	  icode = direct_optab_handler (optab->mem_no_result, mode);
6826 	  create_integer_operand (&ops[2], model);
6827 	  num_ops = 3;
6828 	}
6829       else
6830         {
6831 	  icode = direct_optab_handler (optab->no_result, mode);
6832 	  num_ops = 2;
6833 	}
6834     }
6835   /* Otherwise, we need to generate a result.  */
6836   else
6837     {
6838       if (use_memmodel)
6839         {
6840 	  icode = direct_optab_handler (after ? optab->mem_fetch_after
6841 					: optab->mem_fetch_before, mode);
6842 	  create_integer_operand (&ops[3], model);
6843 	  num_ops = 4;
6844 	}
6845       else
6846 	{
6847 	  icode = optab_handler (after ? optab->fetch_after
6848 				 : optab->fetch_before, mode);
6849 	  num_ops = 3;
6850 	}
6851       create_output_operand (&ops[op_counter++], target, mode);
6852     }
6853   if (icode == CODE_FOR_nothing)
6854     return NULL_RTX;
6855 
6856   create_fixed_operand (&ops[op_counter++], mem);
6857   /* VAL may have been promoted to a wider mode.  Shrink it if so.  */
6858   create_convert_operand_to (&ops[op_counter++], val, mode, true);
6859 
6860   if (maybe_expand_insn (icode, num_ops, ops))
6861     return (target == const0_rtx ? const0_rtx : ops[0].value);
6862 
6863   return NULL_RTX;
6864 }
6865 
6866 
6867 /* This function expands an atomic fetch_OP or OP_fetch operation:
6868    TARGET is an option place to stick the return value.  const0_rtx indicates
6869    the result is unused.
6870    atomically fetch MEM, perform the operation with VAL and return it to MEM.
6871    CODE is the operation being performed (OP)
6872    MEMMODEL is the memory model variant to use.
6873    AFTER is true to return the result of the operation (OP_fetch).
6874    AFTER is false to return the value before the operation (fetch_OP).
6875 
6876    This function will *only* generate instructions if there is a direct
6877    optab. No compare and swap loops or libcalls will be generated. */
6878 
6879 static rtx
6880 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
6881 				    enum rtx_code code, enum memmodel model,
6882 				    bool after)
6883 {
6884   machine_mode mode = GET_MODE (mem);
6885   struct atomic_op_functions optab;
6886   rtx result;
6887   bool unused_result = (target == const0_rtx);
6888 
6889   get_atomic_op_for_code (&optab, code);
6890 
6891   /* Check to see if there are any better instructions.  */
6892   result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
6893   if (result)
6894     return result;
6895 
6896   /* Check for the case where the result isn't used and try those patterns.  */
6897   if (unused_result)
6898     {
6899       /* Try the memory model variant first.  */
6900       result = maybe_emit_op (&optab, target, mem, val, true, model, true);
6901       if (result)
6902         return result;
6903 
6904       /* Next try the old style withuot a memory model.  */
6905       result = maybe_emit_op (&optab, target, mem, val, false, model, true);
6906       if (result)
6907         return result;
6908 
6909       /* There is no no-result pattern, so try patterns with a result.  */
6910       target = NULL_RTX;
6911     }
6912 
6913   /* Try the __atomic version.  */
6914   result = maybe_emit_op (&optab, target, mem, val, true, model, after);
6915   if (result)
6916     return result;
6917 
6918   /* Try the older __sync version.  */
6919   result = maybe_emit_op (&optab, target, mem, val, false, model, after);
6920   if (result)
6921     return result;
6922 
6923   /* If the fetch value can be calculated from the other variation of fetch,
6924      try that operation.  */
6925   if (after || unused_result || optab.reverse_code != UNKNOWN)
6926     {
6927       /* Try the __atomic version, then the older __sync version.  */
6928       result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
6929       if (!result)
6930 	result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
6931 
6932       if (result)
6933 	{
6934 	  /* If the result isn't used, no need to do compensation code.  */
6935 	  if (unused_result)
6936 	    return result;
6937 
6938 	  /* Issue compensation code.  Fetch_after  == fetch_before OP val.
6939 	     Fetch_before == after REVERSE_OP val.  */
6940 	  if (!after)
6941 	    code = optab.reverse_code;
6942 	  if (code == NOT)
6943 	    {
6944 	      result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
6945 					    true, OPTAB_LIB_WIDEN);
6946 	      result = expand_simple_unop (mode, NOT, result, target, true);
6947 	    }
6948 	  else
6949 	    result = expand_simple_binop (mode, code, result, val, target,
6950 					  true, OPTAB_LIB_WIDEN);
6951 	  return result;
6952 	}
6953     }
6954 
6955   /* No direct opcode can be generated.  */
6956   return NULL_RTX;
6957 }
6958 
6959 
6960 
6961 /* This function expands an atomic fetch_OP or OP_fetch operation:
6962    TARGET is an option place to stick the return value.  const0_rtx indicates
6963    the result is unused.
6964    atomically fetch MEM, perform the operation with VAL and return it to MEM.
6965    CODE is the operation being performed (OP)
6966    MEMMODEL is the memory model variant to use.
6967    AFTER is true to return the result of the operation (OP_fetch).
6968    AFTER is false to return the value before the operation (fetch_OP).  */
6969 rtx
6970 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6971 			enum memmodel model, bool after)
6972 {
6973   machine_mode mode = GET_MODE (mem);
6974   rtx result;
6975   bool unused_result = (target == const0_rtx);
6976 
6977   /* If loads are not atomic for the required size and we are not called to
6978      provide a __sync builtin, do not do anything so that we stay consistent
6979      with atomic loads of the same size.  */
6980   if (!can_atomic_load_p (mode) && !is_mm_sync (model))
6981     return NULL_RTX;
6982 
6983   result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
6984 					       after);
6985 
6986   if (result)
6987     return result;
6988 
6989   /* Add/sub can be implemented by doing the reverse operation with -(val).  */
6990   if (code == PLUS || code == MINUS)
6991     {
6992       rtx tmp;
6993       enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
6994 
6995       start_sequence ();
6996       tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
6997       result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
6998 						   model, after);
6999       if (result)
7000 	{
7001 	  /* PLUS worked so emit the insns and return.  */
7002 	  tmp = get_insns ();
7003 	  end_sequence ();
7004 	  emit_insn (tmp);
7005           return result;
7006 	}
7007 
7008       /* PLUS did not work, so throw away the negation code and continue.  */
7009       end_sequence ();
7010     }
7011 
7012   /* Try the __sync libcalls only if we can't do compare-and-swap inline.  */
7013   if (!can_compare_and_swap_p (mode, false))
7014     {
7015       rtx libfunc;
7016       bool fixup = false;
7017       enum rtx_code orig_code = code;
7018       struct atomic_op_functions optab;
7019 
7020       get_atomic_op_for_code (&optab, code);
7021       libfunc = optab_libfunc (after ? optab.fetch_after
7022 			       : optab.fetch_before, mode);
7023       if (libfunc == NULL
7024 	  && (after || unused_result || optab.reverse_code != UNKNOWN))
7025 	{
7026 	  fixup = true;
7027 	  if (!after)
7028 	    code = optab.reverse_code;
7029 	  libfunc = optab_libfunc (after ? optab.fetch_before
7030 				   : optab.fetch_after, mode);
7031 	}
7032       if (libfunc != NULL)
7033 	{
7034 	  rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7035 	  result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
7036 					    addr, ptr_mode, val, mode);
7037 
7038 	  if (!unused_result && fixup)
7039 	    result = expand_simple_binop (mode, code, result, val, target,
7040 					  true, OPTAB_LIB_WIDEN);
7041 	  return result;
7042 	}
7043 
7044       /* We need the original code for any further attempts.  */
7045       code = orig_code;
7046     }
7047 
7048   /* If nothing else has succeeded, default to a compare and swap loop.  */
7049   if (can_compare_and_swap_p (mode, true))
7050     {
7051       rtx_insn *insn;
7052       rtx t0 = gen_reg_rtx (mode), t1;
7053 
7054       start_sequence ();
7055 
7056       /* If the result is used, get a register for it.  */
7057       if (!unused_result)
7058         {
7059 	  if (!target || !register_operand (target, mode))
7060 	    target = gen_reg_rtx (mode);
7061 	  /* If fetch_before, copy the value now.  */
7062 	  if (!after)
7063 	    emit_move_insn (target, t0);
7064 	}
7065       else
7066         target = const0_rtx;
7067 
7068       t1 = t0;
7069       if (code == NOT)
7070         {
7071 	  t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
7072 				    true, OPTAB_LIB_WIDEN);
7073 	  t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
7074 	}
7075       else
7076 	t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
7077 				  OPTAB_LIB_WIDEN);
7078 
7079       /* For after, copy the value now.  */
7080       if (!unused_result && after)
7081         emit_move_insn (target, t1);
7082       insn = get_insns ();
7083       end_sequence ();
7084 
7085       if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7086         return target;
7087     }
7088 
7089   return NULL_RTX;
7090 }
7091 
7092 /* Return true if OPERAND is suitable for operand number OPNO of
7093    instruction ICODE.  */
7094 
7095 bool
7096 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
7097 {
7098   return (!insn_data[(int) icode].operand[opno].predicate
7099 	  || (insn_data[(int) icode].operand[opno].predicate
7100 	      (operand, insn_data[(int) icode].operand[opno].mode)));
7101 }
7102 
7103 /* TARGET is a target of a multiword operation that we are going to
7104    implement as a series of word-mode operations.  Return true if
7105    TARGET is suitable for this purpose.  */
7106 
7107 bool
7108 valid_multiword_target_p (rtx target)
7109 {
7110   machine_mode mode;
7111   int i, size;
7112 
7113   mode = GET_MODE (target);
7114   if (!GET_MODE_SIZE (mode).is_constant (&size))
7115     return false;
7116   for (i = 0; i < size; i += UNITS_PER_WORD)
7117     if (!validate_subreg (word_mode, mode, target, i))
7118       return false;
7119   return true;
7120 }
7121 
7122 /* Make OP describe an input operand that has value INTVAL and that has
7123    no inherent mode.  This function should only be used for operands that
7124    are always expand-time constants.  The backend may request that INTVAL
7125    be copied into a different kind of rtx, but it must specify the mode
7126    of that rtx if so.  */
7127 
7128 void
7129 create_integer_operand (struct expand_operand *op, poly_int64 intval)
7130 {
7131   create_expand_operand (op, EXPAND_INTEGER,
7132 			 gen_int_mode (intval, MAX_MODE_INT),
7133 			 VOIDmode, false, intval);
7134 }
7135 
7136 /* Like maybe_legitimize_operand, but do not change the code of the
7137    current rtx value.  */
7138 
7139 static bool
7140 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
7141 				    struct expand_operand *op)
7142 {
7143   /* See if the operand matches in its current form.  */
7144   if (insn_operand_matches (icode, opno, op->value))
7145     return true;
7146 
7147   /* If the operand is a memory whose address has no side effects,
7148      try forcing the address into a non-virtual pseudo register.
7149      The check for side effects is important because copy_to_mode_reg
7150      cannot handle things like auto-modified addresses.  */
7151   if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
7152     {
7153       rtx addr, mem;
7154 
7155       mem = op->value;
7156       addr = XEXP (mem, 0);
7157       if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
7158 	  && !side_effects_p (addr))
7159 	{
7160 	  rtx_insn *last;
7161 	  machine_mode mode;
7162 
7163 	  last = get_last_insn ();
7164 	  mode = get_address_mode (mem);
7165 	  mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
7166 	  if (insn_operand_matches (icode, opno, mem))
7167 	    {
7168 	      op->value = mem;
7169 	      return true;
7170 	    }
7171 	  delete_insns_since (last);
7172 	}
7173     }
7174 
7175   return false;
7176 }
7177 
7178 /* Try to make OP match operand OPNO of instruction ICODE.  Return true
7179    on success, storing the new operand value back in OP.  */
7180 
7181 static bool
7182 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
7183 			  struct expand_operand *op)
7184 {
7185   machine_mode mode, imode;
7186   bool old_volatile_ok, result;
7187 
7188   mode = op->mode;
7189   switch (op->type)
7190     {
7191     case EXPAND_FIXED:
7192       old_volatile_ok = volatile_ok;
7193       volatile_ok = true;
7194       result = maybe_legitimize_operand_same_code (icode, opno, op);
7195       volatile_ok = old_volatile_ok;
7196       return result;
7197 
7198     case EXPAND_OUTPUT:
7199       gcc_assert (mode != VOIDmode);
7200       if (op->value
7201 	  && op->value != const0_rtx
7202 	  && GET_MODE (op->value) == mode
7203 	  && maybe_legitimize_operand_same_code (icode, opno, op))
7204 	return true;
7205 
7206       op->value = gen_reg_rtx (mode);
7207       op->target = 0;
7208       break;
7209 
7210     case EXPAND_INPUT:
7211     input:
7212       gcc_assert (mode != VOIDmode);
7213       gcc_assert (GET_MODE (op->value) == VOIDmode
7214 		  || GET_MODE (op->value) == mode);
7215       if (maybe_legitimize_operand_same_code (icode, opno, op))
7216 	return true;
7217 
7218       op->value = copy_to_mode_reg (mode, op->value);
7219       break;
7220 
7221     case EXPAND_CONVERT_TO:
7222       gcc_assert (mode != VOIDmode);
7223       op->value = convert_to_mode (mode, op->value, op->unsigned_p);
7224       goto input;
7225 
7226     case EXPAND_CONVERT_FROM:
7227       if (GET_MODE (op->value) != VOIDmode)
7228 	mode = GET_MODE (op->value);
7229       else
7230 	/* The caller must tell us what mode this value has.  */
7231 	gcc_assert (mode != VOIDmode);
7232 
7233       imode = insn_data[(int) icode].operand[opno].mode;
7234       if (imode != VOIDmode && imode != mode)
7235 	{
7236 	  op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
7237 	  mode = imode;
7238 	}
7239       goto input;
7240 
7241     case EXPAND_ADDRESS:
7242       op->value = convert_memory_address (as_a <scalar_int_mode> (mode),
7243 					  op->value);
7244       goto input;
7245 
7246     case EXPAND_INTEGER:
7247       mode = insn_data[(int) icode].operand[opno].mode;
7248       if (mode != VOIDmode
7249 	  && known_eq (trunc_int_for_mode (op->int_value, mode),
7250 		       op->int_value))
7251 	{
7252 	  op->value = gen_int_mode (op->int_value, mode);
7253 	  goto input;
7254 	}
7255       break;
7256     }
7257   return insn_operand_matches (icode, opno, op->value);
7258 }
7259 
7260 /* Make OP describe an input operand that should have the same value
7261    as VALUE, after any mode conversion that the target might request.
7262    TYPE is the type of VALUE.  */
7263 
7264 void
7265 create_convert_operand_from_type (struct expand_operand *op,
7266 				  rtx value, tree type)
7267 {
7268   create_convert_operand_from (op, value, TYPE_MODE (type),
7269 			       TYPE_UNSIGNED (type));
7270 }
7271 
7272 /* Return true if the requirements on operands OP1 and OP2 of instruction
7273    ICODE are similar enough for the result of legitimizing OP1 to be
7274    reusable for OP2.  OPNO1 and OPNO2 are the operand numbers associated
7275    with OP1 and OP2 respectively.  */
7276 
7277 static inline bool
7278 can_reuse_operands_p (enum insn_code icode,
7279 		      unsigned int opno1, unsigned int opno2,
7280 		      const struct expand_operand *op1,
7281 		      const struct expand_operand *op2)
7282 {
7283   /* Check requirements that are common to all types.  */
7284   if (op1->type != op2->type
7285       || op1->mode != op2->mode
7286       || (insn_data[(int) icode].operand[opno1].mode
7287 	  != insn_data[(int) icode].operand[opno2].mode))
7288     return false;
7289 
7290   /* Check the requirements for specific types.  */
7291   switch (op1->type)
7292     {
7293     case EXPAND_OUTPUT:
7294       /* Outputs must remain distinct.  */
7295       return false;
7296 
7297     case EXPAND_FIXED:
7298     case EXPAND_INPUT:
7299     case EXPAND_ADDRESS:
7300     case EXPAND_INTEGER:
7301       return true;
7302 
7303     case EXPAND_CONVERT_TO:
7304     case EXPAND_CONVERT_FROM:
7305       return op1->unsigned_p == op2->unsigned_p;
7306     }
7307   gcc_unreachable ();
7308 }
7309 
7310 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
7311    of instruction ICODE.  Return true on success, leaving the new operand
7312    values in the OPS themselves.  Emit no code on failure.  */
7313 
7314 bool
7315 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
7316 			   unsigned int nops, struct expand_operand *ops)
7317 {
7318   rtx_insn *last = get_last_insn ();
7319   rtx *orig_values = XALLOCAVEC (rtx, nops);
7320   for (unsigned int i = 0; i < nops; i++)
7321     {
7322       orig_values[i] = ops[i].value;
7323 
7324       /* First try reusing the result of an earlier legitimization.
7325 	 This avoids duplicate rtl and ensures that tied operands
7326 	 remain tied.
7327 
7328 	 This search is linear, but NOPS is bounded at compile time
7329 	 to a small number (current a single digit).  */
7330       unsigned int j = 0;
7331       for (; j < i; ++j)
7332 	if (can_reuse_operands_p (icode, opno + j, opno + i, &ops[j], &ops[i])
7333 	    && rtx_equal_p (orig_values[j], orig_values[i])
7334 	    && ops[j].value
7335 	    && insn_operand_matches (icode, opno + i, ops[j].value))
7336 	  {
7337 	    ops[i].value = copy_rtx (ops[j].value);
7338 	    break;
7339 	  }
7340 
7341       /* Otherwise try legitimizing the operand on its own.  */
7342       if (j == i && !maybe_legitimize_operand (icode, opno + i, &ops[i]))
7343 	{
7344 	  delete_insns_since (last);
7345 	  return false;
7346 	}
7347     }
7348   return true;
7349 }
7350 
7351 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
7352    as its operands.  Return the instruction pattern on success,
7353    and emit any necessary set-up code.  Return null and emit no
7354    code on failure.  */
7355 
7356 rtx_insn *
7357 maybe_gen_insn (enum insn_code icode, unsigned int nops,
7358 		struct expand_operand *ops)
7359 {
7360   gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
7361   if (!maybe_legitimize_operands (icode, 0, nops, ops))
7362     return NULL;
7363 
7364   switch (nops)
7365     {
7366     case 1:
7367       return GEN_FCN (icode) (ops[0].value);
7368     case 2:
7369       return GEN_FCN (icode) (ops[0].value, ops[1].value);
7370     case 3:
7371       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
7372     case 4:
7373       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7374 			      ops[3].value);
7375     case 5:
7376       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7377 			      ops[3].value, ops[4].value);
7378     case 6:
7379       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7380 			      ops[3].value, ops[4].value, ops[5].value);
7381     case 7:
7382       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7383 			      ops[3].value, ops[4].value, ops[5].value,
7384 			      ops[6].value);
7385     case 8:
7386       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7387 			      ops[3].value, ops[4].value, ops[5].value,
7388 			      ops[6].value, ops[7].value);
7389     case 9:
7390       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7391 			      ops[3].value, ops[4].value, ops[5].value,
7392 			      ops[6].value, ops[7].value, ops[8].value);
7393     }
7394   gcc_unreachable ();
7395 }
7396 
7397 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7398    as its operands.  Return true on success and emit no code on failure.  */
7399 
7400 bool
7401 maybe_expand_insn (enum insn_code icode, unsigned int nops,
7402 		   struct expand_operand *ops)
7403 {
7404   rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
7405   if (pat)
7406     {
7407       emit_insn (pat);
7408       return true;
7409     }
7410   return false;
7411 }
7412 
7413 /* Like maybe_expand_insn, but for jumps.  */
7414 
7415 bool
7416 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
7417 			struct expand_operand *ops)
7418 {
7419   rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
7420   if (pat)
7421     {
7422       emit_jump_insn (pat);
7423       return true;
7424     }
7425   return false;
7426 }
7427 
7428 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
7429    as its operands.  */
7430 
7431 void
7432 expand_insn (enum insn_code icode, unsigned int nops,
7433 	     struct expand_operand *ops)
7434 {
7435   if (!maybe_expand_insn (icode, nops, ops))
7436     gcc_unreachable ();
7437 }
7438 
7439 /* Like expand_insn, but for jumps.  */
7440 
7441 void
7442 expand_jump_insn (enum insn_code icode, unsigned int nops,
7443 		  struct expand_operand *ops)
7444 {
7445   if (!maybe_expand_jump_insn (icode, nops, ops))
7446     gcc_unreachable ();
7447 }
7448