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