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
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along 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.  */
63struct optab_d optab_table[OTI_MAX];
64#endif
65
66rtx 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.  */
76struct convert_optab_d convert_optab_table[COI_MAX];
77#endif
78
79/* Contains the optab used for each rtx code.  */
80optab 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
88enum 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
94enum insn_code vcond_gen_code[NUM_MACHINE_MODES];
95enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
96
97static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
98				   enum machine_mode *);
99static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
100
101/* Debug facility for use in GDB.  */
102void 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.  */
114struct 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.  */
121static GTY((param_is (struct libfunc_entry))) htab_t libfunc_hash;
122
123/* Used for attribute_hash.  */
124
125static hashval_t
126hash_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
136static int
137eq_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.  */
150rtx
151convert_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.  */
180rtx
181optab_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
219static int
220add_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
283static rtx
284widen_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.  */
319optab
320optab_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
532rtx
533expand_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
671rtx
672expand_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
744static rtx
745simplify_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
763bool
764force_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
779rtx
780expand_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
838static bool
839expand_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
867static bool
868expand_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
948static bool
949expand_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
1032static bool
1033expand_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
1207static rtx
1208expand_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.  */
1316rtx
1317expand_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.  */
1330static bool
1331swap_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
1352static bool
1353shift_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
1373static bool
1374commutative_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
1388static rtx
1389avoid_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.  */
1415static rtx
1416expand_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
1547rtx
1548expand_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
2237rtx
2238sign_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
2297int
2298expand_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
2390int
2391expand_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
2506bool
2507expand_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.  */
2549rtx
2550expand_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)).  */
2563static rtx
2564widen_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.  */
2602static rtx
2603expand_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))).  */
2674static rtx
2675widen_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
2717static rtx
2718expand_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.  */
2739static rtx
2740expand_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
2786static rtx
2787expand_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.  */
2827static rtx
2828expand_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
2906static rtx
2907lowpart_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
2924static rtx
2925expand_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.  */
3027static rtx
3028expand_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
3087rtx
3088expand_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
3375rtx
3376expand_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
3440rtx
3441expand_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
3492rtx
3493expand_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
3543static rtx
3544expand_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
3639static rtx
3640expand_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
3741rtx
3742expand_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
3795bool
3796maybe_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
3835void
3836emit_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
3842struct 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.  */
3851static void
3852no_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
3895void
3896emit_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
4001int
4002can_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
4048static void
4049prepare_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
4265rtx
4266prepare_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
4286static void
4287emit_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
4319void
4320emit_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
4352static void
4353prepare_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
4476void
4477emit_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
4503rtx
4504emit_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
4617int
4618can_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
4642rtx
4643emit_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
4754rtx
4755gen_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
4772rtx
4773gen_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
4789int
4790have_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
4814rtx
4815gen_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
4832rtx
4833gen_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
4849int
4850have_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
4875rtx
4876gen_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
4891enum insn_code
4892can_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
4908rtx
4909gen_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
4925static enum insn_code
4926can_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
4956static enum insn_code
4957can_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
4972void
4973expand_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
5174void
5175expand_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
5358void
5359expand_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
5409bool
5410expand_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.  */
5452int
5453have_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
5462static void
5463init_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.  */
5489static inline void
5490init_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.  */
5498static inline void
5499init_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.  */
5505static void
5506init_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
5525static void
5526gen_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
5551static void
5552gen_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
5569static void
5570gen_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
5590static void
5591gen_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
5602static void
5603gen_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
5614static void
5615gen_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
5625static void
5626gen_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
5638static void
5639gen_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
5658static void
5659gen_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
5673static void
5674gen_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
5688static void
5689gen_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
5701static void
5702gen_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
5714static void
5715gen_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
5730static void
5731gen_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
5793static void
5794gen_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
5809static void
5810gen_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
5824static void
5825gen_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
5840static void
5841gen_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
5857static void
5858gen_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
5919static void
5920gen_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
5948static void
5949gen_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
5977static void
5978gen_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
5996static void
5997gen_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
6017static void
6018gen_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
6037static void
6038gen_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.  */
6053static GTY ((param_is (union tree_node))) htab_t libfunc_decls;
6054
6055/* Hashtable callbacks for libfunc_decls.  */
6056
6057static hashval_t
6058libfunc_decl_hash (const void *entry)
6059{
6060  return htab_hash_string (IDENTIFIER_POINTER (DECL_NAME ((const_tree) entry)));
6061}
6062
6063static int
6064libfunc_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
6071tree
6072build_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
6091rtx
6092init_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
6119rtx
6120set_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.  */
6137void
6138set_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.  */
6163void
6164set_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
6190void
6191init_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
6697void
6698debug_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
6750rtx
6751gen_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
6796static enum rtx_code
6797get_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
6855static rtx
6856vector_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
6889static inline enum insn_code
6890get_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
6904bool
6905expand_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
6915rtx
6916expand_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
6961static rtx
6962expand_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
6991rtx
6992expand_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
7006static void
7007find_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
7022rtx
7023expand_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
7079static bool
7080expand_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
7144rtx
7145expand_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
7237rtx
7238expand_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
7408rtx
7409expand_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