OSDN Git Service

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