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