OSDN Git Service

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