OSDN Git Service

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