OSDN Git Service

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