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