OSDN Git Service

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