OSDN Git Service

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