OSDN Git Service

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