OSDN Git Service

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