OSDN Git Service

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