OSDN Git Service

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