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