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