OSDN Git Service

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