OSDN Git Service

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