OSDN Git Service

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