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