OSDN Git Service

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