optabs.c revision 267654
1290650Shselasky/* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2290650Shselasky   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3290650Shselasky   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4290650Shselasky   Free Software Foundation, Inc.
5290650Shselasky
6290650ShselaskyThis file is part of GCC.
7290650Shselasky
8290650ShselaskyGCC is free software; you can redistribute it and/or modify it under
9290650Shselaskythe terms of the GNU General Public License as published by the Free
10290650ShselaskySoftware Foundation; either version 2, or (at your option) any later
11290650Shselaskyversion.
12290650Shselasky
13290650ShselaskyGCC is distributed in the hope that it will be useful, but WITHOUT ANY
14290650ShselaskyWARRANTY; without even the implied warranty of MERCHANTABILITY or
15290650ShselaskyFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16290650Shselaskyfor more details.
17290650Shselasky
18290650ShselaskyYou should have received a copy of the GNU General Public License
19290650Shselaskyalong with GCC; see the file COPYING.  If not, write to the Free
20290650ShselaskySoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21290650Shselasky02110-1301, USA.  */
22290650Shselasky
23290650Shselasky
24290650Shselasky#include "config.h"
25290650Shselasky#include "system.h"
26290650Shselasky#include "coretypes.h"
27290650Shselasky#include "tm.h"
28290650Shselasky#include "toplev.h"
29290650Shselasky
30290650Shselasky/* Include insn-config.h before expr.h so that HAVE_conditional_move
31290650Shselasky   is properly defined.  */
32290650Shselasky#include "insn-config.h"
33290650Shselasky#include "rtl.h"
34290650Shselasky#include "tree.h"
35290650Shselasky#include "tm_p.h"
36290650Shselasky#include "flags.h"
37290650Shselasky#include "function.h"
38290650Shselasky#include "except.h"
39290650Shselasky#include "expr.h"
40290650Shselasky#include "optabs.h"
41290650Shselasky#include "libfuncs.h"
42290650Shselasky#include "recog.h"
43290650Shselasky#include "reload.h"
44290650Shselasky#include "ggc.h"
45290650Shselasky#include "real.h"
46290650Shselasky#include "basic-block.h"
47290650Shselasky#include "target.h"
48290650Shselasky
49290650Shselasky/* Each optab contains info on how this target machine
50290650Shselasky   can perform a particular operation
51290650Shselasky   for all sizes and kinds of operands.
52290650Shselasky
53290650Shselasky   The operation to be performed is often specified
54290650Shselasky   by passing one of these optabs as an argument.
55290650Shselasky
56290650Shselasky   See expr.h for documentation of these optabs.  */
57290650Shselasky
58290650Shselaskyoptab optab_table[OTI_MAX];
59290650Shselasky
60290650Shselaskyrtx libfunc_table[LTI_MAX];
61290650Shselasky
62290650Shselasky/* Tables of patterns for converting one mode to another.  */
63290650Shselaskyconvert_optab convert_optab_table[COI_MAX];
64290650Shselasky
65290650Shselasky/* Contains the optab used for each rtx code.  */
66290650Shselaskyoptab code_to_optab[NUM_RTX_CODE + 1];
67290650Shselasky
68290650Shselasky/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
69290650Shselasky   gives the gen_function to make a branch to test that condition.  */
70290650Shselasky
71290650Shselaskyrtxfun bcc_gen_fctn[NUM_RTX_CODE];
72290650Shselasky
73290650Shselasky/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
74290650Shselasky   gives the insn code to make a store-condition insn
75290650Shselasky   to test that condition.  */
76290650Shselasky
77290650Shselaskyenum insn_code setcc_gen_code[NUM_RTX_CODE];
78290650Shselasky
79290650Shselasky#ifdef HAVE_conditional_move
80290650Shselasky/* Indexed by the machine mode, gives the insn code to make a conditional
81290650Shselasky   move insn.  This is not indexed by the rtx-code like bcc_gen_fctn and
82290650Shselasky   setcc_gen_code to cut down on the number of named patterns.  Consider a day
83290650Shselasky   when a lot more rtx codes are conditional (eg: for the ARM).  */
84290650Shselasky
85290650Shselaskyenum insn_code movcc_gen_code[NUM_MACHINE_MODES];
86290650Shselasky#endif
87290650Shselasky
88290650Shselasky/* Indexed by the machine mode, gives the insn code for vector conditional
89290650Shselasky   operation.  */
90290650Shselasky
91290650Shselaskyenum insn_code vcond_gen_code[NUM_MACHINE_MODES];
92290650Shselaskyenum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
93290650Shselasky
94290650Shselasky/* The insn generating function can not take an rtx_code argument.
95290650Shselasky   TRAP_RTX is used as an rtx argument.  Its code is replaced with
96290650Shselasky   the code to be used in the trap insn and all other fields are ignored.  */
97290650Shselaskystatic GTY(()) rtx trap_rtx;
98290650Shselasky
99290650Shselaskystatic int add_equal_note (rtx, rtx, enum rtx_code, rtx, rtx);
100290650Shselaskystatic rtx widen_operand (rtx, enum machine_mode, enum machine_mode, int,
101290650Shselasky			  int);
102290650Shselaskystatic void prepare_cmp_insn (rtx *, rtx *, enum rtx_code *, rtx,
103290650Shselasky			      enum machine_mode *, int *,
104290650Shselasky			      enum can_compare_purpose);
105290650Shselaskystatic enum insn_code can_fix_p (enum machine_mode, enum machine_mode, int,
106290650Shselasky				 int *);
107290650Shselaskystatic enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
108290650Shselaskystatic optab new_optab (void);
109290650Shselaskystatic convert_optab new_convert_optab (void);
110290650Shselaskystatic inline optab init_optab (enum rtx_code);
111290650Shselaskystatic inline optab init_optabv (enum rtx_code);
112290650Shselaskystatic inline convert_optab init_convert_optab (enum rtx_code);
113290650Shselaskystatic void init_libfuncs (optab, int, int, const char *, int);
114290650Shselaskystatic void init_integral_libfuncs (optab, const char *, int);
115290650Shselaskystatic void init_floating_libfuncs (optab, const char *, int);
116290650Shselaskystatic void init_interclass_conv_libfuncs (convert_optab, const char *,
117290650Shselasky					   enum mode_class, enum mode_class);
118290650Shselaskystatic void init_intraclass_conv_libfuncs (convert_optab, const char *,
119290650Shselasky					   enum mode_class, bool);
120290650Shselaskystatic void emit_cmp_and_jump_insn_1 (rtx, rtx, enum machine_mode,
121290650Shselasky				      enum rtx_code, int, rtx);
122290650Shselaskystatic void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
123290650Shselasky				   enum machine_mode *, int *);
124290650Shselaskystatic rtx widen_clz (enum machine_mode, rtx, rtx);
125290650Shselaskystatic rtx expand_parity (enum machine_mode, rtx, rtx);
126290650Shselaskystatic enum rtx_code get_rtx_code (enum tree_code, bool);
127290650Shselaskystatic rtx vector_compare_rtx (tree, bool, enum insn_code);
128290650Shselasky
129290650Shselasky#ifndef HAVE_conditional_trap
130290650Shselasky#define HAVE_conditional_trap 0
131290650Shselasky#define gen_conditional_trap(a,b) (gcc_unreachable (), NULL_RTX)
132290650Shselasky#endif
133290650Shselasky
134290650Shselasky/* Add a REG_EQUAL note to the last insn in INSNS.  TARGET is being set to
135290650Shselasky   the result of operation CODE applied to OP0 (and OP1 if it is a binary
136290650Shselasky   operation).
137290650Shselasky
138290650Shselasky   If the last insn does not set TARGET, don't do anything, but return 1.
139290650Shselasky
140290650Shselasky   If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
141290650Shselasky   don't add the REG_EQUAL note but return 0.  Our caller can then try
142290650Shselasky   again, ensuring that TARGET is not one of the operands.  */
143290650Shselasky
144290650Shselaskystatic int
145290650Shselaskyadd_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
146290650Shselasky{
147290650Shselasky  rtx last_insn, insn, set;
148290650Shselasky  rtx note;
149290650Shselasky
150290650Shselasky  gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
151290650Shselasky
152290650Shselasky  if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
153290650Shselasky      && GET_RTX_CLASS (code) != RTX_BIN_ARITH
154290650Shselasky      && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
155290650Shselasky      && GET_RTX_CLASS (code) != RTX_COMPARE
156290650Shselasky      && GET_RTX_CLASS (code) != RTX_UNARY)
157290650Shselasky    return 1;
158290650Shselasky
159290650Shselasky  if (GET_CODE (target) == ZERO_EXTRACT)
160290650Shselasky    return 1;
161290650Shselasky
162290650Shselasky  for (last_insn = insns;
163290650Shselasky       NEXT_INSN (last_insn) != NULL_RTX;
164290650Shselasky       last_insn = NEXT_INSN (last_insn))
165290650Shselasky    ;
166290650Shselasky
167290650Shselasky  set = single_set (last_insn);
168290650Shselasky  if (set == NULL_RTX)
169290650Shselasky    return 1;
170290650Shselasky
171290650Shselasky  if (! rtx_equal_p (SET_DEST (set), target)
172290650Shselasky      /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it.  */
173290650Shselasky      && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
174290650Shselasky	  || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
175290650Shselasky    return 1;
176290650Shselasky
177290650Shselasky  /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
178290650Shselasky     besides the last insn.  */
179290650Shselasky  if (reg_overlap_mentioned_p (target, op0)
180290650Shselasky      || (op1 && reg_overlap_mentioned_p (target, op1)))
181290650Shselasky    {
182290650Shselasky      insn = PREV_INSN (last_insn);
183290650Shselasky      while (insn != NULL_RTX)
184290650Shselasky	{
185290650Shselasky	  if (reg_set_p (target, insn))
186290650Shselasky	    return 0;
187290650Shselasky
188290650Shselasky	  insn = PREV_INSN (insn);
189290650Shselasky	}
190306233Shselasky    }
191290650Shselasky
192306233Shselasky  if (GET_RTX_CLASS (code) == RTX_UNARY)
193306233Shselasky    note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
194306233Shselasky  else
195306233Shselasky    note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
196290650Shselasky
197290650Shselasky  set_unique_reg_note (last_insn, REG_EQUAL, note);
198290650Shselasky
199290650Shselasky  return 1;
200290650Shselasky}
201290650Shselasky
202290650Shselasky/* Widen OP to MODE and return the rtx for the widened operand.  UNSIGNEDP
203306233Shselasky   says whether OP is signed or unsigned.  NO_EXTEND is nonzero if we need
204306233Shselasky   not actually do a sign-extend or zero-extend, but can leave the
205306233Shselasky   higher-order bits of the result rtx undefined, for example, in the case
206290650Shselasky   of logical operations, but not right shifts.  */
207290650Shselasky
208290650Shselaskystatic rtx
209290650Shselaskywiden_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
210290650Shselasky	       int unsignedp, int no_extend)
211290650Shselasky{
212290650Shselasky  rtx result;
213290650Shselasky
214290650Shselasky  /* If we don't have to extend and this is a constant, return it.  */
215290650Shselasky  if (no_extend && GET_MODE (op) == VOIDmode)
216290650Shselasky    return op;
217290650Shselasky
218290650Shselasky  /* If we must extend do so.  If OP is a SUBREG for a promoted object, also
219290650Shselasky     extend since it will be more efficient to do so unless the signedness of
220290650Shselasky     a promoted object differs from our extension.  */
221290650Shselasky  if (! no_extend
222290650Shselasky      || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
223290650Shselasky	  && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
224290650Shselasky    return convert_modes (mode, oldmode, op, unsignedp);
225290650Shselasky
226290650Shselasky  /* If MODE is no wider than a single word, we return a paradoxical
227290650Shselasky     SUBREG.  */
228290650Shselasky  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
229290650Shselasky    return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
230290650Shselasky
231290650Shselasky  /* Otherwise, get an object of MODE, clobber it, and set the low-order
232290650Shselasky     part to OP.  */
233290650Shselasky
234290650Shselasky  result = gen_reg_rtx (mode);
235290650Shselasky  emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
236290650Shselasky  emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
237290650Shselasky  return result;
238290650Shselasky}
239290650Shselasky
240290650Shselasky/* Return the optab used for computing the operation given by
241290650Shselasky   the tree code, CODE.  This function is not always usable (for
242290650Shselasky   example, it cannot give complete results for multiplication
243290650Shselasky   or division) but probably ought to be relied on more widely
244290650Shselasky   throughout the expander.  */
245290650Shselaskyoptab
246290650Shselaskyoptab_for_tree_code (enum tree_code code, tree type)
247290650Shselasky{
248290650Shselasky  bool trapv;
249290650Shselasky  switch (code)
250290650Shselasky    {
251290650Shselasky    case BIT_AND_EXPR:
252290650Shselasky      return and_optab;
253290650Shselasky
254290650Shselasky    case BIT_IOR_EXPR:
255290650Shselasky      return ior_optab;
256290650Shselasky
257290650Shselasky    case BIT_NOT_EXPR:
258290650Shselasky      return one_cmpl_optab;
259290650Shselasky
260290650Shselasky    case BIT_XOR_EXPR:
261290650Shselasky      return xor_optab;
262290650Shselasky
263290650Shselasky    case TRUNC_MOD_EXPR:
264290650Shselasky    case CEIL_MOD_EXPR:
265290650Shselasky    case FLOOR_MOD_EXPR:
266290650Shselasky    case ROUND_MOD_EXPR:
267290650Shselasky      return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
268290650Shselasky
269321995Shselasky    case RDIV_EXPR:
270321995Shselasky    case TRUNC_DIV_EXPR:
271321995Shselasky    case CEIL_DIV_EXPR:
272321995Shselasky    case FLOOR_DIV_EXPR:
273321995Shselasky    case ROUND_DIV_EXPR:
274321995Shselasky    case EXACT_DIV_EXPR:
275321995Shselasky      return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
276321995Shselasky
277321995Shselasky    case LSHIFT_EXPR:
278321995Shselasky      return ashl_optab;
279321995Shselasky
280321995Shselasky    case RSHIFT_EXPR:
281321995Shselasky      return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
282321995Shselasky
283321995Shselasky    case LROTATE_EXPR:
284321995Shselasky      return rotl_optab;
285321995Shselasky
286321995Shselasky    case RROTATE_EXPR:
287321995Shselasky      return rotr_optab;
288321995Shselasky
289321995Shselasky    case MAX_EXPR:
290321995Shselasky      return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
291290650Shselasky
292290650Shselasky    case MIN_EXPR:
293290650Shselasky      return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
294290650Shselasky
295290650Shselasky    case REALIGN_LOAD_EXPR:
296290650Shselasky      return vec_realign_load_optab;
297290650Shselasky
298290650Shselasky    case WIDEN_SUM_EXPR:
299290650Shselasky      return TYPE_UNSIGNED (type) ? usum_widen_optab : ssum_widen_optab;
300290650Shselasky
301290650Shselasky    case DOT_PROD_EXPR:
302290650Shselasky      return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
303290650Shselasky
304290650Shselasky    case REDUC_MAX_EXPR:
305290650Shselasky      return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab;
306290650Shselasky
307290650Shselasky    case REDUC_MIN_EXPR:
308290650Shselasky      return TYPE_UNSIGNED (type) ? reduc_umin_optab : reduc_smin_optab;
309
310    case REDUC_PLUS_EXPR:
311      return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
312
313    case VEC_LSHIFT_EXPR:
314      return vec_shl_optab;
315
316    case VEC_RSHIFT_EXPR:
317      return vec_shr_optab;
318
319    default:
320      break;
321    }
322
323  trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
324  switch (code)
325    {
326    case PLUS_EXPR:
327      return trapv ? addv_optab : add_optab;
328
329    case MINUS_EXPR:
330      return trapv ? subv_optab : sub_optab;
331
332    case MULT_EXPR:
333      return trapv ? smulv_optab : smul_optab;
334
335    case NEGATE_EXPR:
336      return trapv ? negv_optab : neg_optab;
337
338    case ABS_EXPR:
339      return trapv ? absv_optab : abs_optab;
340
341    default:
342      return NULL;
343    }
344}
345
346
347/* Expand vector widening operations.
348
349   There are two different classes of operations handled here:
350   1) Operations whose result is wider than all the arguments to the operation.
351      Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
352      In this case OP0 and optionally OP1 would be initialized,
353      but WIDE_OP wouldn't (not relevant for this case).
354   2) Operations whose result is of the same size as the last argument to the
355      operation, but wider than all the other arguments to the operation.
356      Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
357      In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
358
359   E.g, when called to expand the following operations, this is how
360   the arguments will be initialized:
361                                nops    OP0     OP1     WIDE_OP
362   widening-sum                 2       oprnd0  -       oprnd1
363   widening-dot-product         3       oprnd0  oprnd1  oprnd2
364   widening-mult                2       oprnd0  oprnd1  -
365   type-promotion (vec-unpack)  1       oprnd0  -       -  */
366
367rtx
368expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op, rtx target,
369                           int unsignedp)
370{
371  tree oprnd0, oprnd1, oprnd2;
372  enum machine_mode wmode = 0, tmode0, tmode1 = 0;
373  optab widen_pattern_optab;
374  int icode;
375  enum machine_mode xmode0, xmode1 = 0, wxmode = 0;
376  rtx temp;
377  rtx pat;
378  rtx xop0, xop1, wxop;
379  int nops = TREE_CODE_LENGTH (TREE_CODE (exp));
380
381  oprnd0 = TREE_OPERAND (exp, 0);
382  tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
383  widen_pattern_optab =
384        optab_for_tree_code (TREE_CODE (exp), TREE_TYPE (oprnd0));
385  icode = (int) widen_pattern_optab->handlers[(int) tmode0].insn_code;
386  gcc_assert (icode != CODE_FOR_nothing);
387  xmode0 = insn_data[icode].operand[1].mode;
388
389  if (nops >= 2)
390    {
391      oprnd1 = TREE_OPERAND (exp, 1);
392      tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
393      xmode1 = insn_data[icode].operand[2].mode;
394    }
395
396  /* The last operand is of a wider mode than the rest of the operands.  */
397  if (nops == 2)
398    {
399      wmode = tmode1;
400      wxmode = xmode1;
401    }
402  else if (nops == 3)
403    {
404      gcc_assert (tmode1 == tmode0);
405      gcc_assert (op1);
406      oprnd2 = TREE_OPERAND (exp, 2);
407      wmode = TYPE_MODE (TREE_TYPE (oprnd2));
408      wxmode = insn_data[icode].operand[3].mode;
409    }
410
411  if (!wide_op)
412    wmode = wxmode = insn_data[icode].operand[0].mode;
413
414  if (!target
415      || ! (*insn_data[icode].operand[0].predicate) (target, wmode))
416    temp = gen_reg_rtx (wmode);
417  else
418    temp = target;
419
420  xop0 = op0;
421  xop1 = op1;
422  wxop = wide_op;
423
424  /* In case the insn wants input operands in modes different from
425     those of the actual operands, convert the operands.  It would
426     seem that we don't need to convert CONST_INTs, but we do, so
427     that they're properly zero-extended, sign-extended or truncated
428     for their mode.  */
429
430  if (GET_MODE (op0) != xmode0 && xmode0 != VOIDmode)
431    xop0 = convert_modes (xmode0,
432                          GET_MODE (op0) != VOIDmode
433                          ? GET_MODE (op0)
434                          : tmode0,
435                          xop0, unsignedp);
436
437  if (op1)
438    if (GET_MODE (op1) != xmode1 && xmode1 != VOIDmode)
439      xop1 = convert_modes (xmode1,
440                            GET_MODE (op1) != VOIDmode
441                            ? GET_MODE (op1)
442                            : tmode1,
443                            xop1, unsignedp);
444
445  if (wide_op)
446    if (GET_MODE (wide_op) != wxmode && wxmode != VOIDmode)
447      wxop = convert_modes (wxmode,
448                            GET_MODE (wide_op) != VOIDmode
449                            ? GET_MODE (wide_op)
450                            : wmode,
451                            wxop, unsignedp);
452
453  /* Now, if insn's predicates don't allow our operands, put them into
454     pseudo regs.  */
455
456  if (! (*insn_data[icode].operand[1].predicate) (xop0, xmode0)
457      && xmode0 != VOIDmode)
458    xop0 = copy_to_mode_reg (xmode0, xop0);
459
460  if (op1)
461    {
462      if (! (*insn_data[icode].operand[2].predicate) (xop1, xmode1)
463          && xmode1 != VOIDmode)
464        xop1 = copy_to_mode_reg (xmode1, xop1);
465
466      if (wide_op)
467        {
468          if (! (*insn_data[icode].operand[3].predicate) (wxop, wxmode)
469              && wxmode != VOIDmode)
470            wxop = copy_to_mode_reg (wxmode, wxop);
471
472          pat = GEN_FCN (icode) (temp, xop0, xop1, wxop);
473        }
474      else
475        pat = GEN_FCN (icode) (temp, xop0, xop1);
476    }
477  else
478    {
479      if (wide_op)
480        {
481          if (! (*insn_data[icode].operand[2].predicate) (wxop, wxmode)
482              && wxmode != VOIDmode)
483            wxop = copy_to_mode_reg (wxmode, wxop);
484
485          pat = GEN_FCN (icode) (temp, xop0, wxop);
486        }
487      else
488        pat = GEN_FCN (icode) (temp, xop0);
489    }
490
491  emit_insn (pat);
492  return temp;
493}
494
495/* Generate code to perform an operation specified by TERNARY_OPTAB
496   on operands OP0, OP1 and OP2, with result having machine-mode MODE.
497
498   UNSIGNEDP is for the case where we have to widen the operands
499   to perform the operation.  It says to use zero-extension.
500
501   If TARGET is nonzero, the value
502   is generated there, if it is convenient to do so.
503   In all cases an rtx is returned for the locus of the value;
504   this may or may not be TARGET.  */
505
506rtx
507expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
508		   rtx op1, rtx op2, rtx target, int unsignedp)
509{
510  int icode = (int) ternary_optab->handlers[(int) mode].insn_code;
511  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
512  enum machine_mode mode1 = insn_data[icode].operand[2].mode;
513  enum machine_mode mode2 = insn_data[icode].operand[3].mode;
514  rtx temp;
515  rtx pat;
516  rtx xop0 = op0, xop1 = op1, xop2 = op2;
517
518  gcc_assert (ternary_optab->handlers[(int) mode].insn_code
519	      != CODE_FOR_nothing);
520
521  if (!target || !insn_data[icode].operand[0].predicate (target, mode))
522    temp = gen_reg_rtx (mode);
523  else
524    temp = target;
525
526  /* In case the insn wants input operands in modes different from
527     those of the actual operands, convert the operands.  It would
528     seem that we don't need to convert CONST_INTs, but we do, so
529     that they're properly zero-extended, sign-extended or truncated
530     for their mode.  */
531
532  if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
533    xop0 = convert_modes (mode0,
534                          GET_MODE (op0) != VOIDmode
535                          ? GET_MODE (op0)
536                          : mode,
537                          xop0, unsignedp);
538
539  if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
540    xop1 = convert_modes (mode1,
541                          GET_MODE (op1) != VOIDmode
542                          ? GET_MODE (op1)
543                          : mode,
544                          xop1, unsignedp);
545
546  if (GET_MODE (op2) != mode2 && mode2 != VOIDmode)
547    xop2 = convert_modes (mode2,
548                          GET_MODE (op2) != VOIDmode
549                          ? GET_MODE (op2)
550                          : mode,
551                          xop2, unsignedp);
552
553  /* Now, if insn's predicates don't allow our operands, put them into
554     pseudo regs.  */
555
556  if (!insn_data[icode].operand[1].predicate (xop0, mode0)
557      && mode0 != VOIDmode)
558    xop0 = copy_to_mode_reg (mode0, xop0);
559
560  if (!insn_data[icode].operand[2].predicate (xop1, mode1)
561      && mode1 != VOIDmode)
562    xop1 = copy_to_mode_reg (mode1, xop1);
563
564  if (!insn_data[icode].operand[3].predicate (xop2, mode2)
565      && mode2 != VOIDmode)
566    xop2 = copy_to_mode_reg (mode2, xop2);
567
568  pat = GEN_FCN (icode) (temp, xop0, xop1, xop2);
569
570  emit_insn (pat);
571  return temp;
572}
573
574
575/* Like expand_binop, but return a constant rtx if the result can be
576   calculated at compile time.  The arguments and return value are
577   otherwise the same as for expand_binop.  */
578
579static rtx
580simplify_expand_binop (enum machine_mode mode, optab binoptab,
581		       rtx op0, rtx op1, rtx target, int unsignedp,
582		       enum optab_methods methods)
583{
584  if (CONSTANT_P (op0) && CONSTANT_P (op1))
585    {
586      rtx x = simplify_binary_operation (binoptab->code, mode, op0, op1);
587
588      if (x)
589	return x;
590    }
591
592  return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
593}
594
595/* Like simplify_expand_binop, but always put the result in TARGET.
596   Return true if the expansion succeeded.  */
597
598bool
599force_expand_binop (enum machine_mode mode, optab binoptab,
600		    rtx op0, rtx op1, rtx target, int unsignedp,
601		    enum optab_methods methods)
602{
603  rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
604				 target, unsignedp, methods);
605  if (x == 0)
606    return false;
607  if (x != target)
608    emit_move_insn (target, x);
609  return true;
610}
611
612/* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR.  */
613
614rtx
615expand_vec_shift_expr (tree vec_shift_expr, rtx target)
616{
617  enum insn_code icode;
618  rtx rtx_op1, rtx_op2;
619  enum machine_mode mode1;
620  enum machine_mode mode2;
621  enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_shift_expr));
622  tree vec_oprnd = TREE_OPERAND (vec_shift_expr, 0);
623  tree shift_oprnd = TREE_OPERAND (vec_shift_expr, 1);
624  optab shift_optab;
625  rtx pat;
626
627  switch (TREE_CODE (vec_shift_expr))
628    {
629      case VEC_RSHIFT_EXPR:
630	shift_optab = vec_shr_optab;
631	break;
632      case VEC_LSHIFT_EXPR:
633	shift_optab = vec_shl_optab;
634	break;
635      default:
636	gcc_unreachable ();
637    }
638
639  icode = (int) shift_optab->handlers[(int) mode].insn_code;
640  gcc_assert (icode != CODE_FOR_nothing);
641
642  mode1 = insn_data[icode].operand[1].mode;
643  mode2 = insn_data[icode].operand[2].mode;
644
645  rtx_op1 = expand_expr (vec_oprnd, NULL_RTX, VOIDmode, EXPAND_NORMAL);
646  if (!(*insn_data[icode].operand[1].predicate) (rtx_op1, mode1)
647      && mode1 != VOIDmode)
648    rtx_op1 = force_reg (mode1, rtx_op1);
649
650  rtx_op2 = expand_expr (shift_oprnd, NULL_RTX, VOIDmode, EXPAND_NORMAL);
651  if (!(*insn_data[icode].operand[2].predicate) (rtx_op2, mode2)
652      && mode2 != VOIDmode)
653    rtx_op2 = force_reg (mode2, rtx_op2);
654
655  if (!target
656      || ! (*insn_data[icode].operand[0].predicate) (target, mode))
657    target = gen_reg_rtx (mode);
658
659  /* Emit instruction */
660  pat = GEN_FCN (icode) (target, rtx_op1, rtx_op2);
661  gcc_assert (pat);
662  emit_insn (pat);
663
664  return target;
665}
666
667/* This subroutine of expand_doubleword_shift handles the cases in which
668   the effective shift value is >= BITS_PER_WORD.  The arguments and return
669   value are the same as for the parent routine, except that SUPERWORD_OP1
670   is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
671   INTO_TARGET may be null if the caller has decided to calculate it.  */
672
673static bool
674expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
675			rtx outof_target, rtx into_target,
676			int unsignedp, enum optab_methods methods)
677{
678  if (into_target != 0)
679    if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
680			     into_target, unsignedp, methods))
681      return false;
682
683  if (outof_target != 0)
684    {
685      /* For a signed right shift, we must fill OUTOF_TARGET with copies
686	 of the sign bit, otherwise we must fill it with zeros.  */
687      if (binoptab != ashr_optab)
688	emit_move_insn (outof_target, CONST0_RTX (word_mode));
689      else
690	if (!force_expand_binop (word_mode, binoptab,
691				 outof_input, GEN_INT (BITS_PER_WORD - 1),
692				 outof_target, unsignedp, methods))
693	  return false;
694    }
695  return true;
696}
697
698/* This subroutine of expand_doubleword_shift handles the cases in which
699   the effective shift value is < BITS_PER_WORD.  The arguments and return
700   value are the same as for the parent routine.  */
701
702static bool
703expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
704		      rtx outof_input, rtx into_input, rtx op1,
705		      rtx outof_target, rtx into_target,
706		      int unsignedp, enum optab_methods methods,
707		      unsigned HOST_WIDE_INT shift_mask)
708{
709  optab reverse_unsigned_shift, unsigned_shift;
710  rtx tmp, carries;
711
712  reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
713  unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
714
715  /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
716     We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
717     the opposite direction to BINOPTAB.  */
718  if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
719    {
720      carries = outof_input;
721      tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
722      tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
723				   0, true, methods);
724    }
725  else
726    {
727      /* We must avoid shifting by BITS_PER_WORD bits since that is either
728	 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
729	 has unknown behavior.  Do a single shift first, then shift by the
730	 remainder.  It's OK to use ~OP1 as the remainder if shift counts
731	 are truncated to the mode size.  */
732      carries = expand_binop (word_mode, reverse_unsigned_shift,
733			      outof_input, const1_rtx, 0, unsignedp, methods);
734      if (shift_mask == BITS_PER_WORD - 1)
735	{
736	  tmp = immed_double_const (-1, -1, op1_mode);
737	  tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
738				       0, true, methods);
739	}
740      else
741	{
742	  tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
743	  tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
744				       0, true, methods);
745	}
746    }
747  if (tmp == 0 || carries == 0)
748    return false;
749  carries = expand_binop (word_mode, reverse_unsigned_shift,
750			  carries, tmp, 0, unsignedp, methods);
751  if (carries == 0)
752    return false;
753
754  /* Shift INTO_INPUT logically by OP1.  This is the last use of INTO_INPUT
755     so the result can go directly into INTO_TARGET if convenient.  */
756  tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
757		      into_target, unsignedp, methods);
758  if (tmp == 0)
759    return false;
760
761  /* Now OR in the bits carried over from OUTOF_INPUT.  */
762  if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
763			   into_target, unsignedp, methods))
764    return false;
765
766  /* Use a standard word_mode shift for the out-of half.  */
767  if (outof_target != 0)
768    if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
769			     outof_target, unsignedp, methods))
770      return false;
771
772  return true;
773}
774
775
776#ifdef HAVE_conditional_move
777/* Try implementing expand_doubleword_shift using conditional moves.
778   The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
779   otherwise it is by >= BITS_PER_WORD.  SUBWORD_OP1 and SUPERWORD_OP1
780   are the shift counts to use in the former and latter case.  All other
781   arguments are the same as the parent routine.  */
782
783static bool
784expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
785				  enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
786				  rtx outof_input, rtx into_input,
787				  rtx subword_op1, rtx superword_op1,
788				  rtx outof_target, rtx into_target,
789				  int unsignedp, enum optab_methods methods,
790				  unsigned HOST_WIDE_INT shift_mask)
791{
792  rtx outof_superword, into_superword;
793
794  /* Put the superword version of the output into OUTOF_SUPERWORD and
795     INTO_SUPERWORD.  */
796  outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
797  if (outof_target != 0 && subword_op1 == superword_op1)
798    {
799      /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
800	 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD.  */
801      into_superword = outof_target;
802      if (!expand_superword_shift (binoptab, outof_input, superword_op1,
803				   outof_superword, 0, unsignedp, methods))
804	return false;
805    }
806  else
807    {
808      into_superword = gen_reg_rtx (word_mode);
809      if (!expand_superword_shift (binoptab, outof_input, superword_op1,
810				   outof_superword, into_superword,
811				   unsignedp, methods))
812	return false;
813    }
814
815  /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET.  */
816  if (!expand_subword_shift (op1_mode, binoptab,
817			     outof_input, into_input, subword_op1,
818			     outof_target, into_target,
819			     unsignedp, methods, shift_mask))
820    return false;
821
822  /* Select between them.  Do the INTO half first because INTO_SUPERWORD
823     might be the current value of OUTOF_TARGET.  */
824  if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
825			      into_target, into_superword, word_mode, false))
826    return false;
827
828  if (outof_target != 0)
829    if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
830				outof_target, outof_superword,
831				word_mode, false))
832      return false;
833
834  return true;
835}
836#endif
837
838/* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
839   OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
840   input operand; the shift moves bits in the direction OUTOF_INPUT->
841   INTO_TARGET.  OUTOF_TARGET and INTO_TARGET are the equivalent words
842   of the target.  OP1 is the shift count and OP1_MODE is its mode.
843   If OP1 is constant, it will have been truncated as appropriate
844   and is known to be nonzero.
845
846   If SHIFT_MASK is zero, the result of word shifts is undefined when the
847   shift count is outside the range [0, BITS_PER_WORD).  This routine must
848   avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
849
850   If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
851   masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
852   fill with zeros or sign bits as appropriate.
853
854   If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
855   a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
856   Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
857   In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
858   are undefined.
859
860   BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop.  This function
861   may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
862   OUTOF_INPUT and OUTOF_TARGET.  OUTOF_TARGET can be null if the parent
863   function wants to calculate it itself.
864
865   Return true if the shift could be successfully synthesized.  */
866
867static bool
868expand_doubleword_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  rtx superword_op1, tmp, cmp1, cmp2;
875  rtx subword_label, done_label;
876  enum rtx_code cmp_code;
877
878  /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
879     fill the result with sign or zero bits as appropriate.  If so, the value
880     of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1).   Recursively call
881     this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
882     and INTO_INPUT), then emit code to set up OUTOF_TARGET.
883
884     This isn't worthwhile for constant shifts since the optimizers will
885     cope better with in-range shift counts.  */
886  if (shift_mask >= BITS_PER_WORD
887      && outof_target != 0
888      && !CONSTANT_P (op1))
889    {
890      if (!expand_doubleword_shift (op1_mode, binoptab,
891				    outof_input, into_input, op1,
892				    0, into_target,
893				    unsignedp, methods, shift_mask))
894	return false;
895      if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
896			       outof_target, unsignedp, methods))
897	return false;
898      return true;
899    }
900
901  /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
902     is true when the effective shift value is less than BITS_PER_WORD.
903     Set SUPERWORD_OP1 to the shift count that should be used to shift
904     OUTOF_INPUT into INTO_TARGET when the condition is false.  */
905  tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
906  if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
907    {
908      /* Set CMP1 to OP1 & BITS_PER_WORD.  The result is zero iff OP1
909	 is a subword shift count.  */
910      cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
911				    0, true, methods);
912      cmp2 = CONST0_RTX (op1_mode);
913      cmp_code = EQ;
914      superword_op1 = op1;
915    }
916  else
917    {
918      /* Set CMP1 to OP1 - BITS_PER_WORD.  */
919      cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
920				    0, true, methods);
921      cmp2 = CONST0_RTX (op1_mode);
922      cmp_code = LT;
923      superword_op1 = cmp1;
924    }
925  if (cmp1 == 0)
926    return false;
927
928  /* If we can compute the condition at compile time, pick the
929     appropriate subroutine.  */
930  tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
931  if (tmp != 0 && GET_CODE (tmp) == CONST_INT)
932    {
933      if (tmp == const0_rtx)
934	return expand_superword_shift (binoptab, outof_input, superword_op1,
935				       outof_target, into_target,
936				       unsignedp, methods);
937      else
938	return expand_subword_shift (op1_mode, binoptab,
939				     outof_input, into_input, op1,
940				     outof_target, into_target,
941				     unsignedp, methods, shift_mask);
942    }
943
944#ifdef HAVE_conditional_move
945  /* Try using conditional moves to generate straight-line code.  */
946  {
947    rtx start = get_last_insn ();
948    if (expand_doubleword_shift_condmove (op1_mode, binoptab,
949					  cmp_code, cmp1, cmp2,
950					  outof_input, into_input,
951					  op1, superword_op1,
952					  outof_target, into_target,
953					  unsignedp, methods, shift_mask))
954      return true;
955    delete_insns_since (start);
956  }
957#endif
958
959  /* As a last resort, use branches to select the correct alternative.  */
960  subword_label = gen_label_rtx ();
961  done_label = gen_label_rtx ();
962
963  NO_DEFER_POP;
964  do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
965			   0, 0, subword_label);
966  OK_DEFER_POP;
967
968  if (!expand_superword_shift (binoptab, outof_input, superword_op1,
969			       outof_target, into_target,
970			       unsignedp, methods))
971    return false;
972
973  emit_jump_insn (gen_jump (done_label));
974  emit_barrier ();
975  emit_label (subword_label);
976
977  if (!expand_subword_shift (op1_mode, binoptab,
978			     outof_input, into_input, op1,
979			     outof_target, into_target,
980			     unsignedp, methods, shift_mask))
981    return false;
982
983  emit_label (done_label);
984  return true;
985}
986
987/* Subroutine of expand_binop.  Perform a double word multiplication of
988   operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
989   as the target's word_mode.  This function return NULL_RTX if anything
990   goes wrong, in which case it may have already emitted instructions
991   which need to be deleted.
992
993   If we want to multiply two two-word values and have normal and widening
994   multiplies of single-word values, we can do this with three smaller
995   multiplications.  Note that we do not make a REG_NO_CONFLICT block here
996   because we are not operating on one word at a time.
997
998   The multiplication proceeds as follows:
999			         _______________________
1000			        [__op0_high_|__op0_low__]
1001			         _______________________
1002        *			[__op1_high_|__op1_low__]
1003        _______________________________________________
1004			         _______________________
1005    (1)				[__op0_low__*__op1_low__]
1006		     _______________________
1007    (2a)	    [__op0_low__*__op1_high_]
1008		     _______________________
1009    (2b)	    [__op0_high_*__op1_low__]
1010         _______________________
1011    (3) [__op0_high_*__op1_high_]
1012
1013
1014  This gives a 4-word result.  Since we are only interested in the
1015  lower 2 words, partial result (3) and the upper words of (2a) and
1016  (2b) don't need to be calculated.  Hence (2a) and (2b) can be
1017  calculated using non-widening multiplication.
1018
1019  (1), however, needs to be calculated with an unsigned widening
1020  multiplication.  If this operation is not directly supported we
1021  try using a signed widening multiplication and adjust the result.
1022  This adjustment works as follows:
1023
1024      If both operands are positive then no adjustment is needed.
1025
1026      If the operands have different signs, for example op0_low < 0 and
1027      op1_low >= 0, the instruction treats the most significant bit of
1028      op0_low as a sign bit instead of a bit with significance
1029      2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1030      with 2**BITS_PER_WORD - op0_low, and two's complements the
1031      result.  Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1032      the result.
1033
1034      Similarly, if both operands are negative, we need to add
1035      (op0_low + op1_low) * 2**BITS_PER_WORD.
1036
1037      We use a trick to adjust quickly.  We logically shift op0_low right
1038      (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1039      op0_high (op1_high) before it is used to calculate 2b (2a).  If no
1040      logical shift exists, we do an arithmetic right shift and subtract
1041      the 0 or -1.  */
1042
1043static rtx
1044expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
1045		       bool umulp, enum optab_methods methods)
1046{
1047  int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1048  int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1049  rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
1050  rtx product, adjust, product_high, temp;
1051
1052  rtx op0_high = operand_subword_force (op0, high, mode);
1053  rtx op0_low = operand_subword_force (op0, low, mode);
1054  rtx op1_high = operand_subword_force (op1, high, mode);
1055  rtx op1_low = operand_subword_force (op1, low, mode);
1056
1057  /* If we're using an unsigned multiply to directly compute the product
1058     of the low-order words of the operands and perform any required
1059     adjustments of the operands, we begin by trying two more multiplications
1060     and then computing the appropriate sum.
1061
1062     We have checked above that the required addition is provided.
1063     Full-word addition will normally always succeed, especially if
1064     it is provided at all, so we don't worry about its failure.  The
1065     multiplication may well fail, however, so we do handle that.  */
1066
1067  if (!umulp)
1068    {
1069      /* ??? This could be done with emit_store_flag where available.  */
1070      temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1071			   NULL_RTX, 1, methods);
1072      if (temp)
1073	op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
1074				 NULL_RTX, 0, OPTAB_DIRECT);
1075      else
1076	{
1077	  temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1078			       NULL_RTX, 0, methods);
1079	  if (!temp)
1080	    return NULL_RTX;
1081	  op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
1082				   NULL_RTX, 0, OPTAB_DIRECT);
1083	}
1084
1085      if (!op0_high)
1086	return NULL_RTX;
1087    }
1088
1089  adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
1090			 NULL_RTX, 0, OPTAB_DIRECT);
1091  if (!adjust)
1092    return NULL_RTX;
1093
1094  /* OP0_HIGH should now be dead.  */
1095
1096  if (!umulp)
1097    {
1098      /* ??? This could be done with emit_store_flag where available.  */
1099      temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1100			   NULL_RTX, 1, methods);
1101      if (temp)
1102	op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
1103				 NULL_RTX, 0, OPTAB_DIRECT);
1104      else
1105	{
1106	  temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1107			       NULL_RTX, 0, methods);
1108	  if (!temp)
1109	    return NULL_RTX;
1110	  op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
1111				   NULL_RTX, 0, OPTAB_DIRECT);
1112	}
1113
1114      if (!op1_high)
1115	return NULL_RTX;
1116    }
1117
1118  temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
1119		       NULL_RTX, 0, OPTAB_DIRECT);
1120  if (!temp)
1121    return NULL_RTX;
1122
1123  /* OP1_HIGH should now be dead.  */
1124
1125  adjust = expand_binop (word_mode, add_optab, adjust, temp,
1126			 adjust, 0, OPTAB_DIRECT);
1127
1128  if (target && !REG_P (target))
1129    target = NULL_RTX;
1130
1131  if (umulp)
1132    product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1133			    target, 1, OPTAB_DIRECT);
1134  else
1135    product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1136			    target, 1, OPTAB_DIRECT);
1137
1138  if (!product)
1139    return NULL_RTX;
1140
1141  product_high = operand_subword (product, high, 1, mode);
1142  adjust = expand_binop (word_mode, add_optab, product_high, adjust,
1143			 REG_P (product_high) ? product_high : adjust,
1144			 0, OPTAB_DIRECT);
1145  emit_move_insn (product_high, adjust);
1146  return product;
1147}
1148
1149/* Wrapper around expand_binop which takes an rtx code to specify
1150   the operation to perform, not an optab pointer.  All other
1151   arguments are the same.  */
1152rtx
1153expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
1154		     rtx op1, rtx target, int unsignedp,
1155		     enum optab_methods methods)
1156{
1157  optab binop = code_to_optab[(int) code];
1158  gcc_assert (binop);
1159
1160  return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1161}
1162
1163/* Return whether OP0 and OP1 should be swapped when expanding a commutative
1164   binop.  Order them according to commutative_operand_precedence and, if
1165   possible, try to put TARGET or a pseudo first.  */
1166static bool
1167swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1168{
1169  int op0_prec = commutative_operand_precedence (op0);
1170  int op1_prec = commutative_operand_precedence (op1);
1171
1172  if (op0_prec < op1_prec)
1173    return true;
1174
1175  if (op0_prec > op1_prec)
1176    return false;
1177
1178  /* With equal precedence, both orders are ok, but it is better if the
1179     first operand is TARGET, or if both TARGET and OP0 are pseudos.  */
1180  if (target == 0 || REG_P (target))
1181    return (REG_P (op1) && !REG_P (op0)) || target == op1;
1182  else
1183    return rtx_equal_p (op1, target);
1184}
1185
1186
1187/* Generate code to perform an operation specified by BINOPTAB
1188   on operands OP0 and OP1, with result having machine-mode MODE.
1189
1190   UNSIGNEDP is for the case where we have to widen the operands
1191   to perform the operation.  It says to use zero-extension.
1192
1193   If TARGET is nonzero, the value
1194   is generated there, if it is convenient to do so.
1195   In all cases an rtx is returned for the locus of the value;
1196   this may or may not be TARGET.  */
1197
1198rtx
1199expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
1200	      rtx target, int unsignedp, enum optab_methods methods)
1201{
1202  enum optab_methods next_methods
1203    = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1204       ? OPTAB_WIDEN : methods);
1205  enum mode_class class;
1206  enum machine_mode wider_mode;
1207  rtx temp;
1208  int commutative_op = 0;
1209  int shift_op = (binoptab->code == ASHIFT
1210		  || binoptab->code == ASHIFTRT
1211		  || binoptab->code == LSHIFTRT
1212		  || binoptab->code == ROTATE
1213		  || binoptab->code == ROTATERT);
1214  rtx entry_last = get_last_insn ();
1215  rtx last;
1216  bool first_pass_p = true;
1217
1218  class = GET_MODE_CLASS (mode);
1219
1220  /* If subtracting an integer constant, convert this into an addition of
1221     the negated constant.  */
1222
1223  if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
1224    {
1225      op1 = negate_rtx (mode, op1);
1226      binoptab = add_optab;
1227    }
1228
1229  /* If we are inside an appropriately-short loop and we are optimizing,
1230     force expensive constants into a register.  */
1231  if (CONSTANT_P (op0) && optimize
1232      && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
1233    {
1234      if (GET_MODE (op0) != VOIDmode)
1235	op0 = convert_modes (mode, VOIDmode, op0, unsignedp);
1236      op0 = force_reg (mode, op0);
1237    }
1238
1239  if (CONSTANT_P (op1) && optimize
1240      && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
1241    {
1242      if (GET_MODE (op1) != VOIDmode)
1243	op1 = convert_modes (mode, VOIDmode, op1, unsignedp);
1244      op1 = force_reg (mode, op1);
1245    }
1246
1247  /* Record where to delete back to if we backtrack.  */
1248  last = get_last_insn ();
1249
1250  /* If operation is commutative,
1251     try to make the first operand a register.
1252     Even better, try to make it the same as the target.
1253     Also try to make the last operand a constant.  */
1254  if (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
1255      || binoptab == smul_widen_optab
1256      || binoptab == umul_widen_optab
1257      || binoptab == smul_highpart_optab
1258      || binoptab == umul_highpart_optab)
1259    {
1260      commutative_op = 1;
1261
1262      if (swap_commutative_operands_with_target (target, op0, op1))
1263	{
1264	  temp = op1;
1265	  op1 = op0;
1266	  op0 = temp;
1267	}
1268    }
1269
1270 retry:
1271
1272  /* If we can do it with a three-operand insn, do so.  */
1273
1274  if (methods != OPTAB_MUST_WIDEN
1275      && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1276    {
1277      int icode = (int) binoptab->handlers[(int) mode].insn_code;
1278      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1279      enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1280      rtx pat;
1281      rtx xop0 = op0, xop1 = op1;
1282
1283      if (target)
1284	temp = target;
1285      else
1286	temp = gen_reg_rtx (mode);
1287
1288      /* If it is a commutative operator and the modes would match
1289	 if we would swap the operands, we can save the conversions.  */
1290      if (commutative_op)
1291	{
1292	  if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
1293	      && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
1294	    {
1295	      rtx tmp;
1296
1297	      tmp = op0; op0 = op1; op1 = tmp;
1298	      tmp = xop0; xop0 = xop1; xop1 = tmp;
1299	    }
1300	}
1301
1302      /* In case the insn wants input operands in modes different from
1303	 those of the actual operands, convert the operands.  It would
1304	 seem that we don't need to convert CONST_INTs, but we do, so
1305	 that they're properly zero-extended, sign-extended or truncated
1306	 for their mode.  */
1307
1308      if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
1309	xop0 = convert_modes (mode0,
1310			      GET_MODE (op0) != VOIDmode
1311			      ? GET_MODE (op0)
1312			      : mode,
1313			      xop0, unsignedp);
1314
1315      if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
1316	xop1 = convert_modes (mode1,
1317			      GET_MODE (op1) != VOIDmode
1318			      ? GET_MODE (op1)
1319			      : mode,
1320			      xop1, unsignedp);
1321
1322      /* Now, if insn's predicates don't allow our operands, put them into
1323	 pseudo regs.  */
1324
1325      if (!insn_data[icode].operand[1].predicate (xop0, mode0)
1326	  && mode0 != VOIDmode)
1327	xop0 = copy_to_mode_reg (mode0, xop0);
1328
1329      if (!insn_data[icode].operand[2].predicate (xop1, mode1)
1330	  && mode1 != VOIDmode)
1331	xop1 = copy_to_mode_reg (mode1, xop1);
1332
1333      if (!insn_data[icode].operand[0].predicate (temp, mode))
1334	temp = gen_reg_rtx (mode);
1335
1336      pat = GEN_FCN (icode) (temp, xop0, xop1);
1337      if (pat)
1338	{
1339	  /* If PAT is composed of more than one insn, try to add an appropriate
1340	     REG_EQUAL note to it.  If we can't because TEMP conflicts with an
1341	     operand, call ourselves again, this time without a target.  */
1342	  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1343	      && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
1344	    {
1345	      delete_insns_since (last);
1346	      return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1347				   unsignedp, methods);
1348	    }
1349
1350	  emit_insn (pat);
1351	  return temp;
1352	}
1353      else
1354	delete_insns_since (last);
1355    }
1356
1357  /* If we were trying to rotate by a constant value, and that didn't
1358     work, try rotating the other direction before falling back to
1359     shifts and bitwise-or.  */
1360  if (first_pass_p
1361      && (binoptab == rotl_optab || binoptab == rotr_optab)
1362      && class == MODE_INT
1363      && GET_CODE (op1) == CONST_INT
1364      && INTVAL (op1) > 0
1365      && (unsigned int) INTVAL (op1) < GET_MODE_BITSIZE (mode))
1366    {
1367      first_pass_p = false;
1368      op1 = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1));
1369      binoptab = binoptab == rotl_optab ? rotr_optab : rotl_optab;
1370      goto retry;
1371    }
1372
1373  /* If this is a multiply, see if we can do a widening operation that
1374     takes operands of this mode and makes a wider mode.  */
1375
1376  if (binoptab == smul_optab
1377      && GET_MODE_WIDER_MODE (mode) != VOIDmode
1378      && (((unsignedp ? umul_widen_optab : smul_widen_optab)
1379	   ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
1380	  != CODE_FOR_nothing))
1381    {
1382      temp = expand_binop (GET_MODE_WIDER_MODE (mode),
1383			   unsignedp ? umul_widen_optab : smul_widen_optab,
1384			   op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1385
1386      if (temp != 0)
1387	{
1388	  if (GET_MODE_CLASS (mode) == MODE_INT
1389	      && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1390                                        GET_MODE_BITSIZE (GET_MODE (temp))))
1391	    return gen_lowpart (mode, temp);
1392	  else
1393	    return convert_to_mode (mode, temp, unsignedp);
1394	}
1395    }
1396
1397  /* Look for a wider mode of the same class for which we think we
1398     can open-code the operation.  Check for a widening multiply at the
1399     wider mode as well.  */
1400
1401  if (CLASS_HAS_WIDER_MODES_P (class)
1402      && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1403    for (wider_mode = GET_MODE_WIDER_MODE (mode);
1404	 wider_mode != VOIDmode;
1405	 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1406      {
1407	if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
1408	    || (binoptab == smul_optab
1409		&& GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1410		&& (((unsignedp ? umul_widen_optab : smul_widen_optab)
1411		     ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
1412		    != CODE_FOR_nothing)))
1413	  {
1414	    rtx xop0 = op0, xop1 = op1;
1415	    int no_extend = 0;
1416
1417	    /* For certain integer operations, we need not actually extend
1418	       the narrow operands, as long as we will truncate
1419	       the results to the same narrowness.  */
1420
1421	    if ((binoptab == ior_optab || binoptab == and_optab
1422		 || binoptab == xor_optab
1423		 || binoptab == add_optab || binoptab == sub_optab
1424		 || binoptab == smul_optab || binoptab == ashl_optab)
1425		&& class == MODE_INT)
1426	      no_extend = 1;
1427
1428	    xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1429
1430	    /* The second operand of a shift must always be extended.  */
1431	    xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1432				  no_extend && binoptab != ashl_optab);
1433
1434	    temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1435				 unsignedp, OPTAB_DIRECT);
1436	    if (temp)
1437	      {
1438		if (class != MODE_INT
1439                    || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1440                                               GET_MODE_BITSIZE (wider_mode)))
1441		  {
1442		    if (target == 0)
1443		      target = gen_reg_rtx (mode);
1444		    convert_move (target, temp, 0);
1445		    return target;
1446		  }
1447		else
1448		  return gen_lowpart (mode, temp);
1449	      }
1450	    else
1451	      delete_insns_since (last);
1452	  }
1453      }
1454
1455  /* These can be done a word at a time.  */
1456  if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1457      && class == MODE_INT
1458      && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1459      && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1460    {
1461      int i;
1462      rtx insns;
1463      rtx equiv_value;
1464
1465      /* If TARGET is the same as one of the operands, the REG_EQUAL note
1466	 won't be accurate, so use a new target.  */
1467      if (target == 0 || target == op0 || target == op1)
1468	target = gen_reg_rtx (mode);
1469
1470      start_sequence ();
1471
1472      /* Do the actual arithmetic.  */
1473      for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1474	{
1475	  rtx target_piece = operand_subword (target, i, 1, mode);
1476	  rtx x = expand_binop (word_mode, binoptab,
1477				operand_subword_force (op0, i, mode),
1478				operand_subword_force (op1, i, mode),
1479				target_piece, unsignedp, next_methods);
1480
1481	  if (x == 0)
1482	    break;
1483
1484	  if (target_piece != x)
1485	    emit_move_insn (target_piece, x);
1486	}
1487
1488      insns = get_insns ();
1489      end_sequence ();
1490
1491      if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1492	{
1493	  if (binoptab->code != UNKNOWN)
1494	    equiv_value
1495	      = gen_rtx_fmt_ee (binoptab->code, mode,
1496				copy_rtx (op0), copy_rtx (op1));
1497	  else
1498	    equiv_value = 0;
1499
1500	  emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1501	  return target;
1502	}
1503    }
1504
1505  /* Synthesize double word shifts from single word shifts.  */
1506  if ((binoptab == lshr_optab || binoptab == ashl_optab
1507       || binoptab == ashr_optab)
1508      && class == MODE_INT
1509      && (GET_CODE (op1) == CONST_INT || !optimize_size)
1510      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1511      && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1512      && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1513      && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1514    {
1515      unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1516      enum machine_mode op1_mode;
1517
1518      double_shift_mask = targetm.shift_truncation_mask (mode);
1519      shift_mask = targetm.shift_truncation_mask (word_mode);
1520      op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1521
1522      /* Apply the truncation to constant shifts.  */
1523      if (double_shift_mask > 0 && GET_CODE (op1) == CONST_INT)
1524	op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1525
1526      if (op1 == CONST0_RTX (op1_mode))
1527	return op0;
1528
1529      /* Make sure that this is a combination that expand_doubleword_shift
1530	 can handle.  See the comments there for details.  */
1531      if (double_shift_mask == 0
1532	  || (shift_mask == BITS_PER_WORD - 1
1533	      && double_shift_mask == BITS_PER_WORD * 2 - 1))
1534	{
1535	  rtx insns, equiv_value;
1536	  rtx into_target, outof_target;
1537	  rtx into_input, outof_input;
1538	  int left_shift, outof_word;
1539
1540	  /* If TARGET is the same as one of the operands, the REG_EQUAL note
1541	     won't be accurate, so use a new target.  */
1542	  if (target == 0 || target == op0 || target == op1)
1543	    target = gen_reg_rtx (mode);
1544
1545	  start_sequence ();
1546
1547	  /* OUTOF_* is the word we are shifting bits away from, and
1548	     INTO_* is the word that we are shifting bits towards, thus
1549	     they differ depending on the direction of the shift and
1550	     WORDS_BIG_ENDIAN.  */
1551
1552	  left_shift = binoptab == ashl_optab;
1553	  outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1554
1555	  outof_target = operand_subword (target, outof_word, 1, mode);
1556	  into_target = operand_subword (target, 1 - outof_word, 1, mode);
1557
1558	  outof_input = operand_subword_force (op0, outof_word, mode);
1559	  into_input = operand_subword_force (op0, 1 - outof_word, mode);
1560
1561	  if (expand_doubleword_shift (op1_mode, binoptab,
1562				       outof_input, into_input, op1,
1563				       outof_target, into_target,
1564				       unsignedp, next_methods, shift_mask))
1565	    {
1566	      insns = get_insns ();
1567	      end_sequence ();
1568
1569	      equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1570	      emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1571	      return target;
1572	    }
1573	  end_sequence ();
1574	}
1575    }
1576
1577  /* Synthesize double word rotates from single word shifts.  */
1578  if ((binoptab == rotl_optab || binoptab == rotr_optab)
1579      && class == MODE_INT
1580      && GET_CODE (op1) == CONST_INT
1581      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1582      && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1583      && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1584    {
1585      rtx insns;
1586      rtx into_target, outof_target;
1587      rtx into_input, outof_input;
1588      rtx inter;
1589      int shift_count, left_shift, outof_word;
1590
1591      /* If TARGET is the same as one of the operands, the REG_EQUAL note
1592	 won't be accurate, so use a new target. Do this also if target is not
1593	 a REG, first because having a register instead may open optimization
1594	 opportunities, and second because if target and op0 happen to be MEMs
1595	 designating the same location, we would risk clobbering it too early
1596	 in the code sequence we generate below.  */
1597      if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
1598	target = gen_reg_rtx (mode);
1599
1600      start_sequence ();
1601
1602      shift_count = INTVAL (op1);
1603
1604      /* OUTOF_* is the word we are shifting bits away from, and
1605	 INTO_* is the word that we are shifting bits towards, thus
1606	 they differ depending on the direction of the shift and
1607	 WORDS_BIG_ENDIAN.  */
1608
1609      left_shift = (binoptab == rotl_optab);
1610      outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1611
1612      outof_target = operand_subword (target, outof_word, 1, mode);
1613      into_target = operand_subword (target, 1 - outof_word, 1, mode);
1614
1615      outof_input = operand_subword_force (op0, outof_word, mode);
1616      into_input = operand_subword_force (op0, 1 - outof_word, mode);
1617
1618      if (shift_count == BITS_PER_WORD)
1619	{
1620	  /* This is just a word swap.  */
1621	  emit_move_insn (outof_target, into_input);
1622	  emit_move_insn (into_target, outof_input);
1623	  inter = const0_rtx;
1624	}
1625      else
1626	{
1627	  rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1628	  rtx first_shift_count, second_shift_count;
1629	  optab reverse_unsigned_shift, unsigned_shift;
1630
1631	  reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1632				    ? lshr_optab : ashl_optab);
1633
1634	  unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1635			    ? ashl_optab : lshr_optab);
1636
1637	  if (shift_count > BITS_PER_WORD)
1638	    {
1639	      first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1640	      second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1641	    }
1642	  else
1643	    {
1644	      first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1645	      second_shift_count = GEN_INT (shift_count);
1646	    }
1647
1648	  into_temp1 = expand_binop (word_mode, unsigned_shift,
1649				     outof_input, first_shift_count,
1650				     NULL_RTX, unsignedp, next_methods);
1651	  into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1652				     into_input, second_shift_count,
1653				     NULL_RTX, unsignedp, next_methods);
1654
1655	  if (into_temp1 != 0 && into_temp2 != 0)
1656	    inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1657				  into_target, unsignedp, next_methods);
1658	  else
1659	    inter = 0;
1660
1661	  if (inter != 0 && inter != into_target)
1662	    emit_move_insn (into_target, inter);
1663
1664	  outof_temp1 = expand_binop (word_mode, unsigned_shift,
1665				      into_input, first_shift_count,
1666				      NULL_RTX, unsignedp, next_methods);
1667	  outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1668				      outof_input, second_shift_count,
1669				      NULL_RTX, unsignedp, next_methods);
1670
1671	  if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1672	    inter = expand_binop (word_mode, ior_optab,
1673				  outof_temp1, outof_temp2,
1674				  outof_target, unsignedp, next_methods);
1675
1676	  if (inter != 0 && inter != outof_target)
1677	    emit_move_insn (outof_target, inter);
1678	}
1679
1680      insns = get_insns ();
1681      end_sequence ();
1682
1683      if (inter != 0)
1684	{
1685	  /* One may be tempted to wrap the insns in a REG_NO_CONFLICT
1686	     block to help the register allocator a bit.  But a multi-word
1687	     rotate will need all the input bits when setting the output
1688	     bits, so there clearly is a conflict between the input and
1689	     output registers.  So we can't use a no-conflict block here.  */
1690	  emit_insn (insns);
1691	  return target;
1692	}
1693    }
1694
1695  /* These can be done a word at a time by propagating carries.  */
1696  if ((binoptab == add_optab || binoptab == sub_optab)
1697      && class == MODE_INT
1698      && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1699      && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1700    {
1701      unsigned int i;
1702      optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1703      const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1704      rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1705      rtx xop0, xop1, xtarget;
1706
1707      /* We can handle either a 1 or -1 value for the carry.  If STORE_FLAG
1708	 value is one of those, use it.  Otherwise, use 1 since it is the
1709	 one easiest to get.  */
1710#if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1711      int normalizep = STORE_FLAG_VALUE;
1712#else
1713      int normalizep = 1;
1714#endif
1715
1716      /* Prepare the operands.  */
1717      xop0 = force_reg (mode, op0);
1718      xop1 = force_reg (mode, op1);
1719
1720      xtarget = gen_reg_rtx (mode);
1721
1722      if (target == 0 || !REG_P (target))
1723	target = xtarget;
1724
1725      /* Indicate for flow that the entire target reg is being set.  */
1726      if (REG_P (target))
1727	emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
1728
1729      /* Do the actual arithmetic.  */
1730      for (i = 0; i < nwords; i++)
1731	{
1732	  int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1733	  rtx target_piece = operand_subword (xtarget, index, 1, mode);
1734	  rtx op0_piece = operand_subword_force (xop0, index, mode);
1735	  rtx op1_piece = operand_subword_force (xop1, index, mode);
1736	  rtx x;
1737
1738	  /* Main add/subtract of the input operands.  */
1739	  x = expand_binop (word_mode, binoptab,
1740			    op0_piece, op1_piece,
1741			    target_piece, unsignedp, next_methods);
1742	  if (x == 0)
1743	    break;
1744
1745	  if (i + 1 < nwords)
1746	    {
1747	      /* Store carry from main add/subtract.  */
1748	      carry_out = gen_reg_rtx (word_mode);
1749	      carry_out = emit_store_flag_force (carry_out,
1750						 (binoptab == add_optab
1751						  ? LT : GT),
1752						 x, op0_piece,
1753						 word_mode, 1, normalizep);
1754	    }
1755
1756	  if (i > 0)
1757	    {
1758	      rtx newx;
1759
1760	      /* Add/subtract previous carry to main result.  */
1761	      newx = expand_binop (word_mode,
1762				   normalizep == 1 ? binoptab : otheroptab,
1763				   x, carry_in,
1764				   NULL_RTX, 1, next_methods);
1765
1766	      if (i + 1 < nwords)
1767		{
1768		  /* Get out carry from adding/subtracting carry in.  */
1769		  rtx carry_tmp = gen_reg_rtx (word_mode);
1770		  carry_tmp = emit_store_flag_force (carry_tmp,
1771						     (binoptab == add_optab
1772						      ? LT : GT),
1773						     newx, x,
1774						     word_mode, 1, normalizep);
1775
1776		  /* Logical-ior the two poss. carry together.  */
1777		  carry_out = expand_binop (word_mode, ior_optab,
1778					    carry_out, carry_tmp,
1779					    carry_out, 0, next_methods);
1780		  if (carry_out == 0)
1781		    break;
1782		}
1783	      emit_move_insn (target_piece, newx);
1784	    }
1785	  else
1786	    {
1787	      if (x != target_piece)
1788		emit_move_insn (target_piece, x);
1789	    }
1790
1791	  carry_in = carry_out;
1792	}
1793
1794      if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1795	{
1796	  if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
1797	      || ! rtx_equal_p (target, xtarget))
1798	    {
1799	      rtx temp = emit_move_insn (target, xtarget);
1800
1801	      set_unique_reg_note (temp,
1802				   REG_EQUAL,
1803				   gen_rtx_fmt_ee (binoptab->code, mode,
1804						   copy_rtx (xop0),
1805						   copy_rtx (xop1)));
1806	    }
1807	  else
1808	    target = xtarget;
1809
1810	  return target;
1811	}
1812
1813      else
1814	delete_insns_since (last);
1815    }
1816
1817  /* Attempt to synthesize double word multiplies using a sequence of word
1818     mode multiplications.  We first attempt to generate a sequence using a
1819     more efficient unsigned widening multiply, and if that fails we then
1820     try using a signed widening multiply.  */
1821
1822  if (binoptab == smul_optab
1823      && class == MODE_INT
1824      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1825      && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1826      && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1827    {
1828      rtx product = NULL_RTX;
1829
1830      if (umul_widen_optab->handlers[(int) mode].insn_code
1831	  != CODE_FOR_nothing)
1832	{
1833	  product = expand_doubleword_mult (mode, op0, op1, target,
1834					    true, methods);
1835	  if (!product)
1836	    delete_insns_since (last);
1837	}
1838
1839      if (product == NULL_RTX
1840	  && smul_widen_optab->handlers[(int) mode].insn_code
1841	     != CODE_FOR_nothing)
1842	{
1843	  product = expand_doubleword_mult (mode, op0, op1, target,
1844					    false, methods);
1845	  if (!product)
1846	    delete_insns_since (last);
1847	}
1848
1849      if (product != NULL_RTX)
1850	{
1851	  if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1852	    {
1853	      temp = emit_move_insn (target ? target : product, product);
1854	      set_unique_reg_note (temp,
1855				   REG_EQUAL,
1856				   gen_rtx_fmt_ee (MULT, mode,
1857						   copy_rtx (op0),
1858						   copy_rtx (op1)));
1859	    }
1860	  return product;
1861	}
1862    }
1863
1864  /* It can't be open-coded in this mode.
1865     Use a library call if one is available and caller says that's ok.  */
1866
1867  if (binoptab->handlers[(int) mode].libfunc
1868      && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1869    {
1870      rtx insns;
1871      rtx op1x = op1;
1872      enum machine_mode op1_mode = mode;
1873      rtx value;
1874
1875      start_sequence ();
1876
1877      if (shift_op)
1878	{
1879	  op1_mode = word_mode;
1880	  /* Specify unsigned here,
1881	     since negative shift counts are meaningless.  */
1882	  op1x = convert_to_mode (word_mode, op1, 1);
1883	}
1884
1885      if (GET_MODE (op0) != VOIDmode
1886	  && GET_MODE (op0) != mode)
1887	op0 = convert_to_mode (mode, op0, unsignedp);
1888
1889      /* Pass 1 for NO_QUEUE so we don't lose any increments
1890	 if the libcall is cse'd or moved.  */
1891      value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1892				       NULL_RTX, LCT_CONST, mode, 2,
1893				       op0, mode, op1x, op1_mode);
1894
1895      insns = get_insns ();
1896      end_sequence ();
1897
1898      target = gen_reg_rtx (mode);
1899      emit_libcall_block (insns, target, value,
1900			  gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1901
1902      return target;
1903    }
1904
1905  delete_insns_since (last);
1906
1907  /* It can't be done in this mode.  Can we do it in a wider mode?  */
1908
1909  if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1910	 || methods == OPTAB_MUST_WIDEN))
1911    {
1912      /* Caller says, don't even try.  */
1913      delete_insns_since (entry_last);
1914      return 0;
1915    }
1916
1917  /* Compute the value of METHODS to pass to recursive calls.
1918     Don't allow widening to be tried recursively.  */
1919
1920  methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1921
1922  /* Look for a wider mode of the same class for which it appears we can do
1923     the operation.  */
1924
1925  if (CLASS_HAS_WIDER_MODES_P (class))
1926    {
1927      for (wider_mode = GET_MODE_WIDER_MODE (mode);
1928	   wider_mode != VOIDmode;
1929	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1930	{
1931	  if ((binoptab->handlers[(int) wider_mode].insn_code
1932	       != CODE_FOR_nothing)
1933	      || (methods == OPTAB_LIB
1934		  && binoptab->handlers[(int) wider_mode].libfunc))
1935	    {
1936	      rtx xop0 = op0, xop1 = op1;
1937	      int no_extend = 0;
1938
1939	      /* For certain integer operations, we need not actually extend
1940		 the narrow operands, as long as we will truncate
1941		 the results to the same narrowness.  */
1942
1943	      if ((binoptab == ior_optab || binoptab == and_optab
1944		   || binoptab == xor_optab
1945		   || binoptab == add_optab || binoptab == sub_optab
1946		   || binoptab == smul_optab || binoptab == ashl_optab)
1947		  && class == MODE_INT)
1948		no_extend = 1;
1949
1950	      xop0 = widen_operand (xop0, wider_mode, mode,
1951				    unsignedp, no_extend);
1952
1953	      /* The second operand of a shift must always be extended.  */
1954	      xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1955				    no_extend && binoptab != ashl_optab);
1956
1957	      temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1958				   unsignedp, methods);
1959	      if (temp)
1960		{
1961		  if (class != MODE_INT
1962		      || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1963						 GET_MODE_BITSIZE (wider_mode)))
1964		    {
1965		      if (target == 0)
1966			target = gen_reg_rtx (mode);
1967		      convert_move (target, temp, 0);
1968		      return target;
1969		    }
1970		  else
1971		    return gen_lowpart (mode, temp);
1972		}
1973	      else
1974		delete_insns_since (last);
1975	    }
1976	}
1977    }
1978
1979  delete_insns_since (entry_last);
1980  return 0;
1981}
1982
1983/* Expand a binary operator which has both signed and unsigned forms.
1984   UOPTAB is the optab for unsigned operations, and SOPTAB is for
1985   signed operations.
1986
1987   If we widen unsigned operands, we may use a signed wider operation instead
1988   of an unsigned wider operation, since the result would be the same.  */
1989
1990rtx
1991sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
1992		   rtx op0, rtx op1, rtx target, int unsignedp,
1993		   enum optab_methods methods)
1994{
1995  rtx temp;
1996  optab direct_optab = unsignedp ? uoptab : soptab;
1997  struct optab wide_soptab;
1998
1999  /* Do it without widening, if possible.  */
2000  temp = expand_binop (mode, direct_optab, op0, op1, target,
2001		       unsignedp, OPTAB_DIRECT);
2002  if (temp || methods == OPTAB_DIRECT)
2003    return temp;
2004
2005  /* Try widening to a signed int.  Make a fake signed optab that
2006     hides any signed insn for direct use.  */
2007  wide_soptab = *soptab;
2008  wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
2009  wide_soptab.handlers[(int) mode].libfunc = 0;
2010
2011  temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2012		       unsignedp, OPTAB_WIDEN);
2013
2014  /* For unsigned operands, try widening to an unsigned int.  */
2015  if (temp == 0 && unsignedp)
2016    temp = expand_binop (mode, uoptab, op0, op1, target,
2017			 unsignedp, OPTAB_WIDEN);
2018  if (temp || methods == OPTAB_WIDEN)
2019    return temp;
2020
2021  /* Use the right width lib call if that exists.  */
2022  temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
2023  if (temp || methods == OPTAB_LIB)
2024    return temp;
2025
2026  /* Must widen and use a lib call, use either signed or unsigned.  */
2027  temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2028		       unsignedp, methods);
2029  if (temp != 0)
2030    return temp;
2031  if (unsignedp)
2032    return expand_binop (mode, uoptab, op0, op1, target,
2033			 unsignedp, methods);
2034  return 0;
2035}
2036
2037/* Generate code to perform an operation specified by UNOPPTAB
2038   on operand OP0, with two results to TARG0 and TARG1.
2039   We assume that the order of the operands for the instruction
2040   is TARG0, TARG1, OP0.
2041
2042   Either TARG0 or TARG1 may be zero, but what that means is that
2043   the result is not actually wanted.  We will generate it into
2044   a dummy pseudo-reg and discard it.  They may not both be zero.
2045
2046   Returns 1 if this operation can be performed; 0 if not.  */
2047
2048int
2049expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2050		    int unsignedp)
2051{
2052  enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2053  enum mode_class class;
2054  enum machine_mode wider_mode;
2055  rtx entry_last = get_last_insn ();
2056  rtx last;
2057
2058  class = GET_MODE_CLASS (mode);
2059
2060  if (!targ0)
2061    targ0 = gen_reg_rtx (mode);
2062  if (!targ1)
2063    targ1 = gen_reg_rtx (mode);
2064
2065  /* Record where to go back to if we fail.  */
2066  last = get_last_insn ();
2067
2068  if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2069    {
2070      int icode = (int) unoptab->handlers[(int) mode].insn_code;
2071      enum machine_mode mode0 = insn_data[icode].operand[2].mode;
2072      rtx pat;
2073      rtx xop0 = op0;
2074
2075      if (GET_MODE (xop0) != VOIDmode
2076	  && GET_MODE (xop0) != mode0)
2077	xop0 = convert_to_mode (mode0, xop0, unsignedp);
2078
2079      /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2080      if (!insn_data[icode].operand[2].predicate (xop0, mode0))
2081	xop0 = copy_to_mode_reg (mode0, xop0);
2082
2083      /* We could handle this, but we should always be called with a pseudo
2084	 for our targets and all insns should take them as outputs.  */
2085      gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2086      gcc_assert (insn_data[icode].operand[1].predicate (targ1, mode));
2087
2088      pat = GEN_FCN (icode) (targ0, targ1, xop0);
2089      if (pat)
2090	{
2091	  emit_insn (pat);
2092	  return 1;
2093	}
2094      else
2095	delete_insns_since (last);
2096    }
2097
2098  /* It can't be done in this mode.  Can we do it in a wider mode?  */
2099
2100  if (CLASS_HAS_WIDER_MODES_P (class))
2101    {
2102      for (wider_mode = GET_MODE_WIDER_MODE (mode);
2103	   wider_mode != VOIDmode;
2104	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2105	{
2106	  if (unoptab->handlers[(int) wider_mode].insn_code
2107	      != CODE_FOR_nothing)
2108	    {
2109	      rtx t0 = gen_reg_rtx (wider_mode);
2110	      rtx t1 = gen_reg_rtx (wider_mode);
2111	      rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2112
2113	      if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2114		{
2115		  convert_move (targ0, t0, unsignedp);
2116		  convert_move (targ1, t1, unsignedp);
2117		  return 1;
2118		}
2119	      else
2120		delete_insns_since (last);
2121	    }
2122	}
2123    }
2124
2125  delete_insns_since (entry_last);
2126  return 0;
2127}
2128
2129/* Generate code to perform an operation specified by BINOPTAB
2130   on operands OP0 and OP1, with two results to TARG1 and TARG2.
2131   We assume that the order of the operands for the instruction
2132   is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2133   [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2134
2135   Either TARG0 or TARG1 may be zero, but what that means is that
2136   the result is not actually wanted.  We will generate it into
2137   a dummy pseudo-reg and discard it.  They may not both be zero.
2138
2139   Returns 1 if this operation can be performed; 0 if not.  */
2140
2141int
2142expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2143		     int unsignedp)
2144{
2145  enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2146  enum mode_class class;
2147  enum machine_mode wider_mode;
2148  rtx entry_last = get_last_insn ();
2149  rtx last;
2150
2151  class = GET_MODE_CLASS (mode);
2152
2153  /* If we are inside an appropriately-short loop and we are optimizing,
2154     force expensive constants into a register.  */
2155  if (CONSTANT_P (op0) && optimize
2156      && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
2157    op0 = force_reg (mode, op0);
2158
2159  if (CONSTANT_P (op1) && optimize
2160      && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
2161    op1 = force_reg (mode, op1);
2162
2163  if (!targ0)
2164    targ0 = gen_reg_rtx (mode);
2165  if (!targ1)
2166    targ1 = gen_reg_rtx (mode);
2167
2168  /* Record where to go back to if we fail.  */
2169  last = get_last_insn ();
2170
2171  if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2172    {
2173      int icode = (int) binoptab->handlers[(int) mode].insn_code;
2174      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2175      enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2176      rtx pat;
2177      rtx xop0 = op0, xop1 = op1;
2178
2179      /* In case the insn wants input operands in modes different from
2180	 those of the actual operands, convert the operands.  It would
2181	 seem that we don't need to convert CONST_INTs, but we do, so
2182	 that they're properly zero-extended, sign-extended or truncated
2183	 for their mode.  */
2184
2185      if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
2186	xop0 = convert_modes (mode0,
2187			      GET_MODE (op0) != VOIDmode
2188			      ? GET_MODE (op0)
2189			      : mode,
2190			      xop0, unsignedp);
2191
2192      if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
2193	xop1 = convert_modes (mode1,
2194			      GET_MODE (op1) != VOIDmode
2195			      ? GET_MODE (op1)
2196			      : mode,
2197			      xop1, unsignedp);
2198
2199      /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2200      if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2201	xop0 = copy_to_mode_reg (mode0, xop0);
2202
2203      if (!insn_data[icode].operand[2].predicate (xop1, mode1))
2204	xop1 = copy_to_mode_reg (mode1, xop1);
2205
2206      /* We could handle this, but we should always be called with a pseudo
2207	 for our targets and all insns should take them as outputs.  */
2208      gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2209      gcc_assert (insn_data[icode].operand[3].predicate (targ1, mode));
2210
2211      pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2212      if (pat)
2213	{
2214	  emit_insn (pat);
2215	  return 1;
2216	}
2217      else
2218	delete_insns_since (last);
2219    }
2220
2221  /* It can't be done in this mode.  Can we do it in a wider mode?  */
2222
2223  if (CLASS_HAS_WIDER_MODES_P (class))
2224    {
2225      for (wider_mode = GET_MODE_WIDER_MODE (mode);
2226	   wider_mode != VOIDmode;
2227	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2228	{
2229	  if (binoptab->handlers[(int) wider_mode].insn_code
2230	      != CODE_FOR_nothing)
2231	    {
2232	      rtx t0 = gen_reg_rtx (wider_mode);
2233	      rtx t1 = gen_reg_rtx (wider_mode);
2234	      rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2235	      rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2236
2237	      if (expand_twoval_binop (binoptab, cop0, cop1,
2238				       t0, t1, unsignedp))
2239		{
2240		  convert_move (targ0, t0, unsignedp);
2241		  convert_move (targ1, t1, unsignedp);
2242		  return 1;
2243		}
2244	      else
2245		delete_insns_since (last);
2246	    }
2247	}
2248    }
2249
2250  delete_insns_since (entry_last);
2251  return 0;
2252}
2253
2254/* Expand the two-valued library call indicated by BINOPTAB, but
2255   preserve only one of the values.  If TARG0 is non-NULL, the first
2256   value is placed into TARG0; otherwise the second value is placed
2257   into TARG1.  Exactly one of TARG0 and TARG1 must be non-NULL.  The
2258   value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2259   This routine assumes that the value returned by the library call is
2260   as if the return value was of an integral mode twice as wide as the
2261   mode of OP0.  Returns 1 if the call was successful.  */
2262
2263bool
2264expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2265			     rtx targ0, rtx targ1, enum rtx_code code)
2266{
2267  enum machine_mode mode;
2268  enum machine_mode libval_mode;
2269  rtx libval;
2270  rtx insns;
2271
2272  /* Exactly one of TARG0 or TARG1 should be non-NULL.  */
2273  gcc_assert (!targ0 != !targ1);
2274
2275  mode = GET_MODE (op0);
2276  if (!binoptab->handlers[(int) mode].libfunc)
2277    return false;
2278
2279  /* The value returned by the library function will have twice as
2280     many bits as the nominal MODE.  */
2281  libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2282					MODE_INT);
2283  start_sequence ();
2284  libval = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
2285				    NULL_RTX, LCT_CONST,
2286				    libval_mode, 2,
2287				    op0, mode,
2288				    op1, mode);
2289  /* Get the part of VAL containing the value that we want.  */
2290  libval = simplify_gen_subreg (mode, libval, libval_mode,
2291				targ0 ? 0 : GET_MODE_SIZE (mode));
2292  insns = get_insns ();
2293  end_sequence ();
2294  /* Move the into the desired location.  */
2295  emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2296		      gen_rtx_fmt_ee (code, mode, op0, op1));
2297
2298  return true;
2299}
2300
2301
2302/* Wrapper around expand_unop which takes an rtx code to specify
2303   the operation to perform, not an optab pointer.  All other
2304   arguments are the same.  */
2305rtx
2306expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2307		    rtx target, int unsignedp)
2308{
2309  optab unop = code_to_optab[(int) code];
2310  gcc_assert (unop);
2311
2312  return expand_unop (mode, unop, op0, target, unsignedp);
2313}
2314
2315/* Try calculating
2316	(clz:narrow x)
2317   as
2318	(clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).  */
2319static rtx
2320widen_clz (enum machine_mode mode, rtx op0, rtx target)
2321{
2322  enum mode_class class = GET_MODE_CLASS (mode);
2323  if (CLASS_HAS_WIDER_MODES_P (class))
2324    {
2325      enum machine_mode wider_mode;
2326      for (wider_mode = GET_MODE_WIDER_MODE (mode);
2327	   wider_mode != VOIDmode;
2328	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2329	{
2330	  if (clz_optab->handlers[(int) wider_mode].insn_code
2331	      != CODE_FOR_nothing)
2332	    {
2333	      rtx xop0, temp, last;
2334
2335	      last = get_last_insn ();
2336
2337	      if (target == 0)
2338		target = gen_reg_rtx (mode);
2339	      xop0 = widen_operand (op0, wider_mode, mode, true, false);
2340	      temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2341	      if (temp != 0)
2342		temp = expand_binop (wider_mode, sub_optab, temp,
2343				     GEN_INT (GET_MODE_BITSIZE (wider_mode)
2344					      - GET_MODE_BITSIZE (mode)),
2345				     target, true, OPTAB_DIRECT);
2346	      if (temp == 0)
2347		delete_insns_since (last);
2348
2349	      return temp;
2350	    }
2351	}
2352    }
2353  return 0;
2354}
2355
2356/* Try calculating (parity x) as (and (popcount x) 1), where
2357   popcount can also be done in a wider mode.  */
2358static rtx
2359expand_parity (enum machine_mode mode, rtx op0, rtx target)
2360{
2361  enum mode_class class = GET_MODE_CLASS (mode);
2362  if (CLASS_HAS_WIDER_MODES_P (class))
2363    {
2364      enum machine_mode wider_mode;
2365      for (wider_mode = mode; wider_mode != VOIDmode;
2366	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2367	{
2368	  if (popcount_optab->handlers[(int) wider_mode].insn_code
2369	      != CODE_FOR_nothing)
2370	    {
2371	      rtx xop0, temp, last;
2372
2373	      last = get_last_insn ();
2374
2375	      if (target == 0)
2376		target = gen_reg_rtx (mode);
2377	      xop0 = widen_operand (op0, wider_mode, mode, true, false);
2378	      temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2379				  true);
2380	      if (temp != 0)
2381		temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2382				     target, true, OPTAB_DIRECT);
2383	      if (temp == 0)
2384		delete_insns_since (last);
2385
2386	      return temp;
2387	    }
2388	}
2389    }
2390  return 0;
2391}
2392
2393/* Extract the OMODE lowpart from VAL, which has IMODE.  Under certain
2394   conditions, VAL may already be a SUBREG against which we cannot generate
2395   a further SUBREG.  In this case, we expect forcing the value into a
2396   register will work around the situation.  */
2397
2398static rtx
2399lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2400			   enum machine_mode imode)
2401{
2402  rtx ret;
2403  ret = lowpart_subreg (omode, val, imode);
2404  if (ret == NULL)
2405    {
2406      val = force_reg (imode, val);
2407      ret = lowpart_subreg (omode, val, imode);
2408      gcc_assert (ret != NULL);
2409    }
2410  return ret;
2411}
2412
2413/* Expand a floating point absolute value or negation operation via a
2414   logical operation on the sign bit.  */
2415
2416static rtx
2417expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2418		   rtx op0, rtx target)
2419{
2420  const struct real_format *fmt;
2421  int bitpos, word, nwords, i;
2422  enum machine_mode imode;
2423  HOST_WIDE_INT hi, lo;
2424  rtx temp, insns;
2425
2426  /* The format has to have a simple sign bit.  */
2427  fmt = REAL_MODE_FORMAT (mode);
2428  if (fmt == NULL)
2429    return NULL_RTX;
2430
2431  bitpos = fmt->signbit_rw;
2432  if (bitpos < 0)
2433    return NULL_RTX;
2434
2435  /* Don't create negative zeros if the format doesn't support them.  */
2436  if (code == NEG && !fmt->has_signed_zero)
2437    return NULL_RTX;
2438
2439  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2440    {
2441      imode = int_mode_for_mode (mode);
2442      if (imode == BLKmode)
2443	return NULL_RTX;
2444      word = 0;
2445      nwords = 1;
2446    }
2447  else
2448    {
2449      imode = word_mode;
2450
2451      if (FLOAT_WORDS_BIG_ENDIAN)
2452	word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2453      else
2454	word = bitpos / BITS_PER_WORD;
2455      bitpos = bitpos % BITS_PER_WORD;
2456      nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2457    }
2458
2459  if (bitpos < HOST_BITS_PER_WIDE_INT)
2460    {
2461      hi = 0;
2462      lo = (HOST_WIDE_INT) 1 << bitpos;
2463    }
2464  else
2465    {
2466      hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2467      lo = 0;
2468    }
2469  if (code == ABS)
2470    lo = ~lo, hi = ~hi;
2471
2472  if (target == 0 || target == op0)
2473    target = gen_reg_rtx (mode);
2474
2475  if (nwords > 1)
2476    {
2477      start_sequence ();
2478
2479      for (i = 0; i < nwords; ++i)
2480	{
2481	  rtx targ_piece = operand_subword (target, i, 1, mode);
2482	  rtx op0_piece = operand_subword_force (op0, i, mode);
2483
2484	  if (i == word)
2485	    {
2486	      temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2487				   op0_piece,
2488				   immed_double_const (lo, hi, imode),
2489				   targ_piece, 1, OPTAB_LIB_WIDEN);
2490	      if (temp != targ_piece)
2491		emit_move_insn (targ_piece, temp);
2492	    }
2493	  else
2494	    emit_move_insn (targ_piece, op0_piece);
2495	}
2496
2497      insns = get_insns ();
2498      end_sequence ();
2499
2500      temp = gen_rtx_fmt_e (code, mode, copy_rtx (op0));
2501      emit_no_conflict_block (insns, target, op0, NULL_RTX, temp);
2502    }
2503  else
2504    {
2505      temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2506			   gen_lowpart (imode, op0),
2507			   immed_double_const (lo, hi, imode),
2508		           gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2509      target = lowpart_subreg_maybe_copy (mode, temp, imode);
2510
2511      set_unique_reg_note (get_last_insn (), REG_EQUAL,
2512			   gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
2513    }
2514
2515  return target;
2516}
2517
2518/* Generate code to perform an operation specified by UNOPTAB
2519   on operand OP0, with result having machine-mode MODE.
2520
2521   UNSIGNEDP is for the case where we have to widen the operands
2522   to perform the operation.  It says to use zero-extension.
2523
2524   If TARGET is nonzero, the value
2525   is generated there, if it is convenient to do so.
2526   In all cases an rtx is returned for the locus of the value;
2527   this may or may not be TARGET.  */
2528
2529rtx
2530expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2531	     int unsignedp)
2532{
2533  enum mode_class class;
2534  enum machine_mode wider_mode;
2535  rtx temp;
2536  rtx last = get_last_insn ();
2537  rtx pat;
2538
2539  class = GET_MODE_CLASS (mode);
2540
2541  if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2542    {
2543      int icode = (int) unoptab->handlers[(int) mode].insn_code;
2544      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2545      rtx xop0 = op0;
2546
2547      if (target)
2548	temp = target;
2549      else
2550	temp = gen_reg_rtx (mode);
2551
2552      if (GET_MODE (xop0) != VOIDmode
2553	  && GET_MODE (xop0) != mode0)
2554	xop0 = convert_to_mode (mode0, xop0, unsignedp);
2555
2556      /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
2557
2558      if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2559	xop0 = copy_to_mode_reg (mode0, xop0);
2560
2561      if (!insn_data[icode].operand[0].predicate (temp, mode))
2562	temp = gen_reg_rtx (mode);
2563
2564      pat = GEN_FCN (icode) (temp, xop0);
2565      if (pat)
2566	{
2567	  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2568	      && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2569	    {
2570	      delete_insns_since (last);
2571	      return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2572	    }
2573
2574	  emit_insn (pat);
2575
2576	  return temp;
2577	}
2578      else
2579	delete_insns_since (last);
2580    }
2581
2582  /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
2583
2584  /* Widening clz needs special treatment.  */
2585  if (unoptab == clz_optab)
2586    {
2587      temp = widen_clz (mode, op0, target);
2588      if (temp)
2589	return temp;
2590      else
2591	goto try_libcall;
2592    }
2593
2594  if (CLASS_HAS_WIDER_MODES_P (class))
2595    for (wider_mode = GET_MODE_WIDER_MODE (mode);
2596	 wider_mode != VOIDmode;
2597	 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2598      {
2599	if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2600	  {
2601	    rtx xop0 = op0;
2602
2603	    /* For certain operations, we need not actually extend
2604	       the narrow operand, as long as we will truncate the
2605	       results to the same narrowness.  */
2606
2607	    xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2608				  (unoptab == neg_optab
2609				   || unoptab == one_cmpl_optab)
2610				  && class == MODE_INT);
2611
2612	    temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2613				unsignedp);
2614
2615	    if (temp)
2616	      {
2617		if (class != MODE_INT
2618		    || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
2619					       GET_MODE_BITSIZE (wider_mode)))
2620		  {
2621		    if (target == 0)
2622		      target = gen_reg_rtx (mode);
2623		    convert_move (target, temp, 0);
2624		    return target;
2625		  }
2626		else
2627		  return gen_lowpart (mode, temp);
2628	      }
2629	    else
2630	      delete_insns_since (last);
2631	  }
2632      }
2633
2634  /* These can be done a word at a time.  */
2635  if (unoptab == one_cmpl_optab
2636      && class == MODE_INT
2637      && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2638      && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2639    {
2640      int i;
2641      rtx insns;
2642
2643      if (target == 0 || target == op0)
2644	target = gen_reg_rtx (mode);
2645
2646      start_sequence ();
2647
2648      /* Do the actual arithmetic.  */
2649      for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2650	{
2651	  rtx target_piece = operand_subword (target, i, 1, mode);
2652	  rtx x = expand_unop (word_mode, unoptab,
2653			       operand_subword_force (op0, i, mode),
2654			       target_piece, unsignedp);
2655
2656	  if (target_piece != x)
2657	    emit_move_insn (target_piece, x);
2658	}
2659
2660      insns = get_insns ();
2661      end_sequence ();
2662
2663      emit_no_conflict_block (insns, target, op0, NULL_RTX,
2664			      gen_rtx_fmt_e (unoptab->code, mode,
2665					     copy_rtx (op0)));
2666      return target;
2667    }
2668
2669  if (unoptab->code == NEG)
2670    {
2671      /* Try negating floating point values by flipping the sign bit.  */
2672      if (SCALAR_FLOAT_MODE_P (mode))
2673	{
2674	  temp = expand_absneg_bit (NEG, mode, op0, target);
2675	  if (temp)
2676	    return temp;
2677	}
2678
2679      /* If there is no negation pattern, and we have no negative zero,
2680	 try subtracting from zero.  */
2681      if (!HONOR_SIGNED_ZEROS (mode))
2682	{
2683	  temp = expand_binop (mode, (unoptab == negv_optab
2684				      ? subv_optab : sub_optab),
2685			       CONST0_RTX (mode), op0, target,
2686			       unsignedp, OPTAB_DIRECT);
2687	  if (temp)
2688	    return temp;
2689	}
2690    }
2691
2692  /* Try calculating parity (x) as popcount (x) % 2.  */
2693  if (unoptab == parity_optab)
2694    {
2695      temp = expand_parity (mode, op0, target);
2696      if (temp)
2697	return temp;
2698    }
2699
2700 try_libcall:
2701  /* Now try a library call in this mode.  */
2702  if (unoptab->handlers[(int) mode].libfunc)
2703    {
2704      rtx insns;
2705      rtx value;
2706      enum machine_mode outmode = mode;
2707
2708      /* All of these functions return small values.  Thus we choose to
2709	 have them return something that isn't a double-word.  */
2710      if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2711	  || unoptab == popcount_optab || unoptab == parity_optab)
2712	outmode
2713	    = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
2714
2715      start_sequence ();
2716
2717      /* Pass 1 for NO_QUEUE so we don't lose any increments
2718	 if the libcall is cse'd or moved.  */
2719      value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2720				       NULL_RTX, LCT_CONST, outmode,
2721				       1, op0, mode);
2722      insns = get_insns ();
2723      end_sequence ();
2724
2725      target = gen_reg_rtx (outmode);
2726      emit_libcall_block (insns, target, value,
2727			  gen_rtx_fmt_e (unoptab->code, outmode, op0));
2728
2729      return target;
2730    }
2731
2732  /* It can't be done in this mode.  Can we do it in a wider mode?  */
2733
2734  if (CLASS_HAS_WIDER_MODES_P (class))
2735    {
2736      for (wider_mode = GET_MODE_WIDER_MODE (mode);
2737	   wider_mode != VOIDmode;
2738	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2739	{
2740	  if ((unoptab->handlers[(int) wider_mode].insn_code
2741	       != CODE_FOR_nothing)
2742	      || unoptab->handlers[(int) wider_mode].libfunc)
2743	    {
2744	      rtx xop0 = op0;
2745
2746	      /* For certain operations, we need not actually extend
2747		 the narrow operand, as long as we will truncate the
2748		 results to the same narrowness.  */
2749
2750	      xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2751				    (unoptab == neg_optab
2752				     || unoptab == one_cmpl_optab)
2753				    && class == MODE_INT);
2754
2755	      temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2756				  unsignedp);
2757
2758	      /* If we are generating clz using wider mode, adjust the
2759		 result.  */
2760	      if (unoptab == clz_optab && temp != 0)
2761		temp = expand_binop (wider_mode, sub_optab, temp,
2762				     GEN_INT (GET_MODE_BITSIZE (wider_mode)
2763					      - GET_MODE_BITSIZE (mode)),
2764				     target, true, OPTAB_DIRECT);
2765
2766	      if (temp)
2767		{
2768		  if (class != MODE_INT)
2769		    {
2770		      if (target == 0)
2771			target = gen_reg_rtx (mode);
2772		      convert_move (target, temp, 0);
2773		      return target;
2774		    }
2775		  else
2776		    return gen_lowpart (mode, temp);
2777		}
2778	      else
2779		delete_insns_since (last);
2780	    }
2781	}
2782    }
2783
2784  /* One final attempt at implementing negation via subtraction,
2785     this time allowing widening of the operand.  */
2786  if (unoptab->code == NEG && !HONOR_SIGNED_ZEROS (mode))
2787    {
2788      rtx temp;
2789      temp = expand_binop (mode,
2790                           unoptab == negv_optab ? subv_optab : sub_optab,
2791                           CONST0_RTX (mode), op0,
2792                           target, unsignedp, OPTAB_LIB_WIDEN);
2793      if (temp)
2794        return temp;
2795    }
2796
2797  return 0;
2798}
2799
2800/* Emit code to compute the absolute value of OP0, with result to
2801   TARGET if convenient.  (TARGET may be 0.)  The return value says
2802   where the result actually is to be found.
2803
2804   MODE is the mode of the operand; the mode of the result is
2805   different but can be deduced from MODE.
2806
2807 */
2808
2809rtx
2810expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
2811		   int result_unsignedp)
2812{
2813  rtx temp;
2814
2815  if (! flag_trapv)
2816    result_unsignedp = 1;
2817
2818  /* First try to do it with a special abs instruction.  */
2819  temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2820                      op0, target, 0);
2821  if (temp != 0)
2822    return temp;
2823
2824  /* For floating point modes, try clearing the sign bit.  */
2825  if (SCALAR_FLOAT_MODE_P (mode))
2826    {
2827      temp = expand_absneg_bit (ABS, mode, op0, target);
2828      if (temp)
2829	return temp;
2830    }
2831
2832  /* If we have a MAX insn, we can do this as MAX (x, -x).  */
2833  if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
2834      && !HONOR_SIGNED_ZEROS (mode))
2835    {
2836      rtx last = get_last_insn ();
2837
2838      temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2839      if (temp != 0)
2840	temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2841			     OPTAB_WIDEN);
2842
2843      if (temp != 0)
2844	return temp;
2845
2846      delete_insns_since (last);
2847    }
2848
2849  /* If this machine has expensive jumps, we can do integer absolute
2850     value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2851     where W is the width of MODE.  */
2852
2853  if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2854    {
2855      rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2856				   size_int (GET_MODE_BITSIZE (mode) - 1),
2857				   NULL_RTX, 0);
2858
2859      temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2860			   OPTAB_LIB_WIDEN);
2861      if (temp != 0)
2862	temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2863                             temp, extended, target, 0, OPTAB_LIB_WIDEN);
2864
2865      if (temp != 0)
2866	return temp;
2867    }
2868
2869  return NULL_RTX;
2870}
2871
2872rtx
2873expand_abs (enum machine_mode mode, rtx op0, rtx target,
2874	    int result_unsignedp, int safe)
2875{
2876  rtx temp, op1;
2877
2878  if (! flag_trapv)
2879    result_unsignedp = 1;
2880
2881  temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
2882  if (temp != 0)
2883    return temp;
2884
2885  /* If that does not win, use conditional jump and negate.  */
2886
2887  /* It is safe to use the target if it is the same
2888     as the source if this is also a pseudo register */
2889  if (op0 == target && REG_P (op0)
2890      && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2891    safe = 1;
2892
2893  op1 = gen_label_rtx ();
2894  if (target == 0 || ! safe
2895      || GET_MODE (target) != mode
2896      || (MEM_P (target) && MEM_VOLATILE_P (target))
2897      || (REG_P (target)
2898	  && REGNO (target) < FIRST_PSEUDO_REGISTER))
2899    target = gen_reg_rtx (mode);
2900
2901  emit_move_insn (target, op0);
2902  NO_DEFER_POP;
2903
2904  do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2905			   NULL_RTX, NULL_RTX, op1);
2906
2907  op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2908                     target, target, 0);
2909  if (op0 != target)
2910    emit_move_insn (target, op0);
2911  emit_label (op1);
2912  OK_DEFER_POP;
2913  return target;
2914}
2915
2916/* A subroutine of expand_copysign, perform the copysign operation using the
2917   abs and neg primitives advertised to exist on the target.  The assumption
2918   is that we have a split register file, and leaving op0 in fp registers,
2919   and not playing with subregs so much, will help the register allocator.  */
2920
2921static rtx
2922expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
2923		        int bitpos, bool op0_is_abs)
2924{
2925  enum machine_mode imode;
2926  HOST_WIDE_INT hi, lo;
2927  int word;
2928  rtx label;
2929
2930  if (target == op1)
2931    target = NULL_RTX;
2932
2933  if (!op0_is_abs)
2934    {
2935      op0 = expand_unop (mode, abs_optab, op0, target, 0);
2936      if (op0 == NULL)
2937	return NULL_RTX;
2938      target = op0;
2939    }
2940  else
2941    {
2942      if (target == NULL_RTX)
2943        target = copy_to_reg (op0);
2944      else
2945	emit_move_insn (target, op0);
2946    }
2947
2948  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2949    {
2950      imode = int_mode_for_mode (mode);
2951      if (imode == BLKmode)
2952	return NULL_RTX;
2953      op1 = gen_lowpart (imode, op1);
2954    }
2955  else
2956    {
2957      imode = word_mode;
2958      if (FLOAT_WORDS_BIG_ENDIAN)
2959	word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2960      else
2961	word = bitpos / BITS_PER_WORD;
2962      bitpos = bitpos % BITS_PER_WORD;
2963      op1 = operand_subword_force (op1, word, mode);
2964    }
2965
2966  if (bitpos < HOST_BITS_PER_WIDE_INT)
2967    {
2968      hi = 0;
2969      lo = (HOST_WIDE_INT) 1 << bitpos;
2970    }
2971  else
2972    {
2973      hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2974      lo = 0;
2975    }
2976
2977  op1 = expand_binop (imode, and_optab, op1,
2978		      immed_double_const (lo, hi, imode),
2979		      NULL_RTX, 1, OPTAB_LIB_WIDEN);
2980
2981  label = gen_label_rtx ();
2982  emit_cmp_and_jump_insns (op1, const0_rtx, EQ, NULL_RTX, imode, 1, label);
2983
2984  if (GET_CODE (op0) == CONST_DOUBLE)
2985    op0 = simplify_unary_operation (NEG, mode, op0, mode);
2986  else
2987    op0 = expand_unop (mode, neg_optab, op0, target, 0);
2988  if (op0 != target)
2989    emit_move_insn (target, op0);
2990
2991  emit_label (label);
2992
2993  return target;
2994}
2995
2996
2997/* A subroutine of expand_copysign, perform the entire copysign operation
2998   with integer bitmasks.  BITPOS is the position of the sign bit; OP0_IS_ABS
2999   is true if op0 is known to have its sign bit clear.  */
3000
3001static rtx
3002expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3003		     int bitpos, bool op0_is_abs)
3004{
3005  enum machine_mode imode;
3006  HOST_WIDE_INT hi, lo;
3007  int word, nwords, i;
3008  rtx temp, insns;
3009
3010  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3011    {
3012      imode = int_mode_for_mode (mode);
3013      if (imode == BLKmode)
3014	return NULL_RTX;
3015      word = 0;
3016      nwords = 1;
3017    }
3018  else
3019    {
3020      imode = word_mode;
3021
3022      if (FLOAT_WORDS_BIG_ENDIAN)
3023	word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3024      else
3025	word = bitpos / BITS_PER_WORD;
3026      bitpos = bitpos % BITS_PER_WORD;
3027      nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3028    }
3029
3030  if (bitpos < HOST_BITS_PER_WIDE_INT)
3031    {
3032      hi = 0;
3033      lo = (HOST_WIDE_INT) 1 << bitpos;
3034    }
3035  else
3036    {
3037      hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3038      lo = 0;
3039    }
3040
3041  if (target == 0 || target == op0 || target == op1)
3042    target = gen_reg_rtx (mode);
3043
3044  if (nwords > 1)
3045    {
3046      start_sequence ();
3047
3048      for (i = 0; i < nwords; ++i)
3049	{
3050	  rtx targ_piece = operand_subword (target, i, 1, mode);
3051	  rtx op0_piece = operand_subword_force (op0, i, mode);
3052
3053	  if (i == word)
3054	    {
3055	      if (!op0_is_abs)
3056		op0_piece = expand_binop (imode, and_optab, op0_piece,
3057					  immed_double_const (~lo, ~hi, imode),
3058					  NULL_RTX, 1, OPTAB_LIB_WIDEN);
3059
3060	      op1 = expand_binop (imode, and_optab,
3061				  operand_subword_force (op1, i, mode),
3062				  immed_double_const (lo, hi, imode),
3063				  NULL_RTX, 1, OPTAB_LIB_WIDEN);
3064
3065	      temp = expand_binop (imode, ior_optab, op0_piece, op1,
3066				   targ_piece, 1, OPTAB_LIB_WIDEN);
3067	      if (temp != targ_piece)
3068		emit_move_insn (targ_piece, temp);
3069	    }
3070	  else
3071	    emit_move_insn (targ_piece, op0_piece);
3072	}
3073
3074      insns = get_insns ();
3075      end_sequence ();
3076
3077      emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
3078    }
3079  else
3080    {
3081      op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3082		          immed_double_const (lo, hi, imode),
3083		          NULL_RTX, 1, OPTAB_LIB_WIDEN);
3084
3085      op0 = gen_lowpart (imode, op0);
3086      if (!op0_is_abs)
3087	op0 = expand_binop (imode, and_optab, op0,
3088			    immed_double_const (~lo, ~hi, imode),
3089			    NULL_RTX, 1, OPTAB_LIB_WIDEN);
3090
3091      temp = expand_binop (imode, ior_optab, op0, op1,
3092			   gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3093      target = lowpart_subreg_maybe_copy (mode, temp, imode);
3094    }
3095
3096  return target;
3097}
3098
3099/* Expand the C99 copysign operation.  OP0 and OP1 must be the same
3100   scalar floating point mode.  Return NULL if we do not know how to
3101   expand the operation inline.  */
3102
3103rtx
3104expand_copysign (rtx op0, rtx op1, rtx target)
3105{
3106  enum machine_mode mode = GET_MODE (op0);
3107  const struct real_format *fmt;
3108  bool op0_is_abs;
3109  rtx temp;
3110
3111  gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3112  gcc_assert (GET_MODE (op1) == mode);
3113
3114  /* First try to do it with a special instruction.  */
3115  temp = expand_binop (mode, copysign_optab, op0, op1,
3116		       target, 0, OPTAB_DIRECT);
3117  if (temp)
3118    return temp;
3119
3120  fmt = REAL_MODE_FORMAT (mode);
3121  if (fmt == NULL || !fmt->has_signed_zero)
3122    return NULL_RTX;
3123
3124  op0_is_abs = false;
3125  if (GET_CODE (op0) == CONST_DOUBLE)
3126    {
3127      if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3128	op0 = simplify_unary_operation (ABS, mode, op0, mode);
3129      op0_is_abs = true;
3130    }
3131
3132  if (fmt->signbit_ro >= 0
3133      && (GET_CODE (op0) == CONST_DOUBLE
3134	  || (neg_optab->handlers[mode].insn_code != CODE_FOR_nothing
3135	      && abs_optab->handlers[mode].insn_code != CODE_FOR_nothing)))
3136    {
3137      temp = expand_copysign_absneg (mode, op0, op1, target,
3138				     fmt->signbit_ro, op0_is_abs);
3139      if (temp)
3140	return temp;
3141    }
3142
3143  if (fmt->signbit_rw < 0)
3144    return NULL_RTX;
3145  return expand_copysign_bit (mode, op0, op1, target,
3146			      fmt->signbit_rw, op0_is_abs);
3147}
3148
3149/* Generate an instruction whose insn-code is INSN_CODE,
3150   with two operands: an output TARGET and an input OP0.
3151   TARGET *must* be nonzero, and the output is always stored there.
3152   CODE is an rtx code such that (CODE OP0) is an rtx that describes
3153   the value that is stored into TARGET.  */
3154
3155void
3156emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3157{
3158  rtx temp;
3159  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3160  rtx pat;
3161
3162  temp = target;
3163
3164  /* Now, if insn does not accept our operands, put them into pseudos.  */
3165
3166  if (!insn_data[icode].operand[1].predicate (op0, mode0))
3167    op0 = copy_to_mode_reg (mode0, op0);
3168
3169  if (!insn_data[icode].operand[0].predicate (temp, GET_MODE (temp)))
3170    temp = gen_reg_rtx (GET_MODE (temp));
3171
3172  pat = GEN_FCN (icode) (temp, op0);
3173
3174  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3175    add_equal_note (pat, temp, code, op0, NULL_RTX);
3176
3177  emit_insn (pat);
3178
3179  if (temp != target)
3180    emit_move_insn (target, temp);
3181}
3182
3183struct no_conflict_data
3184{
3185  rtx target, first, insn;
3186  bool must_stay;
3187};
3188
3189/* Called via note_stores by emit_no_conflict_block and emit_libcall_block.
3190   Set P->must_stay if the currently examined clobber / store has to stay
3191   in the list of insns that constitute the actual no_conflict block /
3192   libcall block.  */
3193static void
3194no_conflict_move_test (rtx dest, rtx set, void *p0)
3195{
3196  struct no_conflict_data *p= p0;
3197
3198  /* If this inns directly contributes to setting the target, it must stay.  */
3199  if (reg_overlap_mentioned_p (p->target, dest))
3200    p->must_stay = true;
3201  /* If we haven't committed to keeping any other insns in the list yet,
3202     there is nothing more to check.  */
3203  else if (p->insn == p->first)
3204    return;
3205  /* If this insn sets / clobbers a register that feeds one of the insns
3206     already in the list, this insn has to stay too.  */
3207  else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3208	   || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3209	   || reg_used_between_p (dest, p->first, p->insn)
3210	   /* Likewise if this insn depends on a register set by a previous
3211	      insn in the list, or if it sets a result (presumably a hard
3212	      register) that is set or clobbered by a previous insn.
3213	      N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3214	      SET_DEST perform the former check on the address, and the latter
3215	      check on the MEM.  */
3216	   || (GET_CODE (set) == SET
3217	       && (modified_in_p (SET_SRC (set), p->first)
3218		   || modified_in_p (SET_DEST (set), p->first)
3219		   || modified_between_p (SET_SRC (set), p->first, p->insn)
3220		   || modified_between_p (SET_DEST (set), p->first, p->insn))))
3221    p->must_stay = true;
3222}
3223
3224/* Encapsulate the block starting at FIRST and ending with LAST, which is
3225   logically equivalent to EQUIV, so it gets manipulated as a unit if it
3226   is possible to do so.  */
3227
3228static void
3229maybe_encapsulate_block (rtx first, rtx last, rtx equiv)
3230{
3231  if (!flag_non_call_exceptions || !may_trap_p (equiv))
3232    {
3233      /* We can't attach the REG_LIBCALL and REG_RETVAL notes when the
3234	 encapsulated region would not be in one basic block, i.e. when
3235	 there is a control_flow_insn_p insn between FIRST and LAST.  */
3236      bool attach_libcall_retval_notes = true;
3237      rtx insn, next = NEXT_INSN (last);
3238
3239      for (insn = first; insn != next; insn = NEXT_INSN (insn))
3240	if (control_flow_insn_p (insn))
3241	  {
3242	    attach_libcall_retval_notes = false;
3243	    break;
3244	  }
3245
3246      if (attach_libcall_retval_notes)
3247	{
3248	  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3249						 REG_NOTES (first));
3250	  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3251						REG_NOTES (last));
3252	}
3253    }
3254}
3255
3256/* Emit code to perform a series of operations on a multi-word quantity, one
3257   word at a time.
3258
3259   Such a block is preceded by a CLOBBER of the output, consists of multiple
3260   insns, each setting one word of the output, and followed by a SET copying
3261   the output to itself.
3262
3263   Each of the insns setting words of the output receives a REG_NO_CONFLICT
3264   note indicating that it doesn't conflict with the (also multi-word)
3265   inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3266   notes.
3267
3268   INSNS is a block of code generated to perform the operation, not including
3269   the CLOBBER and final copy.  All insns that compute intermediate values
3270   are first emitted, followed by the block as described above.
3271
3272   TARGET, OP0, and OP1 are the output and inputs of the operations,
3273   respectively.  OP1 may be zero for a unary operation.
3274
3275   EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3276   on the last insn.
3277
3278   If TARGET is not a register, INSNS is simply emitted with no special
3279   processing.  Likewise if anything in INSNS is not an INSN or if
3280   there is a libcall block inside INSNS.
3281
3282   The final insn emitted is returned.  */
3283
3284rtx
3285emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
3286{
3287  rtx prev, next, first, last, insn;
3288
3289  if (!REG_P (target) || reload_in_progress)
3290    return emit_insn (insns);
3291  else
3292    for (insn = insns; insn; insn = NEXT_INSN (insn))
3293      if (!NONJUMP_INSN_P (insn)
3294	  || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3295	return emit_insn (insns);
3296
3297  /* First emit all insns that do not store into words of the output and remove
3298     these from the list.  */
3299  for (insn = insns; insn; insn = next)
3300    {
3301      rtx note;
3302      struct no_conflict_data data;
3303
3304      next = NEXT_INSN (insn);
3305
3306      /* Some ports (cris) create a libcall regions at their own.  We must
3307	 avoid any potential nesting of LIBCALLs.  */
3308      if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3309	remove_note (insn, note);
3310      if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3311	remove_note (insn, note);
3312
3313      data.target = target;
3314      data.first = insns;
3315      data.insn = insn;
3316      data.must_stay = 0;
3317      note_stores (PATTERN (insn), no_conflict_move_test, &data);
3318      if (! data.must_stay)
3319	{
3320	  if (PREV_INSN (insn))
3321	    NEXT_INSN (PREV_INSN (insn)) = next;
3322	  else
3323	    insns = next;
3324
3325	  if (next)
3326	    PREV_INSN (next) = PREV_INSN (insn);
3327
3328	  add_insn (insn);
3329	}
3330    }
3331
3332  prev = get_last_insn ();
3333
3334  /* Now write the CLOBBER of the output, followed by the setting of each
3335     of the words, followed by the final copy.  */
3336  if (target != op0 && target != op1)
3337    emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3338
3339  for (insn = insns; insn; insn = next)
3340    {
3341      next = NEXT_INSN (insn);
3342      add_insn (insn);
3343
3344      if (op1 && REG_P (op1))
3345	REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3346					      REG_NOTES (insn));
3347
3348      if (op0 && REG_P (op0))
3349	REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3350					      REG_NOTES (insn));
3351    }
3352
3353  if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3354      != CODE_FOR_nothing)
3355    {
3356      last = emit_move_insn (target, target);
3357      if (equiv)
3358	set_unique_reg_note (last, REG_EQUAL, equiv);
3359    }
3360  else
3361    {
3362      last = get_last_insn ();
3363
3364      /* Remove any existing REG_EQUAL note from "last", or else it will
3365	 be mistaken for a note referring to the full contents of the
3366	 alleged libcall value when found together with the REG_RETVAL
3367	 note added below.  An existing note can come from an insn
3368	 expansion at "last".  */
3369      remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3370    }
3371
3372  if (prev == 0)
3373    first = get_insns ();
3374  else
3375    first = NEXT_INSN (prev);
3376
3377  maybe_encapsulate_block (first, last, equiv);
3378
3379  return last;
3380}
3381
3382/* Emit code to make a call to a constant function or a library call.
3383
3384   INSNS is a list containing all insns emitted in the call.
3385   These insns leave the result in RESULT.  Our block is to copy RESULT
3386   to TARGET, which is logically equivalent to EQUIV.
3387
3388   We first emit any insns that set a pseudo on the assumption that these are
3389   loading constants into registers; doing so allows them to be safely cse'ed
3390   between blocks.  Then we emit all the other insns in the block, followed by
3391   an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
3392   note with an operand of EQUIV.
3393
3394   Moving assignments to pseudos outside of the block is done to improve
3395   the generated code, but is not required to generate correct code,
3396   hence being unable to move an assignment is not grounds for not making
3397   a libcall block.  There are two reasons why it is safe to leave these
3398   insns inside the block: First, we know that these pseudos cannot be
3399   used in generated RTL outside the block since they are created for
3400   temporary purposes within the block.  Second, CSE will not record the
3401   values of anything set inside a libcall block, so we know they must
3402   be dead at the end of the block.
3403
3404   Except for the first group of insns (the ones setting pseudos), the
3405   block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
3406
3407void
3408emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3409{
3410  rtx final_dest = target;
3411  rtx prev, next, first, last, insn;
3412
3413  /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3414     into a MEM later.  Protect the libcall block from this change.  */
3415  if (! REG_P (target) || REG_USERVAR_P (target))
3416    target = gen_reg_rtx (GET_MODE (target));
3417
3418  /* If we're using non-call exceptions, a libcall corresponding to an
3419     operation that may trap may also trap.  */
3420  if (flag_non_call_exceptions && may_trap_p (equiv))
3421    {
3422      for (insn = insns; insn; insn = NEXT_INSN (insn))
3423	if (CALL_P (insn))
3424	  {
3425	    rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3426
3427	    if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3428	      remove_note (insn, note);
3429	  }
3430    }
3431  else
3432  /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3433     reg note to indicate that this call cannot throw or execute a nonlocal
3434     goto (unless there is already a REG_EH_REGION note, in which case
3435     we update it).  */
3436    for (insn = insns; insn; insn = NEXT_INSN (insn))
3437      if (CALL_P (insn))
3438	{
3439	  rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3440
3441	  if (note != 0)
3442	    XEXP (note, 0) = constm1_rtx;
3443	  else
3444	    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
3445						  REG_NOTES (insn));
3446	}
3447
3448  /* First emit all insns that set pseudos.  Remove them from the list as
3449     we go.  Avoid insns that set pseudos which were referenced in previous
3450     insns.  These can be generated by move_by_pieces, for example,
3451     to update an address.  Similarly, avoid insns that reference things
3452     set in previous insns.  */
3453
3454  for (insn = insns; insn; insn = next)
3455    {
3456      rtx set = single_set (insn);
3457      rtx note;
3458
3459      /* Some ports (cris) create a libcall regions at their own.  We must
3460	 avoid any potential nesting of LIBCALLs.  */
3461      if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3462	remove_note (insn, note);
3463      if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3464	remove_note (insn, note);
3465
3466      next = NEXT_INSN (insn);
3467
3468      if (set != 0 && REG_P (SET_DEST (set))
3469	  && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3470	{
3471	  struct no_conflict_data data;
3472
3473	  data.target = const0_rtx;
3474	  data.first = insns;
3475	  data.insn = insn;
3476	  data.must_stay = 0;
3477	  note_stores (PATTERN (insn), no_conflict_move_test, &data);
3478	  if (! data.must_stay)
3479	    {
3480	      if (PREV_INSN (insn))
3481		NEXT_INSN (PREV_INSN (insn)) = next;
3482	      else
3483		insns = next;
3484
3485	      if (next)
3486		PREV_INSN (next) = PREV_INSN (insn);
3487
3488	      add_insn (insn);
3489	    }
3490	}
3491
3492      /* Some ports use a loop to copy large arguments onto the stack.
3493	 Don't move anything outside such a loop.  */
3494      if (LABEL_P (insn))
3495	break;
3496    }
3497
3498  prev = get_last_insn ();
3499
3500  /* Write the remaining insns followed by the final copy.  */
3501
3502  for (insn = insns; insn; insn = next)
3503    {
3504      next = NEXT_INSN (insn);
3505
3506      add_insn (insn);
3507    }
3508
3509  last = emit_move_insn (target, result);
3510  if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3511      != CODE_FOR_nothing)
3512    set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3513  else
3514    {
3515      /* Remove any existing REG_EQUAL note from "last", or else it will
3516	 be mistaken for a note referring to the full contents of the
3517	 libcall value when found together with the REG_RETVAL note added
3518	 below.  An existing note can come from an insn expansion at
3519	 "last".  */
3520      remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3521    }
3522
3523  if (final_dest != target)
3524    emit_move_insn (final_dest, target);
3525
3526  if (prev == 0)
3527    first = get_insns ();
3528  else
3529    first = NEXT_INSN (prev);
3530
3531  maybe_encapsulate_block (first, last, equiv);
3532}
3533
3534/* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3535   PURPOSE describes how this comparison will be used.  CODE is the rtx
3536   comparison code we will be using.
3537
3538   ??? Actually, CODE is slightly weaker than that.  A target is still
3539   required to implement all of the normal bcc operations, but not
3540   required to implement all (or any) of the unordered bcc operations.  */
3541
3542int
3543can_compare_p (enum rtx_code code, enum machine_mode mode,
3544	       enum can_compare_purpose purpose)
3545{
3546  do
3547    {
3548      if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3549	{
3550	  if (purpose == ccp_jump)
3551	    return bcc_gen_fctn[(int) code] != NULL;
3552	  else if (purpose == ccp_store_flag)
3553	    return setcc_gen_code[(int) code] != CODE_FOR_nothing;
3554	  else
3555	    /* There's only one cmov entry point, and it's allowed to fail.  */
3556	    return 1;
3557	}
3558      if (purpose == ccp_jump
3559	  && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3560	return 1;
3561      if (purpose == ccp_cmov
3562	  && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3563	return 1;
3564      if (purpose == ccp_store_flag
3565	  && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3566	return 1;
3567      mode = GET_MODE_WIDER_MODE (mode);
3568    }
3569  while (mode != VOIDmode);
3570
3571  return 0;
3572}
3573
3574/* This function is called when we are going to emit a compare instruction that
3575   compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3576
3577   *PMODE is the mode of the inputs (in case they are const_int).
3578   *PUNSIGNEDP nonzero says that the operands are unsigned;
3579   this matters if they need to be widened.
3580
3581   If they have mode BLKmode, then SIZE specifies the size of both operands.
3582
3583   This function performs all the setup necessary so that the caller only has
3584   to emit a single comparison insn.  This setup can involve doing a BLKmode
3585   comparison or emitting a library call to perform the comparison if no insn
3586   is available to handle it.
3587   The values which are passed in through pointers can be modified; the caller
3588   should perform the comparison on the modified values.  Constant
3589   comparisons must have already been folded.  */
3590
3591static void
3592prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
3593		  enum machine_mode *pmode, int *punsignedp,
3594		  enum can_compare_purpose purpose)
3595{
3596  enum machine_mode mode = *pmode;
3597  rtx x = *px, y = *py;
3598  int unsignedp = *punsignedp;
3599
3600  /* If we are inside an appropriately-short loop and we are optimizing,
3601     force expensive constants into a register.  */
3602  if (CONSTANT_P (x) && optimize
3603      && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3604    x = force_reg (mode, x);
3605
3606  if (CONSTANT_P (y) && optimize
3607      && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3608    y = force_reg (mode, y);
3609
3610#ifdef HAVE_cc0
3611  /* Make sure if we have a canonical comparison.  The RTL
3612     documentation states that canonical comparisons are required only
3613     for targets which have cc0.  */
3614  gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3615#endif
3616
3617  /* Don't let both operands fail to indicate the mode.  */
3618  if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3619    x = force_reg (mode, x);
3620
3621  /* Handle all BLKmode compares.  */
3622
3623  if (mode == BLKmode)
3624    {
3625      enum machine_mode cmp_mode, result_mode;
3626      enum insn_code cmp_code;
3627      tree length_type;
3628      rtx libfunc;
3629      rtx result;
3630      rtx opalign
3631	= GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3632
3633      gcc_assert (size);
3634
3635      /* Try to use a memory block compare insn - either cmpstr
3636	 or cmpmem will do.  */
3637      for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3638	   cmp_mode != VOIDmode;
3639	   cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3640	{
3641	  cmp_code = cmpmem_optab[cmp_mode];
3642	  if (cmp_code == CODE_FOR_nothing)
3643	    cmp_code = cmpstr_optab[cmp_mode];
3644	  if (cmp_code == CODE_FOR_nothing)
3645	    cmp_code = cmpstrn_optab[cmp_mode];
3646	  if (cmp_code == CODE_FOR_nothing)
3647	    continue;
3648
3649	  /* Must make sure the size fits the insn's mode.  */
3650	  if ((GET_CODE (size) == CONST_INT
3651	       && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3652	      || (GET_MODE_BITSIZE (GET_MODE (size))
3653		  > GET_MODE_BITSIZE (cmp_mode)))
3654	    continue;
3655
3656	  result_mode = insn_data[cmp_code].operand[0].mode;
3657	  result = gen_reg_rtx (result_mode);
3658	  size = convert_to_mode (cmp_mode, size, 1);
3659	  emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3660
3661	  *px = result;
3662	  *py = const0_rtx;
3663	  *pmode = result_mode;
3664	  return;
3665	}
3666
3667      /* Otherwise call a library function, memcmp.  */
3668      libfunc = memcmp_libfunc;
3669      length_type = sizetype;
3670      result_mode = TYPE_MODE (integer_type_node);
3671      cmp_mode = TYPE_MODE (length_type);
3672      size = convert_to_mode (TYPE_MODE (length_type), size,
3673			      TYPE_UNSIGNED (length_type));
3674
3675      result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
3676					result_mode, 3,
3677					XEXP (x, 0), Pmode,
3678					XEXP (y, 0), Pmode,
3679					size, cmp_mode);
3680      *px = result;
3681      *py = const0_rtx;
3682      *pmode = result_mode;
3683      return;
3684    }
3685
3686  /* Don't allow operands to the compare to trap, as that can put the
3687     compare and branch in different basic blocks.  */
3688  if (flag_non_call_exceptions)
3689    {
3690      if (may_trap_p (x))
3691	x = force_reg (mode, x);
3692      if (may_trap_p (y))
3693	y = force_reg (mode, y);
3694    }
3695
3696  *px = x;
3697  *py = y;
3698  if (can_compare_p (*pcomparison, mode, purpose))
3699    return;
3700
3701  /* Handle a lib call just for the mode we are using.  */
3702
3703  if (cmp_optab->handlers[(int) mode].libfunc && !SCALAR_FLOAT_MODE_P (mode))
3704    {
3705      rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3706      rtx result;
3707
3708      /* If we want unsigned, and this mode has a distinct unsigned
3709	 comparison routine, use that.  */
3710      if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3711	libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3712
3713      result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
3714					word_mode, 2, x, mode, y, mode);
3715
3716      /* There are two kinds of comparison routines. Biased routines
3717	 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3718	 of gcc expect that the comparison operation is equivalent
3719	 to the modified comparison. For signed comparisons compare the
3720	 result against 1 in the biased case, and zero in the unbiased
3721	 case. For unsigned comparisons always compare against 1 after
3722	 biasing the unbiased result by adding 1. This gives us a way to
3723	 represent LTU. */
3724      *px = result;
3725      *pmode = word_mode;
3726      *py = const1_rtx;
3727
3728      if (!TARGET_LIB_INT_CMP_BIASED)
3729	{
3730	  if (*punsignedp)
3731	    *px = plus_constant (result, 1);
3732	  else
3733	    *py = const0_rtx;
3734	}
3735      return;
3736    }
3737
3738  gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3739  prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3740}
3741
3742/* Before emitting an insn with code ICODE, make sure that X, which is going
3743   to be used for operand OPNUM of the insn, is converted from mode MODE to
3744   WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3745   that it is accepted by the operand predicate.  Return the new value.  */
3746
3747static rtx
3748prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
3749		 enum machine_mode wider_mode, int unsignedp)
3750{
3751  if (mode != wider_mode)
3752    x = convert_modes (wider_mode, mode, x, unsignedp);
3753
3754  if (!insn_data[icode].operand[opnum].predicate
3755      (x, insn_data[icode].operand[opnum].mode))
3756    {
3757      if (no_new_pseudos)
3758	return NULL_RTX;
3759      x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3760    }
3761
3762  return x;
3763}
3764
3765/* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3766   we can do the comparison.
3767   The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3768   be NULL_RTX which indicates that only a comparison is to be generated.  */
3769
3770static void
3771emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
3772			  enum rtx_code comparison, int unsignedp, rtx label)
3773{
3774  rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3775  enum mode_class class = GET_MODE_CLASS (mode);
3776  enum machine_mode wider_mode = mode;
3777
3778  /* Try combined insns first.  */
3779  do
3780    {
3781      enum insn_code icode;
3782      PUT_MODE (test, wider_mode);
3783
3784      if (label)
3785	{
3786	  icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
3787
3788	  if (icode != CODE_FOR_nothing
3789	      && insn_data[icode].operand[0].predicate (test, wider_mode))
3790	    {
3791	      x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3792	      y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3793	      emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3794	      return;
3795	    }
3796	}
3797
3798      /* Handle some compares against zero.  */
3799      icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3800      if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3801	{
3802	  x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3803	  emit_insn (GEN_FCN (icode) (x));
3804	  if (label)
3805	    emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
3806	  return;
3807	}
3808
3809      /* Handle compares for which there is a directly suitable insn.  */
3810
3811      icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3812      if (icode != CODE_FOR_nothing)
3813	{
3814	  x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3815	  y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3816	  emit_insn (GEN_FCN (icode) (x, y));
3817	  if (label)
3818	    emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
3819	  return;
3820	}
3821
3822      if (!CLASS_HAS_WIDER_MODES_P (class))
3823	break;
3824
3825      wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3826    }
3827  while (wider_mode != VOIDmode);
3828
3829  gcc_unreachable ();
3830}
3831
3832/* Generate code to compare X with Y so that the condition codes are
3833   set and to jump to LABEL if the condition is true.  If X is a
3834   constant and Y is not a constant, then the comparison is swapped to
3835   ensure that the comparison RTL has the canonical form.
3836
3837   UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3838   need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
3839   the proper branch condition code.
3840
3841   If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3842
3843   MODE is the mode of the inputs (in case they are const_int).
3844
3845   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
3846   be passed unchanged to emit_cmp_insn, then potentially converted into an
3847   unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
3848
3849void
3850emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
3851			 enum machine_mode mode, int unsignedp, rtx label)
3852{
3853  rtx op0 = x, op1 = y;
3854
3855  /* Swap operands and condition to ensure canonical RTL.  */
3856  if (swap_commutative_operands_p (x, y))
3857    {
3858      /* If we're not emitting a branch, this means some caller
3859         is out of sync.  */
3860      gcc_assert (label);
3861
3862      op0 = y, op1 = x;
3863      comparison = swap_condition (comparison);
3864    }
3865
3866#ifdef HAVE_cc0
3867  /* If OP0 is still a constant, then both X and Y must be constants.
3868     Force X into a register to create canonical RTL.  */
3869  if (CONSTANT_P (op0))
3870    op0 = force_reg (mode, op0);
3871#endif
3872
3873  if (unsignedp)
3874    comparison = unsigned_condition (comparison);
3875
3876  prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3877		    ccp_jump);
3878  emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3879}
3880
3881/* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
3882
3883void
3884emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3885	       enum machine_mode mode, int unsignedp)
3886{
3887  emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3888}
3889
3890/* Emit a library call comparison between floating point X and Y.
3891   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
3892
3893static void
3894prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
3895		       enum machine_mode *pmode, int *punsignedp)
3896{
3897  enum rtx_code comparison = *pcomparison;
3898  enum rtx_code swapped = swap_condition (comparison);
3899  enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
3900  rtx x = *px;
3901  rtx y = *py;
3902  enum machine_mode orig_mode = GET_MODE (x);
3903  enum machine_mode mode;
3904  rtx value, target, insns, equiv;
3905  rtx libfunc = 0;
3906  bool reversed_p = false;
3907
3908  for (mode = orig_mode;
3909       mode != VOIDmode;
3910       mode = GET_MODE_WIDER_MODE (mode))
3911    {
3912      if ((libfunc = code_to_optab[comparison]->handlers[mode].libfunc))
3913	break;
3914
3915      if ((libfunc = code_to_optab[swapped]->handlers[mode].libfunc))
3916	{
3917	  rtx tmp;
3918	  tmp = x; x = y; y = tmp;
3919	  comparison = swapped;
3920	  break;
3921	}
3922
3923      if ((libfunc = code_to_optab[reversed]->handlers[mode].libfunc)
3924	  && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
3925	{
3926	  comparison = reversed;
3927	  reversed_p = true;
3928	  break;
3929	}
3930    }
3931
3932  gcc_assert (mode != VOIDmode);
3933
3934  if (mode != orig_mode)
3935    {
3936      x = convert_to_mode (mode, x, 0);
3937      y = convert_to_mode (mode, y, 0);
3938    }
3939
3940  /* Attach a REG_EQUAL note describing the semantics of the libcall to
3941     the RTL.  The allows the RTL optimizers to delete the libcall if the
3942     condition can be determined at compile-time.  */
3943  if (comparison == UNORDERED)
3944    {
3945      rtx temp = simplify_gen_relational (NE, word_mode, mode, x, x);
3946      equiv = simplify_gen_relational (NE, word_mode, mode, y, y);
3947      equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3948				    temp, const_true_rtx, equiv);
3949    }
3950  else
3951    {
3952      equiv = simplify_gen_relational (comparison, word_mode, mode, x, y);
3953      if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3954	{
3955	  rtx true_rtx, false_rtx;
3956
3957	  switch (comparison)
3958	    {
3959	    case EQ:
3960	      true_rtx = const0_rtx;
3961	      false_rtx = const_true_rtx;
3962	      break;
3963
3964	    case NE:
3965	      true_rtx = const_true_rtx;
3966	      false_rtx = const0_rtx;
3967	      break;
3968
3969	    case GT:
3970	      true_rtx = const1_rtx;
3971	      false_rtx = const0_rtx;
3972	      break;
3973
3974	    case GE:
3975	      true_rtx = const0_rtx;
3976	      false_rtx = constm1_rtx;
3977	      break;
3978
3979	    case LT:
3980	      true_rtx = constm1_rtx;
3981	      false_rtx = const0_rtx;
3982	      break;
3983
3984	    case LE:
3985	      true_rtx = const0_rtx;
3986	      false_rtx = const1_rtx;
3987	      break;
3988
3989	    default:
3990	      gcc_unreachable ();
3991	    }
3992	  equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3993					equiv, true_rtx, false_rtx);
3994	}
3995    }
3996
3997  start_sequence ();
3998  value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
3999				   word_mode, 2, x, mode, y, mode);
4000  insns = get_insns ();
4001  end_sequence ();
4002
4003  target = gen_reg_rtx (word_mode);
4004  emit_libcall_block (insns, target, value, equiv);
4005
4006  if (comparison == UNORDERED
4007      || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4008    comparison = reversed_p ? EQ : NE;
4009
4010  *px = target;
4011  *py = const0_rtx;
4012  *pmode = word_mode;
4013  *pcomparison = comparison;
4014  *punsignedp = 0;
4015}
4016
4017/* Generate code to indirectly jump to a location given in the rtx LOC.  */
4018
4019void
4020emit_indirect_jump (rtx loc)
4021{
4022  if (!insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate
4023      (loc, Pmode))
4024    loc = copy_to_mode_reg (Pmode, loc);
4025
4026  emit_jump_insn (gen_indirect_jump (loc));
4027  emit_barrier ();
4028}
4029
4030#ifdef HAVE_conditional_move
4031
4032/* Emit a conditional move instruction if the machine supports one for that
4033   condition and machine mode.
4034
4035   OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4036   the mode to use should they be constants.  If it is VOIDmode, they cannot
4037   both be constants.
4038
4039   OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4040   should be stored there.  MODE is the mode to use should they be constants.
4041   If it is VOIDmode, they cannot both be constants.
4042
4043   The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4044   is not supported.  */
4045
4046rtx
4047emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4048		       enum machine_mode cmode, rtx op2, rtx op3,
4049		       enum machine_mode mode, int unsignedp)
4050{
4051  rtx tem, subtarget, comparison, insn;
4052  enum insn_code icode;
4053  enum rtx_code reversed;
4054
4055  /* If one operand is constant, make it the second one.  Only do this
4056     if the other operand is not constant as well.  */
4057
4058  if (swap_commutative_operands_p (op0, op1))
4059    {
4060      tem = op0;
4061      op0 = op1;
4062      op1 = tem;
4063      code = swap_condition (code);
4064    }
4065
4066  /* get_condition will prefer to generate LT and GT even if the old
4067     comparison was against zero, so undo that canonicalization here since
4068     comparisons against zero are cheaper.  */
4069  if (code == LT && op1 == const1_rtx)
4070    code = LE, op1 = const0_rtx;
4071  else if (code == GT && op1 == constm1_rtx)
4072    code = GE, op1 = const0_rtx;
4073
4074  if (cmode == VOIDmode)
4075    cmode = GET_MODE (op0);
4076
4077  if (swap_commutative_operands_p (op2, op3)
4078      && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4079          != UNKNOWN))
4080    {
4081      tem = op2;
4082      op2 = op3;
4083      op3 = tem;
4084      code = reversed;
4085    }
4086
4087  if (mode == VOIDmode)
4088    mode = GET_MODE (op2);
4089
4090  icode = movcc_gen_code[mode];
4091
4092  if (icode == CODE_FOR_nothing)
4093    return 0;
4094
4095  if (!target)
4096    target = gen_reg_rtx (mode);
4097
4098  subtarget = target;
4099
4100  /* If the insn doesn't accept these operands, put them in pseudos.  */
4101
4102  if (!insn_data[icode].operand[0].predicate
4103      (subtarget, insn_data[icode].operand[0].mode))
4104    subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4105
4106  if (!insn_data[icode].operand[2].predicate
4107      (op2, insn_data[icode].operand[2].mode))
4108    op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4109
4110  if (!insn_data[icode].operand[3].predicate
4111      (op3, insn_data[icode].operand[3].mode))
4112    op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4113
4114  /* Everything should now be in the suitable form, so emit the compare insn
4115     and then the conditional move.  */
4116
4117  comparison
4118    = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4119
4120  /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4121  /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4122     return NULL and let the caller figure out how best to deal with this
4123     situation.  */
4124  if (GET_CODE (comparison) != code)
4125    return NULL_RTX;
4126
4127  insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4128
4129  /* If that failed, then give up.  */
4130  if (insn == 0)
4131    return 0;
4132
4133  emit_insn (insn);
4134
4135  if (subtarget != target)
4136    convert_move (target, subtarget, 0);
4137
4138  return target;
4139}
4140
4141/* Return nonzero if a conditional move of mode MODE is supported.
4142
4143   This function is for combine so it can tell whether an insn that looks
4144   like a conditional move is actually supported by the hardware.  If we
4145   guess wrong we lose a bit on optimization, but that's it.  */
4146/* ??? sparc64 supports conditionally moving integers values based on fp
4147   comparisons, and vice versa.  How do we handle them?  */
4148
4149int
4150can_conditionally_move_p (enum machine_mode mode)
4151{
4152  if (movcc_gen_code[mode] != CODE_FOR_nothing)
4153    return 1;
4154
4155  return 0;
4156}
4157
4158#endif /* HAVE_conditional_move */
4159
4160/* Emit a conditional addition instruction if the machine supports one for that
4161   condition and machine mode.
4162
4163   OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4164   the mode to use should they be constants.  If it is VOIDmode, they cannot
4165   both be constants.
4166
4167   OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4168   should be stored there.  MODE is the mode to use should they be constants.
4169   If it is VOIDmode, they cannot both be constants.
4170
4171   The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4172   is not supported.  */
4173
4174rtx
4175emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4176		      enum machine_mode cmode, rtx op2, rtx op3,
4177		      enum machine_mode mode, int unsignedp)
4178{
4179  rtx tem, subtarget, comparison, insn;
4180  enum insn_code icode;
4181  enum rtx_code reversed;
4182
4183  /* If one operand is constant, make it the second one.  Only do this
4184     if the other operand is not constant as well.  */
4185
4186  if (swap_commutative_operands_p (op0, op1))
4187    {
4188      tem = op0;
4189      op0 = op1;
4190      op1 = tem;
4191      code = swap_condition (code);
4192    }
4193
4194  /* get_condition will prefer to generate LT and GT even if the old
4195     comparison was against zero, so undo that canonicalization here since
4196     comparisons against zero are cheaper.  */
4197  if (code == LT && op1 == const1_rtx)
4198    code = LE, op1 = const0_rtx;
4199  else if (code == GT && op1 == constm1_rtx)
4200    code = GE, op1 = const0_rtx;
4201
4202  if (cmode == VOIDmode)
4203    cmode = GET_MODE (op0);
4204
4205  if (swap_commutative_operands_p (op2, op3)
4206      && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4207          != UNKNOWN))
4208    {
4209      tem = op2;
4210      op2 = op3;
4211      op3 = tem;
4212      code = reversed;
4213    }
4214
4215  if (mode == VOIDmode)
4216    mode = GET_MODE (op2);
4217
4218  icode = addcc_optab->handlers[(int) mode].insn_code;
4219
4220  if (icode == CODE_FOR_nothing)
4221    return 0;
4222
4223  if (!target)
4224    target = gen_reg_rtx (mode);
4225
4226  /* If the insn doesn't accept these operands, put them in pseudos.  */
4227
4228  if (!insn_data[icode].operand[0].predicate
4229      (target, insn_data[icode].operand[0].mode))
4230    subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4231  else
4232    subtarget = target;
4233
4234  if (!insn_data[icode].operand[2].predicate
4235      (op2, insn_data[icode].operand[2].mode))
4236    op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4237
4238  if (!insn_data[icode].operand[3].predicate
4239      (op3, insn_data[icode].operand[3].mode))
4240    op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4241
4242  /* Everything should now be in the suitable form, so emit the compare insn
4243     and then the conditional move.  */
4244
4245  comparison
4246    = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4247
4248  /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4249  /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4250     return NULL and let the caller figure out how best to deal with this
4251     situation.  */
4252  if (GET_CODE (comparison) != code)
4253    return NULL_RTX;
4254
4255  insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4256
4257  /* If that failed, then give up.  */
4258  if (insn == 0)
4259    return 0;
4260
4261  emit_insn (insn);
4262
4263  if (subtarget != target)
4264    convert_move (target, subtarget, 0);
4265
4266  return target;
4267}
4268
4269/* These functions attempt to generate an insn body, rather than
4270   emitting the insn, but if the gen function already emits them, we
4271   make no attempt to turn them back into naked patterns.  */
4272
4273/* Generate and return an insn body to add Y to X.  */
4274
4275rtx
4276gen_add2_insn (rtx x, rtx y)
4277{
4278  int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4279
4280  gcc_assert (insn_data[icode].operand[0].predicate
4281	      (x, insn_data[icode].operand[0].mode));
4282  gcc_assert (insn_data[icode].operand[1].predicate
4283	      (x, insn_data[icode].operand[1].mode));
4284  gcc_assert (insn_data[icode].operand[2].predicate
4285	      (y, insn_data[icode].operand[2].mode));
4286
4287  return GEN_FCN (icode) (x, x, y);
4288}
4289
4290/* Generate and return an insn body to add r1 and c,
4291   storing the result in r0.  */
4292rtx
4293gen_add3_insn (rtx r0, rtx r1, rtx c)
4294{
4295  int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4296
4297  if (icode == CODE_FOR_nothing
4298      || !(insn_data[icode].operand[0].predicate
4299	   (r0, insn_data[icode].operand[0].mode))
4300      || !(insn_data[icode].operand[1].predicate
4301	   (r1, insn_data[icode].operand[1].mode))
4302      || !(insn_data[icode].operand[2].predicate
4303	   (c, insn_data[icode].operand[2].mode)))
4304    return NULL_RTX;
4305
4306  return GEN_FCN (icode) (r0, r1, c);
4307}
4308
4309int
4310have_add2_insn (rtx x, rtx y)
4311{
4312  int icode;
4313
4314  gcc_assert (GET_MODE (x) != VOIDmode);
4315
4316  icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4317
4318  if (icode == CODE_FOR_nothing)
4319    return 0;
4320
4321  if (!(insn_data[icode].operand[0].predicate
4322	(x, insn_data[icode].operand[0].mode))
4323      || !(insn_data[icode].operand[1].predicate
4324	   (x, insn_data[icode].operand[1].mode))
4325      || !(insn_data[icode].operand[2].predicate
4326	   (y, insn_data[icode].operand[2].mode)))
4327    return 0;
4328
4329  return 1;
4330}
4331
4332/* Generate and return an insn body to subtract Y from X.  */
4333
4334rtx
4335gen_sub2_insn (rtx x, rtx y)
4336{
4337  int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4338
4339  gcc_assert (insn_data[icode].operand[0].predicate
4340	      (x, insn_data[icode].operand[0].mode));
4341  gcc_assert (insn_data[icode].operand[1].predicate
4342	      (x, insn_data[icode].operand[1].mode));
4343  gcc_assert  (insn_data[icode].operand[2].predicate
4344	       (y, insn_data[icode].operand[2].mode));
4345
4346  return GEN_FCN (icode) (x, x, y);
4347}
4348
4349/* Generate and return an insn body to subtract r1 and c,
4350   storing the result in r0.  */
4351rtx
4352gen_sub3_insn (rtx r0, rtx r1, rtx c)
4353{
4354  int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4355
4356  if (icode == CODE_FOR_nothing
4357      || !(insn_data[icode].operand[0].predicate
4358	   (r0, insn_data[icode].operand[0].mode))
4359      || !(insn_data[icode].operand[1].predicate
4360	   (r1, insn_data[icode].operand[1].mode))
4361      || !(insn_data[icode].operand[2].predicate
4362	   (c, insn_data[icode].operand[2].mode)))
4363    return NULL_RTX;
4364
4365  return GEN_FCN (icode) (r0, r1, c);
4366}
4367
4368int
4369have_sub2_insn (rtx x, rtx y)
4370{
4371  int icode;
4372
4373  gcc_assert (GET_MODE (x) != VOIDmode);
4374
4375  icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4376
4377  if (icode == CODE_FOR_nothing)
4378    return 0;
4379
4380  if (!(insn_data[icode].operand[0].predicate
4381	(x, insn_data[icode].operand[0].mode))
4382      || !(insn_data[icode].operand[1].predicate
4383	   (x, insn_data[icode].operand[1].mode))
4384      || !(insn_data[icode].operand[2].predicate
4385	   (y, insn_data[icode].operand[2].mode)))
4386    return 0;
4387
4388  return 1;
4389}
4390
4391/* Generate the body of an instruction to copy Y into X.
4392   It may be a list of insns, if one insn isn't enough.  */
4393
4394rtx
4395gen_move_insn (rtx x, rtx y)
4396{
4397  rtx seq;
4398
4399  start_sequence ();
4400  emit_move_insn_1 (x, y);
4401  seq = get_insns ();
4402  end_sequence ();
4403  return seq;
4404}
4405
4406/* Return the insn code used to extend FROM_MODE to TO_MODE.
4407   UNSIGNEDP specifies zero-extension instead of sign-extension.  If
4408   no such operation exists, CODE_FOR_nothing will be returned.  */
4409
4410enum insn_code
4411can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4412	      int unsignedp)
4413{
4414  convert_optab tab;
4415#ifdef HAVE_ptr_extend
4416  if (unsignedp < 0)
4417    return CODE_FOR_ptr_extend;
4418#endif
4419
4420  tab = unsignedp ? zext_optab : sext_optab;
4421  return tab->handlers[to_mode][from_mode].insn_code;
4422}
4423
4424/* Generate the body of an insn to extend Y (with mode MFROM)
4425   into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
4426
4427rtx
4428gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4429		 enum machine_mode mfrom, int unsignedp)
4430{
4431  enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4432  return GEN_FCN (icode) (x, y);
4433}
4434
4435/* can_fix_p and can_float_p say whether the target machine
4436   can directly convert a given fixed point type to
4437   a given floating point type, or vice versa.
4438   The returned value is the CODE_FOR_... value to use,
4439   or CODE_FOR_nothing if these modes cannot be directly converted.
4440
4441   *TRUNCP_PTR is set to 1 if it is necessary to output
4442   an explicit FTRUNC insn before the fix insn; otherwise 0.  */
4443
4444static enum insn_code
4445can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4446	   int unsignedp, int *truncp_ptr)
4447{
4448  convert_optab tab;
4449  enum insn_code icode;
4450
4451  tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4452  icode = tab->handlers[fixmode][fltmode].insn_code;
4453  if (icode != CODE_FOR_nothing)
4454    {
4455      *truncp_ptr = 0;
4456      return icode;
4457    }
4458
4459  /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4460     for this to work. We need to rework the fix* and ftrunc* patterns
4461     and documentation.  */
4462  tab = unsignedp ? ufix_optab : sfix_optab;
4463  icode = tab->handlers[fixmode][fltmode].insn_code;
4464  if (icode != CODE_FOR_nothing
4465      && ftrunc_optab->handlers[fltmode].insn_code != CODE_FOR_nothing)
4466    {
4467      *truncp_ptr = 1;
4468      return icode;
4469    }
4470
4471  *truncp_ptr = 0;
4472  return CODE_FOR_nothing;
4473}
4474
4475static enum insn_code
4476can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4477	     int unsignedp)
4478{
4479  convert_optab tab;
4480
4481  tab = unsignedp ? ufloat_optab : sfloat_optab;
4482  return tab->handlers[fltmode][fixmode].insn_code;
4483}
4484
4485/* Generate code to convert FROM to floating point
4486   and store in TO.  FROM must be fixed point and not VOIDmode.
4487   UNSIGNEDP nonzero means regard FROM as unsigned.
4488   Normally this is done by correcting the final value
4489   if it is negative.  */
4490
4491void
4492expand_float (rtx to, rtx from, int unsignedp)
4493{
4494  enum insn_code icode;
4495  rtx target = to;
4496  enum machine_mode fmode, imode;
4497  bool can_do_signed = false;
4498
4499  /* Crash now, because we won't be able to decide which mode to use.  */
4500  gcc_assert (GET_MODE (from) != VOIDmode);
4501
4502  /* Look for an insn to do the conversion.  Do it in the specified
4503     modes if possible; otherwise convert either input, output or both to
4504     wider mode.  If the integer mode is wider than the mode of FROM,
4505     we can do the conversion signed even if the input is unsigned.  */
4506
4507  for (fmode = GET_MODE (to); fmode != VOIDmode;
4508       fmode = GET_MODE_WIDER_MODE (fmode))
4509    for (imode = GET_MODE (from); imode != VOIDmode;
4510	 imode = GET_MODE_WIDER_MODE (imode))
4511      {
4512	int doing_unsigned = unsignedp;
4513
4514	if (fmode != GET_MODE (to)
4515	    && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4516	  continue;
4517
4518	icode = can_float_p (fmode, imode, unsignedp);
4519	if (icode == CODE_FOR_nothing && unsignedp)
4520	  {
4521	    enum insn_code scode = can_float_p (fmode, imode, 0);
4522	    if (scode != CODE_FOR_nothing)
4523	      can_do_signed = true;
4524	    if (imode != GET_MODE (from))
4525	      icode = scode, doing_unsigned = 0;
4526	  }
4527
4528	if (icode != CODE_FOR_nothing)
4529	  {
4530	    if (imode != GET_MODE (from))
4531	      from = convert_to_mode (imode, from, unsignedp);
4532
4533	    if (fmode != GET_MODE (to))
4534	      target = gen_reg_rtx (fmode);
4535
4536	    emit_unop_insn (icode, target, from,
4537			    doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4538
4539	    if (target != to)
4540	      convert_move (to, target, 0);
4541	    return;
4542	  }
4543      }
4544
4545  /* Unsigned integer, and no way to convert directly.  For binary
4546     floating point modes, convert as signed, then conditionally adjust
4547     the result.  */
4548  if (unsignedp && can_do_signed && !DECIMAL_FLOAT_MODE_P (GET_MODE (to)))
4549    {
4550      rtx label = gen_label_rtx ();
4551      rtx temp;
4552      REAL_VALUE_TYPE offset;
4553
4554      /* Look for a usable floating mode FMODE wider than the source and at
4555	 least as wide as the target.  Using FMODE will avoid rounding woes
4556	 with unsigned values greater than the signed maximum value.  */
4557
4558      for (fmode = GET_MODE (to);  fmode != VOIDmode;
4559	   fmode = GET_MODE_WIDER_MODE (fmode))
4560	if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4561	    && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4562	  break;
4563
4564      if (fmode == VOIDmode)
4565	{
4566	  /* There is no such mode.  Pretend the target is wide enough.  */
4567	  fmode = GET_MODE (to);
4568
4569	  /* Avoid double-rounding when TO is narrower than FROM.  */
4570	  if ((significand_size (fmode) + 1)
4571	      < GET_MODE_BITSIZE (GET_MODE (from)))
4572	    {
4573	      rtx temp1;
4574	      rtx neglabel = gen_label_rtx ();
4575
4576	      /* Don't use TARGET if it isn't a register, is a hard register,
4577		 or is the wrong mode.  */
4578	      if (!REG_P (target)
4579		  || REGNO (target) < FIRST_PSEUDO_REGISTER
4580		  || GET_MODE (target) != fmode)
4581		target = gen_reg_rtx (fmode);
4582
4583	      imode = GET_MODE (from);
4584	      do_pending_stack_adjust ();
4585
4586	      /* Test whether the sign bit is set.  */
4587	      emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4588				       0, neglabel);
4589
4590	      /* The sign bit is not set.  Convert as signed.  */
4591	      expand_float (target, from, 0);
4592	      emit_jump_insn (gen_jump (label));
4593	      emit_barrier ();
4594
4595	      /* The sign bit is set.
4596		 Convert to a usable (positive signed) value by shifting right
4597		 one bit, while remembering if a nonzero bit was shifted
4598		 out; i.e., compute  (from & 1) | (from >> 1).  */
4599
4600	      emit_label (neglabel);
4601	      temp = expand_binop (imode, and_optab, from, const1_rtx,
4602				   NULL_RTX, 1, OPTAB_LIB_WIDEN);
4603	      temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4604				    NULL_RTX, 1);
4605	      temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4606				   OPTAB_LIB_WIDEN);
4607	      expand_float (target, temp, 0);
4608
4609	      /* Multiply by 2 to undo the shift above.  */
4610	      temp = expand_binop (fmode, add_optab, target, target,
4611				   target, 0, OPTAB_LIB_WIDEN);
4612	      if (temp != target)
4613		emit_move_insn (target, temp);
4614
4615	      do_pending_stack_adjust ();
4616	      emit_label (label);
4617	      goto done;
4618	    }
4619	}
4620
4621      /* If we are about to do some arithmetic to correct for an
4622	 unsigned operand, do it in a pseudo-register.  */
4623
4624      if (GET_MODE (to) != fmode
4625	  || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4626	target = gen_reg_rtx (fmode);
4627
4628      /* Convert as signed integer to floating.  */
4629      expand_float (target, from, 0);
4630
4631      /* If FROM is negative (and therefore TO is negative),
4632	 correct its value by 2**bitwidth.  */
4633
4634      do_pending_stack_adjust ();
4635      emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4636			       0, label);
4637
4638
4639      real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
4640      temp = expand_binop (fmode, add_optab, target,
4641			   CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4642			   target, 0, OPTAB_LIB_WIDEN);
4643      if (temp != target)
4644	emit_move_insn (target, temp);
4645
4646      do_pending_stack_adjust ();
4647      emit_label (label);
4648      goto done;
4649    }
4650
4651  /* No hardware instruction available; call a library routine.  */
4652    {
4653      rtx libfunc;
4654      rtx insns;
4655      rtx value;
4656      convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4657
4658      if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4659	from = convert_to_mode (SImode, from, unsignedp);
4660
4661      libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4662      gcc_assert (libfunc);
4663
4664      start_sequence ();
4665
4666      value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4667				       GET_MODE (to), 1, from,
4668				       GET_MODE (from));
4669      insns = get_insns ();
4670      end_sequence ();
4671
4672      emit_libcall_block (insns, target, value,
4673			  gen_rtx_FLOAT (GET_MODE (to), from));
4674    }
4675
4676 done:
4677
4678  /* Copy result to requested destination
4679     if we have been computing in a temp location.  */
4680
4681  if (target != to)
4682    {
4683      if (GET_MODE (target) == GET_MODE (to))
4684	emit_move_insn (to, target);
4685      else
4686	convert_move (to, target, 0);
4687    }
4688}
4689
4690/* Generate code to convert FROM to fixed point and store in TO.  FROM
4691   must be floating point.  */
4692
4693void
4694expand_fix (rtx to, rtx from, int unsignedp)
4695{
4696  enum insn_code icode;
4697  rtx target = to;
4698  enum machine_mode fmode, imode;
4699  int must_trunc = 0;
4700
4701  /* We first try to find a pair of modes, one real and one integer, at
4702     least as wide as FROM and TO, respectively, in which we can open-code
4703     this conversion.  If the integer mode is wider than the mode of TO,
4704     we can do the conversion either signed or unsigned.  */
4705
4706  for (fmode = GET_MODE (from); fmode != VOIDmode;
4707       fmode = GET_MODE_WIDER_MODE (fmode))
4708    for (imode = GET_MODE (to); imode != VOIDmode;
4709	 imode = GET_MODE_WIDER_MODE (imode))
4710      {
4711	int doing_unsigned = unsignedp;
4712
4713	icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4714	if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4715	  icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4716
4717	if (icode != CODE_FOR_nothing)
4718	  {
4719	    if (fmode != GET_MODE (from))
4720	      from = convert_to_mode (fmode, from, 0);
4721
4722	    if (must_trunc)
4723	      {
4724		rtx temp = gen_reg_rtx (GET_MODE (from));
4725		from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4726				    temp, 0);
4727	      }
4728
4729	    if (imode != GET_MODE (to))
4730	      target = gen_reg_rtx (imode);
4731
4732	    emit_unop_insn (icode, target, from,
4733			    doing_unsigned ? UNSIGNED_FIX : FIX);
4734	    if (target != to)
4735	      convert_move (to, target, unsignedp);
4736	    return;
4737	  }
4738      }
4739
4740  /* For an unsigned conversion, there is one more way to do it.
4741     If we have a signed conversion, we generate code that compares
4742     the real value to the largest representable positive number.  If if
4743     is smaller, the conversion is done normally.  Otherwise, subtract
4744     one plus the highest signed number, convert, and add it back.
4745
4746     We only need to check all real modes, since we know we didn't find
4747     anything with a wider integer mode.
4748
4749     This code used to extend FP value into mode wider than the destination.
4750     This is not needed.  Consider, for instance conversion from SFmode
4751     into DImode.
4752
4753     The hot path through the code is dealing with inputs smaller than 2^63
4754     and doing just the conversion, so there is no bits to lose.
4755
4756     In the other path we know the value is positive in the range 2^63..2^64-1
4757     inclusive.  (as for other imput overflow happens and result is undefined)
4758     So we know that the most important bit set in mantissa corresponds to
4759     2^63.  The subtraction of 2^63 should not generate any rounding as it
4760     simply clears out that bit.  The rest is trivial.  */
4761
4762  if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4763    for (fmode = GET_MODE (from); fmode != VOIDmode;
4764	 fmode = GET_MODE_WIDER_MODE (fmode))
4765      if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4766					 &must_trunc))
4767	{
4768	  int bitsize;
4769	  REAL_VALUE_TYPE offset;
4770	  rtx limit, lab1, lab2, insn;
4771
4772	  bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4773	  real_2expN (&offset, bitsize - 1);
4774	  limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4775	  lab1 = gen_label_rtx ();
4776	  lab2 = gen_label_rtx ();
4777
4778	  if (fmode != GET_MODE (from))
4779	    from = convert_to_mode (fmode, from, 0);
4780
4781	  /* See if we need to do the subtraction.  */
4782	  do_pending_stack_adjust ();
4783	  emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4784				   0, lab1);
4785
4786	  /* If not, do the signed "fix" and branch around fixup code.  */
4787	  expand_fix (to, from, 0);
4788	  emit_jump_insn (gen_jump (lab2));
4789	  emit_barrier ();
4790
4791	  /* Otherwise, subtract 2**(N-1), convert to signed number,
4792	     then add 2**(N-1).  Do the addition using XOR since this
4793	     will often generate better code.  */
4794	  emit_label (lab1);
4795	  target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4796				 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4797	  expand_fix (to, target, 0);
4798	  target = expand_binop (GET_MODE (to), xor_optab, to,
4799				 gen_int_mode
4800				 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4801				  GET_MODE (to)),
4802				 to, 1, OPTAB_LIB_WIDEN);
4803
4804	  if (target != to)
4805	    emit_move_insn (to, target);
4806
4807	  emit_label (lab2);
4808
4809	  if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4810	      != CODE_FOR_nothing)
4811	    {
4812	      /* Make a place for a REG_NOTE and add it.  */
4813	      insn = emit_move_insn (to, to);
4814	      set_unique_reg_note (insn,
4815	                           REG_EQUAL,
4816				   gen_rtx_fmt_e (UNSIGNED_FIX,
4817						  GET_MODE (to),
4818						  copy_rtx (from)));
4819	    }
4820
4821	  return;
4822	}
4823
4824  /* We can't do it with an insn, so use a library call.  But first ensure
4825     that the mode of TO is at least as wide as SImode, since those are the
4826     only library calls we know about.  */
4827
4828  if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4829    {
4830      target = gen_reg_rtx (SImode);
4831
4832      expand_fix (target, from, unsignedp);
4833    }
4834  else
4835    {
4836      rtx insns;
4837      rtx value;
4838      rtx libfunc;
4839
4840      convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
4841      libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4842      gcc_assert (libfunc);
4843
4844      start_sequence ();
4845
4846      value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4847				       GET_MODE (to), 1, from,
4848				       GET_MODE (from));
4849      insns = get_insns ();
4850      end_sequence ();
4851
4852      emit_libcall_block (insns, target, value,
4853			  gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4854					 GET_MODE (to), from));
4855    }
4856
4857  if (target != to)
4858    {
4859      if (GET_MODE (to) == GET_MODE (target))
4860        emit_move_insn (to, target);
4861      else
4862        convert_move (to, target, 0);
4863    }
4864}
4865
4866/* Report whether we have an instruction to perform the operation
4867   specified by CODE on operands of mode MODE.  */
4868int
4869have_insn_for (enum rtx_code code, enum machine_mode mode)
4870{
4871  return (code_to_optab[(int) code] != 0
4872	  && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
4873	      != CODE_FOR_nothing));
4874}
4875
4876/* Create a blank optab.  */
4877static optab
4878new_optab (void)
4879{
4880  int i;
4881  optab op = ggc_alloc (sizeof (struct optab));
4882  for (i = 0; i < NUM_MACHINE_MODES; i++)
4883    {
4884      op->handlers[i].insn_code = CODE_FOR_nothing;
4885      op->handlers[i].libfunc = 0;
4886    }
4887
4888  return op;
4889}
4890
4891static convert_optab
4892new_convert_optab (void)
4893{
4894  int i, j;
4895  convert_optab op = ggc_alloc (sizeof (struct convert_optab));
4896  for (i = 0; i < NUM_MACHINE_MODES; i++)
4897    for (j = 0; j < NUM_MACHINE_MODES; j++)
4898      {
4899	op->handlers[i][j].insn_code = CODE_FOR_nothing;
4900	op->handlers[i][j].libfunc = 0;
4901      }
4902  return op;
4903}
4904
4905/* Same, but fill in its code as CODE, and write it into the
4906   code_to_optab table.  */
4907static inline optab
4908init_optab (enum rtx_code code)
4909{
4910  optab op = new_optab ();
4911  op->code = code;
4912  code_to_optab[(int) code] = op;
4913  return op;
4914}
4915
4916/* Same, but fill in its code as CODE, and do _not_ write it into
4917   the code_to_optab table.  */
4918static inline optab
4919init_optabv (enum rtx_code code)
4920{
4921  optab op = new_optab ();
4922  op->code = code;
4923  return op;
4924}
4925
4926/* Conversion optabs never go in the code_to_optab table.  */
4927static inline convert_optab
4928init_convert_optab (enum rtx_code code)
4929{
4930  convert_optab op = new_convert_optab ();
4931  op->code = code;
4932  return op;
4933}
4934
4935/* Initialize the libfunc fields of an entire group of entries in some
4936   optab.  Each entry is set equal to a string consisting of a leading
4937   pair of underscores followed by a generic operation name followed by
4938   a mode name (downshifted to lowercase) followed by a single character
4939   representing the number of operands for the given operation (which is
4940   usually one of the characters '2', '3', or '4').
4941
4942   OPTABLE is the table in which libfunc fields are to be initialized.
4943   FIRST_MODE is the first machine mode index in the given optab to
4944     initialize.
4945   LAST_MODE is the last machine mode index in the given optab to
4946     initialize.
4947   OPNAME is the generic (string) name of the operation.
4948   SUFFIX is the character which specifies the number of operands for
4949     the given generic operation.
4950*/
4951
4952static void
4953init_libfuncs (optab optable, int first_mode, int last_mode,
4954	       const char *opname, int suffix)
4955{
4956  int mode;
4957  unsigned opname_len = strlen (opname);
4958
4959  for (mode = first_mode; (int) mode <= (int) last_mode;
4960       mode = (enum machine_mode) ((int) mode + 1))
4961    {
4962      const char *mname = GET_MODE_NAME (mode);
4963      unsigned mname_len = strlen (mname);
4964      char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
4965      char *p;
4966      const char *q;
4967
4968      p = libfunc_name;
4969      *p++ = '_';
4970      *p++ = '_';
4971      for (q = opname; *q; )
4972	*p++ = *q++;
4973      for (q = mname; *q; q++)
4974	*p++ = TOLOWER (*q);
4975      *p++ = suffix;
4976      *p = '\0';
4977
4978      optable->handlers[(int) mode].libfunc
4979	= init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
4980    }
4981}
4982
4983/* Initialize the libfunc fields of an entire group of entries in some
4984   optab which correspond to all integer mode operations.  The parameters
4985   have the same meaning as similarly named ones for the `init_libfuncs'
4986   routine.  (See above).  */
4987
4988static void
4989init_integral_libfuncs (optab optable, const char *opname, int suffix)
4990{
4991  int maxsize = 2*BITS_PER_WORD;
4992  if (maxsize < LONG_LONG_TYPE_SIZE)
4993    maxsize = LONG_LONG_TYPE_SIZE;
4994  init_libfuncs (optable, word_mode,
4995		 mode_for_size (maxsize, MODE_INT, 0),
4996		 opname, suffix);
4997}
4998
4999/* Initialize the libfunc fields of an entire group of entries in some
5000   optab which correspond to all real mode operations.  The parameters
5001   have the same meaning as similarly named ones for the `init_libfuncs'
5002   routine.  (See above).  */
5003
5004static void
5005init_floating_libfuncs (optab optable, const char *opname, int suffix)
5006{
5007  init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
5008  init_libfuncs (optable, MIN_MODE_DECIMAL_FLOAT, MAX_MODE_DECIMAL_FLOAT,
5009		 opname, suffix);
5010}
5011
5012/* Initialize the libfunc fields of an entire group of entries of an
5013   inter-mode-class conversion optab.  The string formation rules are
5014   similar to the ones for init_libfuncs, above, but instead of having
5015   a mode name and an operand count these functions have two mode names
5016   and no operand count.  */
5017static void
5018init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
5019			       enum mode_class from_class,
5020			       enum mode_class to_class)
5021{
5022  enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
5023  enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
5024  size_t opname_len = strlen (opname);
5025  size_t max_mname_len = 0;
5026
5027  enum machine_mode fmode, tmode;
5028  const char *fname, *tname;
5029  const char *q;
5030  char *libfunc_name, *suffix;
5031  char *p;
5032
5033  for (fmode = first_from_mode;
5034       fmode != VOIDmode;
5035       fmode = GET_MODE_WIDER_MODE (fmode))
5036    max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
5037
5038  for (tmode = first_to_mode;
5039       tmode != VOIDmode;
5040       tmode = GET_MODE_WIDER_MODE (tmode))
5041    max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
5042
5043  libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5044  libfunc_name[0] = '_';
5045  libfunc_name[1] = '_';
5046  memcpy (&libfunc_name[2], opname, opname_len);
5047  suffix = libfunc_name + opname_len + 2;
5048
5049  for (fmode = first_from_mode; fmode != VOIDmode;
5050       fmode = GET_MODE_WIDER_MODE (fmode))
5051    for (tmode = first_to_mode; tmode != VOIDmode;
5052	 tmode = GET_MODE_WIDER_MODE (tmode))
5053      {
5054	fname = GET_MODE_NAME (fmode);
5055	tname = GET_MODE_NAME (tmode);
5056
5057	p = suffix;
5058	for (q = fname; *q; p++, q++)
5059	  *p = TOLOWER (*q);
5060	for (q = tname; *q; p++, q++)
5061	  *p = TOLOWER (*q);
5062
5063	*p = '\0';
5064
5065	tab->handlers[tmode][fmode].libfunc
5066	  = init_one_libfunc (ggc_alloc_string (libfunc_name,
5067						p - libfunc_name));
5068      }
5069}
5070
5071/* Initialize the libfunc fields of an entire group of entries of an
5072   intra-mode-class conversion optab.  The string formation rules are
5073   similar to the ones for init_libfunc, above.  WIDENING says whether
5074   the optab goes from narrow to wide modes or vice versa.  These functions
5075   have two mode names _and_ an operand count.  */
5076static void
5077init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
5078			       enum mode_class class, bool widening)
5079{
5080  enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
5081  size_t opname_len = strlen (opname);
5082  size_t max_mname_len = 0;
5083
5084  enum machine_mode nmode, wmode;
5085  const char *nname, *wname;
5086  const char *q;
5087  char *libfunc_name, *suffix;
5088  char *p;
5089
5090  for (nmode = first_mode; nmode != VOIDmode;
5091       nmode = GET_MODE_WIDER_MODE (nmode))
5092    max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
5093
5094  libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5095  libfunc_name[0] = '_';
5096  libfunc_name[1] = '_';
5097  memcpy (&libfunc_name[2], opname, opname_len);
5098  suffix = libfunc_name + opname_len + 2;
5099
5100  for (nmode = first_mode; nmode != VOIDmode;
5101       nmode = GET_MODE_WIDER_MODE (nmode))
5102    for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
5103	 wmode = GET_MODE_WIDER_MODE (wmode))
5104      {
5105	nname = GET_MODE_NAME (nmode);
5106	wname = GET_MODE_NAME (wmode);
5107
5108	p = suffix;
5109	for (q = widening ? nname : wname; *q; p++, q++)
5110	  *p = TOLOWER (*q);
5111	for (q = widening ? wname : nname; *q; p++, q++)
5112	  *p = TOLOWER (*q);
5113
5114	*p++ = '2';
5115	*p = '\0';
5116
5117	tab->handlers[widening ? wmode : nmode]
5118	             [widening ? nmode : wmode].libfunc
5119	  = init_one_libfunc (ggc_alloc_string (libfunc_name,
5120						p - libfunc_name));
5121      }
5122}
5123
5124
5125rtx
5126init_one_libfunc (const char *name)
5127{
5128  rtx symbol;
5129
5130  /* Create a FUNCTION_DECL that can be passed to
5131     targetm.encode_section_info.  */
5132  /* ??? We don't have any type information except for this is
5133     a function.  Pretend this is "int foo()".  */
5134  tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
5135			  build_function_type (integer_type_node, NULL_TREE));
5136  DECL_ARTIFICIAL (decl) = 1;
5137  DECL_EXTERNAL (decl) = 1;
5138  TREE_PUBLIC (decl) = 1;
5139
5140  symbol = XEXP (DECL_RTL (decl), 0);
5141
5142  /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
5143     are the flags assigned by targetm.encode_section_info.  */
5144  SET_SYMBOL_REF_DECL (symbol, 0);
5145
5146  return symbol;
5147}
5148
5149/* Call this to reset the function entry for one optab (OPTABLE) in mode
5150   MODE to NAME, which should be either 0 or a string constant.  */
5151void
5152set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
5153{
5154  if (name)
5155    optable->handlers[mode].libfunc = init_one_libfunc (name);
5156  else
5157    optable->handlers[mode].libfunc = 0;
5158}
5159
5160/* Call this to reset the function entry for one conversion optab
5161   (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
5162   either 0 or a string constant.  */
5163void
5164set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
5165		  enum machine_mode fmode, const char *name)
5166{
5167  if (name)
5168    optable->handlers[tmode][fmode].libfunc = init_one_libfunc (name);
5169  else
5170    optable->handlers[tmode][fmode].libfunc = 0;
5171}
5172
5173/* Call this once to initialize the contents of the optabs
5174   appropriately for the current target machine.  */
5175
5176void
5177init_optabs (void)
5178{
5179  unsigned int i;
5180
5181  /* Start by initializing all tables to contain CODE_FOR_nothing.  */
5182
5183  for (i = 0; i < NUM_RTX_CODE; i++)
5184    setcc_gen_code[i] = CODE_FOR_nothing;
5185
5186#ifdef HAVE_conditional_move
5187  for (i = 0; i < NUM_MACHINE_MODES; i++)
5188    movcc_gen_code[i] = CODE_FOR_nothing;
5189#endif
5190
5191  for (i = 0; i < NUM_MACHINE_MODES; i++)
5192    {
5193      vcond_gen_code[i] = CODE_FOR_nothing;
5194      vcondu_gen_code[i] = CODE_FOR_nothing;
5195    }
5196
5197  add_optab = init_optab (PLUS);
5198  addv_optab = init_optabv (PLUS);
5199  sub_optab = init_optab (MINUS);
5200  subv_optab = init_optabv (MINUS);
5201  smul_optab = init_optab (MULT);
5202  smulv_optab = init_optabv (MULT);
5203  smul_highpart_optab = init_optab (UNKNOWN);
5204  umul_highpart_optab = init_optab (UNKNOWN);
5205  smul_widen_optab = init_optab (UNKNOWN);
5206  umul_widen_optab = init_optab (UNKNOWN);
5207  usmul_widen_optab = init_optab (UNKNOWN);
5208  sdiv_optab = init_optab (DIV);
5209  sdivv_optab = init_optabv (DIV);
5210  sdivmod_optab = init_optab (UNKNOWN);
5211  udiv_optab = init_optab (UDIV);
5212  udivmod_optab = init_optab (UNKNOWN);
5213  smod_optab = init_optab (MOD);
5214  umod_optab = init_optab (UMOD);
5215  fmod_optab = init_optab (UNKNOWN);
5216  drem_optab = init_optab (UNKNOWN);
5217  ftrunc_optab = init_optab (UNKNOWN);
5218  and_optab = init_optab (AND);
5219  ior_optab = init_optab (IOR);
5220  xor_optab = init_optab (XOR);
5221  ashl_optab = init_optab (ASHIFT);
5222  ashr_optab = init_optab (ASHIFTRT);
5223  lshr_optab = init_optab (LSHIFTRT);
5224  rotl_optab = init_optab (ROTATE);
5225  rotr_optab = init_optab (ROTATERT);
5226  smin_optab = init_optab (SMIN);
5227  smax_optab = init_optab (SMAX);
5228  umin_optab = init_optab (UMIN);
5229  umax_optab = init_optab (UMAX);
5230  pow_optab = init_optab (UNKNOWN);
5231  atan2_optab = init_optab (UNKNOWN);
5232
5233  /* These three have codes assigned exclusively for the sake of
5234     have_insn_for.  */
5235  mov_optab = init_optab (SET);
5236  movstrict_optab = init_optab (STRICT_LOW_PART);
5237  cmp_optab = init_optab (COMPARE);
5238
5239  ucmp_optab = init_optab (UNKNOWN);
5240  tst_optab = init_optab (UNKNOWN);
5241
5242  eq_optab = init_optab (EQ);
5243  ne_optab = init_optab (NE);
5244  gt_optab = init_optab (GT);
5245  ge_optab = init_optab (GE);
5246  lt_optab = init_optab (LT);
5247  le_optab = init_optab (LE);
5248  unord_optab = init_optab (UNORDERED);
5249
5250  neg_optab = init_optab (NEG);
5251  negv_optab = init_optabv (NEG);
5252  abs_optab = init_optab (ABS);
5253  absv_optab = init_optabv (ABS);
5254  addcc_optab = init_optab (UNKNOWN);
5255  one_cmpl_optab = init_optab (NOT);
5256  ffs_optab = init_optab (FFS);
5257  clz_optab = init_optab (CLZ);
5258  ctz_optab = init_optab (CTZ);
5259  popcount_optab = init_optab (POPCOUNT);
5260  parity_optab = init_optab (PARITY);
5261  sqrt_optab = init_optab (SQRT);
5262  floor_optab = init_optab (UNKNOWN);
5263  lfloor_optab = init_optab (UNKNOWN);
5264  ceil_optab = init_optab (UNKNOWN);
5265  lceil_optab = init_optab (UNKNOWN);
5266  round_optab = init_optab (UNKNOWN);
5267  btrunc_optab = init_optab (UNKNOWN);
5268  nearbyint_optab = init_optab (UNKNOWN);
5269  rint_optab = init_optab (UNKNOWN);
5270  lrint_optab = init_optab (UNKNOWN);
5271  sincos_optab = init_optab (UNKNOWN);
5272  sin_optab = init_optab (UNKNOWN);
5273  asin_optab = init_optab (UNKNOWN);
5274  cos_optab = init_optab (UNKNOWN);
5275  acos_optab = init_optab (UNKNOWN);
5276  exp_optab = init_optab (UNKNOWN);
5277  exp10_optab = init_optab (UNKNOWN);
5278  exp2_optab = init_optab (UNKNOWN);
5279  expm1_optab = init_optab (UNKNOWN);
5280  ldexp_optab = init_optab (UNKNOWN);
5281  logb_optab = init_optab (UNKNOWN);
5282  ilogb_optab = init_optab (UNKNOWN);
5283  log_optab = init_optab (UNKNOWN);
5284  log10_optab = init_optab (UNKNOWN);
5285  log2_optab = init_optab (UNKNOWN);
5286  log1p_optab = init_optab (UNKNOWN);
5287  tan_optab = init_optab (UNKNOWN);
5288  atan_optab = init_optab (UNKNOWN);
5289  copysign_optab = init_optab (UNKNOWN);
5290
5291  strlen_optab = init_optab (UNKNOWN);
5292  cbranch_optab = init_optab (UNKNOWN);
5293  cmov_optab = init_optab (UNKNOWN);
5294  cstore_optab = init_optab (UNKNOWN);
5295  push_optab = init_optab (UNKNOWN);
5296
5297  reduc_smax_optab = init_optab (UNKNOWN);
5298  reduc_umax_optab = init_optab (UNKNOWN);
5299  reduc_smin_optab = init_optab (UNKNOWN);
5300  reduc_umin_optab = init_optab (UNKNOWN);
5301  reduc_splus_optab = init_optab (UNKNOWN);
5302  reduc_uplus_optab = init_optab (UNKNOWN);
5303
5304  ssum_widen_optab = init_optab (UNKNOWN);
5305  usum_widen_optab = init_optab (UNKNOWN);
5306  sdot_prod_optab = init_optab (UNKNOWN);
5307  udot_prod_optab = init_optab (UNKNOWN);
5308
5309  vec_extract_optab = init_optab (UNKNOWN);
5310  vec_set_optab = init_optab (UNKNOWN);
5311  vec_init_optab = init_optab (UNKNOWN);
5312  vec_shl_optab = init_optab (UNKNOWN);
5313  vec_shr_optab = init_optab (UNKNOWN);
5314  vec_realign_load_optab = init_optab (UNKNOWN);
5315  movmisalign_optab = init_optab (UNKNOWN);
5316
5317  powi_optab = init_optab (UNKNOWN);
5318
5319  /* Conversions.  */
5320  sext_optab = init_convert_optab (SIGN_EXTEND);
5321  zext_optab = init_convert_optab (ZERO_EXTEND);
5322  trunc_optab = init_convert_optab (TRUNCATE);
5323  sfix_optab = init_convert_optab (FIX);
5324  ufix_optab = init_convert_optab (UNSIGNED_FIX);
5325  sfixtrunc_optab = init_convert_optab (UNKNOWN);
5326  ufixtrunc_optab = init_convert_optab (UNKNOWN);
5327  sfloat_optab = init_convert_optab (FLOAT);
5328  ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
5329
5330  for (i = 0; i < NUM_MACHINE_MODES; i++)
5331    {
5332      movmem_optab[i] = CODE_FOR_nothing;
5333      cmpstr_optab[i] = CODE_FOR_nothing;
5334      cmpstrn_optab[i] = CODE_FOR_nothing;
5335      cmpmem_optab[i] = CODE_FOR_nothing;
5336      setmem_optab[i] = CODE_FOR_nothing;
5337
5338      sync_add_optab[i] = CODE_FOR_nothing;
5339      sync_sub_optab[i] = CODE_FOR_nothing;
5340      sync_ior_optab[i] = CODE_FOR_nothing;
5341      sync_and_optab[i] = CODE_FOR_nothing;
5342      sync_xor_optab[i] = CODE_FOR_nothing;
5343      sync_nand_optab[i] = CODE_FOR_nothing;
5344      sync_old_add_optab[i] = CODE_FOR_nothing;
5345      sync_old_sub_optab[i] = CODE_FOR_nothing;
5346      sync_old_ior_optab[i] = CODE_FOR_nothing;
5347      sync_old_and_optab[i] = CODE_FOR_nothing;
5348      sync_old_xor_optab[i] = CODE_FOR_nothing;
5349      sync_old_nand_optab[i] = CODE_FOR_nothing;
5350      sync_new_add_optab[i] = CODE_FOR_nothing;
5351      sync_new_sub_optab[i] = CODE_FOR_nothing;
5352      sync_new_ior_optab[i] = CODE_FOR_nothing;
5353      sync_new_and_optab[i] = CODE_FOR_nothing;
5354      sync_new_xor_optab[i] = CODE_FOR_nothing;
5355      sync_new_nand_optab[i] = CODE_FOR_nothing;
5356      sync_compare_and_swap[i] = CODE_FOR_nothing;
5357      sync_compare_and_swap_cc[i] = CODE_FOR_nothing;
5358      sync_lock_test_and_set[i] = CODE_FOR_nothing;
5359      sync_lock_release[i] = CODE_FOR_nothing;
5360
5361      reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5362    }
5363
5364  /* Fill in the optabs with the insns we support.  */
5365  init_all_optabs ();
5366
5367  /* Initialize the optabs with the names of the library functions.  */
5368  init_integral_libfuncs (add_optab, "add", '3');
5369  init_floating_libfuncs (add_optab, "add", '3');
5370  init_integral_libfuncs (addv_optab, "addv", '3');
5371  init_floating_libfuncs (addv_optab, "add", '3');
5372  init_integral_libfuncs (sub_optab, "sub", '3');
5373  init_floating_libfuncs (sub_optab, "sub", '3');
5374  init_integral_libfuncs (subv_optab, "subv", '3');
5375  init_floating_libfuncs (subv_optab, "sub", '3');
5376  init_integral_libfuncs (smul_optab, "mul", '3');
5377  init_floating_libfuncs (smul_optab, "mul", '3');
5378  init_integral_libfuncs (smulv_optab, "mulv", '3');
5379  init_floating_libfuncs (smulv_optab, "mul", '3');
5380  init_integral_libfuncs (sdiv_optab, "div", '3');
5381  init_floating_libfuncs (sdiv_optab, "div", '3');
5382  init_integral_libfuncs (sdivv_optab, "divv", '3');
5383  init_integral_libfuncs (udiv_optab, "udiv", '3');
5384  init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5385  init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5386  init_integral_libfuncs (smod_optab, "mod", '3');
5387  init_integral_libfuncs (umod_optab, "umod", '3');
5388  init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5389  init_integral_libfuncs (and_optab, "and", '3');
5390  init_integral_libfuncs (ior_optab, "ior", '3');
5391  init_integral_libfuncs (xor_optab, "xor", '3');
5392  init_integral_libfuncs (ashl_optab, "ashl", '3');
5393  init_integral_libfuncs (ashr_optab, "ashr", '3');
5394  init_integral_libfuncs (lshr_optab, "lshr", '3');
5395  init_integral_libfuncs (smin_optab, "min", '3');
5396  init_floating_libfuncs (smin_optab, "min", '3');
5397  init_integral_libfuncs (smax_optab, "max", '3');
5398  init_floating_libfuncs (smax_optab, "max", '3');
5399  init_integral_libfuncs (umin_optab, "umin", '3');
5400  init_integral_libfuncs (umax_optab, "umax", '3');
5401  init_integral_libfuncs (neg_optab, "neg", '2');
5402  init_floating_libfuncs (neg_optab, "neg", '2');
5403  init_integral_libfuncs (negv_optab, "negv", '2');
5404  init_floating_libfuncs (negv_optab, "neg", '2');
5405  init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5406  init_integral_libfuncs (ffs_optab, "ffs", '2');
5407  init_integral_libfuncs (clz_optab, "clz", '2');
5408  init_integral_libfuncs (ctz_optab, "ctz", '2');
5409  init_integral_libfuncs (popcount_optab, "popcount", '2');
5410  init_integral_libfuncs (parity_optab, "parity", '2');
5411
5412  /* Comparison libcalls for integers MUST come in pairs,
5413     signed/unsigned.  */
5414  init_integral_libfuncs (cmp_optab, "cmp", '2');
5415  init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5416  init_floating_libfuncs (cmp_optab, "cmp", '2');
5417
5418  /* EQ etc are floating point only.  */
5419  init_floating_libfuncs (eq_optab, "eq", '2');
5420  init_floating_libfuncs (ne_optab, "ne", '2');
5421  init_floating_libfuncs (gt_optab, "gt", '2');
5422  init_floating_libfuncs (ge_optab, "ge", '2');
5423  init_floating_libfuncs (lt_optab, "lt", '2');
5424  init_floating_libfuncs (le_optab, "le", '2');
5425  init_floating_libfuncs (unord_optab, "unord", '2');
5426
5427  init_floating_libfuncs (powi_optab, "powi", '2');
5428
5429  /* Conversions.  */
5430  init_interclass_conv_libfuncs (sfloat_optab, "float",
5431				 MODE_INT, MODE_FLOAT);
5432  init_interclass_conv_libfuncs (sfloat_optab, "float",
5433				 MODE_INT, MODE_DECIMAL_FLOAT);
5434  init_interclass_conv_libfuncs (ufloat_optab, "floatun",
5435				 MODE_INT, MODE_FLOAT);
5436  init_interclass_conv_libfuncs (ufloat_optab, "floatun",
5437				 MODE_INT, MODE_DECIMAL_FLOAT);
5438  init_interclass_conv_libfuncs (sfix_optab, "fix",
5439				 MODE_FLOAT, MODE_INT);
5440  init_interclass_conv_libfuncs (sfix_optab, "fix",
5441				 MODE_DECIMAL_FLOAT, MODE_INT);
5442  init_interclass_conv_libfuncs (ufix_optab, "fixuns",
5443				 MODE_FLOAT, MODE_INT);
5444  init_interclass_conv_libfuncs (ufix_optab, "fixuns",
5445				 MODE_DECIMAL_FLOAT, MODE_INT);
5446  init_interclass_conv_libfuncs (ufloat_optab, "floatuns",
5447				 MODE_INT, MODE_DECIMAL_FLOAT);
5448
5449  /* sext_optab is also used for FLOAT_EXTEND.  */
5450  init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
5451  init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, true);
5452  init_interclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, MODE_DECIMAL_FLOAT);
5453  init_interclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, MODE_FLOAT);
5454  init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
5455  init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, false);
5456  init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, MODE_DECIMAL_FLOAT);
5457  init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, MODE_FLOAT);
5458
5459  /* Use cabs for double complex abs, since systems generally have cabs.
5460     Don't define any libcall for float complex, so that cabs will be used.  */
5461  if (complex_double_type_node)
5462    abs_optab->handlers[TYPE_MODE (complex_double_type_node)].libfunc
5463      = init_one_libfunc ("cabs");
5464
5465  /* The ffs function operates on `int'.  */
5466  ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5467    = init_one_libfunc ("ffs");
5468
5469  abort_libfunc = init_one_libfunc ("abort");
5470  memcpy_libfunc = init_one_libfunc ("memcpy");
5471  memmove_libfunc = init_one_libfunc ("memmove");
5472  memcmp_libfunc = init_one_libfunc ("memcmp");
5473  memset_libfunc = init_one_libfunc ("memset");
5474  setbits_libfunc = init_one_libfunc ("__setbits");
5475
5476#ifndef DONT_USE_BUILTIN_SETJMP
5477  setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5478  longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5479#else
5480  setjmp_libfunc = init_one_libfunc ("setjmp");
5481  longjmp_libfunc = init_one_libfunc ("longjmp");
5482#endif
5483  unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5484  unwind_sjlj_unregister_libfunc
5485    = init_one_libfunc ("_Unwind_SjLj_Unregister");
5486
5487  /* For function entry/exit instrumentation.  */
5488  profile_function_entry_libfunc
5489    = init_one_libfunc ("__cyg_profile_func_enter");
5490  profile_function_exit_libfunc
5491    = init_one_libfunc ("__cyg_profile_func_exit");
5492
5493  gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
5494
5495  if (HAVE_conditional_trap)
5496    trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5497
5498  /* Allow the target to add more libcalls or rename some, etc.  */
5499  targetm.init_libfuncs ();
5500}
5501
5502#ifdef DEBUG
5503
5504/* Print information about the current contents of the optabs on
5505   STDERR.  */
5506
5507static void
5508debug_optab_libfuncs (void)
5509{
5510  int i;
5511  int j;
5512  int k;
5513
5514  /* Dump the arithmetic optabs.  */
5515  for (i = 0; i != (int) OTI_MAX; i++)
5516    for (j = 0; j < NUM_MACHINE_MODES; ++j)
5517      {
5518	optab o;
5519	struct optab_handlers *h;
5520
5521	o = optab_table[i];
5522	h = &o->handlers[j];
5523	if (h->libfunc)
5524	  {
5525	    gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5526	    fprintf (stderr, "%s\t%s:\t%s\n",
5527		     GET_RTX_NAME (o->code),
5528		     GET_MODE_NAME (j),
5529		     XSTR (h->libfunc, 0));
5530	  }
5531      }
5532
5533  /* Dump the conversion optabs.  */
5534  for (i = 0; i < (int) COI_MAX; ++i)
5535    for (j = 0; j < NUM_MACHINE_MODES; ++j)
5536      for (k = 0; k < NUM_MACHINE_MODES; ++k)
5537	{
5538	  convert_optab o;
5539	  struct optab_handlers *h;
5540
5541	  o = &convert_optab_table[i];
5542	  h = &o->handlers[j][k];
5543	  if (h->libfunc)
5544	    {
5545	      gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5546	      fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5547		       GET_RTX_NAME (o->code),
5548		       GET_MODE_NAME (j),
5549		       GET_MODE_NAME (k),
5550		       XSTR (h->libfunc, 0));
5551	    }
5552	}
5553}
5554
5555#endif /* DEBUG */
5556
5557
5558/* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5559   CODE.  Return 0 on failure.  */
5560
5561rtx
5562gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
5563	       rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
5564{
5565  enum machine_mode mode = GET_MODE (op1);
5566  enum insn_code icode;
5567  rtx insn;
5568
5569  if (!HAVE_conditional_trap)
5570    return 0;
5571
5572  if (mode == VOIDmode)
5573    return 0;
5574
5575  icode = cmp_optab->handlers[(int) mode].insn_code;
5576  if (icode == CODE_FOR_nothing)
5577    return 0;
5578
5579  start_sequence ();
5580  op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
5581  op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
5582  if (!op1 || !op2)
5583    {
5584      end_sequence ();
5585      return 0;
5586    }
5587  emit_insn (GEN_FCN (icode) (op1, op2));
5588
5589  PUT_CODE (trap_rtx, code);
5590  gcc_assert (HAVE_conditional_trap);
5591  insn = gen_conditional_trap (trap_rtx, tcode);
5592  if (insn)
5593    {
5594      emit_insn (insn);
5595      insn = get_insns ();
5596    }
5597  end_sequence ();
5598
5599  return insn;
5600}
5601
5602/* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5603   or unsigned operation code.  */
5604
5605static enum rtx_code
5606get_rtx_code (enum tree_code tcode, bool unsignedp)
5607{
5608  enum rtx_code code;
5609  switch (tcode)
5610    {
5611    case EQ_EXPR:
5612      code = EQ;
5613      break;
5614    case NE_EXPR:
5615      code = NE;
5616      break;
5617    case LT_EXPR:
5618      code = unsignedp ? LTU : LT;
5619      break;
5620    case LE_EXPR:
5621      code = unsignedp ? LEU : LE;
5622      break;
5623    case GT_EXPR:
5624      code = unsignedp ? GTU : GT;
5625      break;
5626    case GE_EXPR:
5627      code = unsignedp ? GEU : GE;
5628      break;
5629
5630    case UNORDERED_EXPR:
5631      code = UNORDERED;
5632      break;
5633    case ORDERED_EXPR:
5634      code = ORDERED;
5635      break;
5636    case UNLT_EXPR:
5637      code = UNLT;
5638      break;
5639    case UNLE_EXPR:
5640      code = UNLE;
5641      break;
5642    case UNGT_EXPR:
5643      code = UNGT;
5644      break;
5645    case UNGE_EXPR:
5646      code = UNGE;
5647      break;
5648    case UNEQ_EXPR:
5649      code = UNEQ;
5650      break;
5651    case LTGT_EXPR:
5652      code = LTGT;
5653      break;
5654
5655    default:
5656      gcc_unreachable ();
5657    }
5658  return code;
5659}
5660
5661/* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
5662   unsigned operators. Do not generate compare instruction.  */
5663
5664static rtx
5665vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
5666{
5667  enum rtx_code rcode;
5668  tree t_op0, t_op1;
5669  rtx rtx_op0, rtx_op1;
5670
5671  /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
5672     ensures that condition is a relational operation.  */
5673  gcc_assert (COMPARISON_CLASS_P (cond));
5674
5675  rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
5676  t_op0 = TREE_OPERAND (cond, 0);
5677  t_op1 = TREE_OPERAND (cond, 1);
5678
5679  /* Expand operands.  */
5680  rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)), 1);
5681  rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)), 1);
5682
5683  if (!insn_data[icode].operand[4].predicate (rtx_op0, GET_MODE (rtx_op0))
5684      && GET_MODE (rtx_op0) != VOIDmode)
5685    rtx_op0 = force_reg (GET_MODE (rtx_op0), rtx_op0);
5686
5687  if (!insn_data[icode].operand[5].predicate (rtx_op1, GET_MODE (rtx_op1))
5688      && GET_MODE (rtx_op1) != VOIDmode)
5689    rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
5690
5691  return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1);
5692}
5693
5694/* Return insn code for VEC_COND_EXPR EXPR.  */
5695
5696static inline enum insn_code
5697get_vcond_icode (tree expr, enum machine_mode mode)
5698{
5699  enum insn_code icode = CODE_FOR_nothing;
5700
5701  if (TYPE_UNSIGNED (TREE_TYPE (expr)))
5702    icode = vcondu_gen_code[mode];
5703  else
5704    icode = vcond_gen_code[mode];
5705  return icode;
5706}
5707
5708/* Return TRUE iff, appropriate vector insns are available
5709   for vector cond expr expr in VMODE mode.  */
5710
5711bool
5712expand_vec_cond_expr_p (tree expr, enum machine_mode vmode)
5713{
5714  if (get_vcond_icode (expr, vmode) == CODE_FOR_nothing)
5715    return false;
5716  return true;
5717}
5718
5719/* Generate insns for VEC_COND_EXPR.  */
5720
5721rtx
5722expand_vec_cond_expr (tree vec_cond_expr, rtx target)
5723{
5724  enum insn_code icode;
5725  rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1;
5726  enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_cond_expr));
5727  bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr));
5728
5729  icode = get_vcond_icode (vec_cond_expr, mode);
5730  if (icode == CODE_FOR_nothing)
5731    return 0;
5732
5733  if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5734    target = gen_reg_rtx (mode);
5735
5736  /* Get comparison rtx.  First expand both cond expr operands.  */
5737  comparison = vector_compare_rtx (TREE_OPERAND (vec_cond_expr, 0),
5738				   unsignedp, icode);
5739  cc_op0 = XEXP (comparison, 0);
5740  cc_op1 = XEXP (comparison, 1);
5741  /* Expand both operands and force them in reg, if required.  */
5742  rtx_op1 = expand_expr (TREE_OPERAND (vec_cond_expr, 1),
5743			 NULL_RTX, VOIDmode, EXPAND_NORMAL);
5744  if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
5745      && mode != VOIDmode)
5746    rtx_op1 = force_reg (mode, rtx_op1);
5747
5748  rtx_op2 = expand_expr (TREE_OPERAND (vec_cond_expr, 2),
5749			 NULL_RTX, VOIDmode, EXPAND_NORMAL);
5750  if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
5751      && mode != VOIDmode)
5752    rtx_op2 = force_reg (mode, rtx_op2);
5753
5754  /* Emit instruction! */
5755  emit_insn (GEN_FCN (icode) (target, rtx_op1, rtx_op2,
5756			      comparison, cc_op0,  cc_op1));
5757
5758  return target;
5759}
5760
5761
5762/* This is an internal subroutine of the other compare_and_swap expanders.
5763   MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
5764   operation.  TARGET is an optional place to store the value result of
5765   the operation.  ICODE is the particular instruction to expand.  Return
5766   the result of the operation.  */
5767
5768static rtx
5769expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
5770			       rtx target, enum insn_code icode)
5771{
5772  enum machine_mode mode = GET_MODE (mem);
5773  rtx insn;
5774
5775  if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5776    target = gen_reg_rtx (mode);
5777
5778  if (GET_MODE (old_val) != VOIDmode && GET_MODE (old_val) != mode)
5779    old_val = convert_modes (mode, GET_MODE (old_val), old_val, 1);
5780  if (!insn_data[icode].operand[2].predicate (old_val, mode))
5781    old_val = force_reg (mode, old_val);
5782
5783  if (GET_MODE (new_val) != VOIDmode && GET_MODE (new_val) != mode)
5784    new_val = convert_modes (mode, GET_MODE (new_val), new_val, 1);
5785  if (!insn_data[icode].operand[3].predicate (new_val, mode))
5786    new_val = force_reg (mode, new_val);
5787
5788  insn = GEN_FCN (icode) (target, mem, old_val, new_val);
5789  if (insn == NULL_RTX)
5790    return NULL_RTX;
5791  emit_insn (insn);
5792
5793  return target;
5794}
5795
5796/* Expand a compare-and-swap operation and return its value.  */
5797
5798rtx
5799expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5800{
5801  enum machine_mode mode = GET_MODE (mem);
5802  enum insn_code icode = sync_compare_and_swap[mode];
5803
5804  if (icode == CODE_FOR_nothing)
5805    return NULL_RTX;
5806
5807  return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
5808}
5809
5810/* Expand a compare-and-swap operation and store true into the result if
5811   the operation was successful and false otherwise.  Return the result.
5812   Unlike other routines, TARGET is not optional.  */
5813
5814rtx
5815expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5816{
5817  enum machine_mode mode = GET_MODE (mem);
5818  enum insn_code icode;
5819  rtx subtarget, label0, label1;
5820
5821  /* If the target supports a compare-and-swap pattern that simultaneously
5822     sets some flag for success, then use it.  Otherwise use the regular
5823     compare-and-swap and follow that immediately with a compare insn.  */
5824  icode = sync_compare_and_swap_cc[mode];
5825  switch (icode)
5826    {
5827    default:
5828      subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5829						 NULL_RTX, icode);
5830      if (subtarget != NULL_RTX)
5831	break;
5832
5833      /* FALLTHRU */
5834    case CODE_FOR_nothing:
5835      icode = sync_compare_and_swap[mode];
5836      if (icode == CODE_FOR_nothing)
5837	return NULL_RTX;
5838
5839      /* Ensure that if old_val == mem, that we're not comparing
5840	 against an old value.  */
5841      if (MEM_P (old_val))
5842	old_val = force_reg (mode, old_val);
5843
5844      subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5845						 NULL_RTX, icode);
5846      if (subtarget == NULL_RTX)
5847	return NULL_RTX;
5848
5849      emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
5850    }
5851
5852  /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
5853     setcc instruction from the beginning.  We don't work too hard here,
5854     but it's nice to not be stupid about initial code gen either.  */
5855  if (STORE_FLAG_VALUE == 1)
5856    {
5857      icode = setcc_gen_code[EQ];
5858      if (icode != CODE_FOR_nothing)
5859	{
5860	  enum machine_mode cmode = insn_data[icode].operand[0].mode;
5861	  rtx insn;
5862
5863	  subtarget = target;
5864	  if (!insn_data[icode].operand[0].predicate (target, cmode))
5865	    subtarget = gen_reg_rtx (cmode);
5866
5867	  insn = GEN_FCN (icode) (subtarget);
5868	  if (insn)
5869	    {
5870	      emit_insn (insn);
5871	      if (GET_MODE (target) != GET_MODE (subtarget))
5872		{
5873	          convert_move (target, subtarget, 1);
5874		  subtarget = target;
5875		}
5876	      return subtarget;
5877	    }
5878	}
5879    }
5880
5881  /* Without an appropriate setcc instruction, use a set of branches to
5882     get 1 and 0 stored into target.  Presumably if the target has a
5883     STORE_FLAG_VALUE that isn't 1, then this will get cleaned up by ifcvt.  */
5884
5885  label0 = gen_label_rtx ();
5886  label1 = gen_label_rtx ();
5887
5888  emit_jump_insn (bcc_gen_fctn[EQ] (label0));
5889  emit_move_insn (target, const0_rtx);
5890  emit_jump_insn (gen_jump (label1));
5891  emit_barrier ();
5892  emit_label (label0);
5893  emit_move_insn (target, const1_rtx);
5894  emit_label (label1);
5895
5896  return target;
5897}
5898
5899/* This is a helper function for the other atomic operations.  This function
5900   emits a loop that contains SEQ that iterates until a compare-and-swap
5901   operation at the end succeeds.  MEM is the memory to be modified.  SEQ is
5902   a set of instructions that takes a value from OLD_REG as an input and
5903   produces a value in NEW_REG as an output.  Before SEQ, OLD_REG will be
5904   set to the current contents of MEM.  After SEQ, a compare-and-swap will
5905   attempt to update MEM with NEW_REG.  The function returns true when the
5906   loop was generated successfully.  */
5907
5908static bool
5909expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5910{
5911  enum machine_mode mode = GET_MODE (mem);
5912  enum insn_code icode;
5913  rtx label, cmp_reg, subtarget;
5914
5915  /* The loop we want to generate looks like
5916
5917	cmp_reg = mem;
5918      label:
5919        old_reg = cmp_reg;
5920	seq;
5921	cmp_reg = compare-and-swap(mem, old_reg, new_reg)
5922	if (cmp_reg != old_reg)
5923	  goto label;
5924
5925     Note that we only do the plain load from memory once.  Subsequent
5926     iterations use the value loaded by the compare-and-swap pattern.  */
5927
5928  label = gen_label_rtx ();
5929  cmp_reg = gen_reg_rtx (mode);
5930
5931  emit_move_insn (cmp_reg, mem);
5932  emit_label (label);
5933  emit_move_insn (old_reg, cmp_reg);
5934  if (seq)
5935    emit_insn (seq);
5936
5937  /* If the target supports a compare-and-swap pattern that simultaneously
5938     sets some flag for success, then use it.  Otherwise use the regular
5939     compare-and-swap and follow that immediately with a compare insn.  */
5940  icode = sync_compare_and_swap_cc[mode];
5941  switch (icode)
5942    {
5943    default:
5944      subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
5945						 cmp_reg, icode);
5946      if (subtarget != NULL_RTX)
5947	{
5948	  gcc_assert (subtarget == cmp_reg);
5949	  break;
5950	}
5951
5952      /* FALLTHRU */
5953    case CODE_FOR_nothing:
5954      icode = sync_compare_and_swap[mode];
5955      if (icode == CODE_FOR_nothing)
5956	return false;
5957
5958      subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
5959						 cmp_reg, icode);
5960      if (subtarget == NULL_RTX)
5961	return false;
5962      if (subtarget != cmp_reg)
5963	emit_move_insn (cmp_reg, subtarget);
5964
5965      emit_cmp_insn (cmp_reg, old_reg, EQ, const0_rtx, mode, true);
5966    }
5967
5968  /* ??? Mark this jump predicted not taken?  */
5969  emit_jump_insn (bcc_gen_fctn[NE] (label));
5970
5971  return true;
5972}
5973
5974/* This function generates the atomic operation MEM CODE= VAL.  In this
5975   case, we do not care about any resulting value.  Returns NULL if we
5976   cannot generate the operation.  */
5977
5978rtx
5979expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
5980{
5981  enum machine_mode mode = GET_MODE (mem);
5982  enum insn_code icode;
5983  rtx insn;
5984
5985  /* Look to see if the target supports the operation directly.  */
5986  switch (code)
5987    {
5988    case PLUS:
5989      icode = sync_add_optab[mode];
5990      break;
5991    case IOR:
5992      icode = sync_ior_optab[mode];
5993      break;
5994    case XOR:
5995      icode = sync_xor_optab[mode];
5996      break;
5997    case AND:
5998      icode = sync_and_optab[mode];
5999      break;
6000    case NOT:
6001      icode = sync_nand_optab[mode];
6002      break;
6003
6004    case MINUS:
6005      icode = sync_sub_optab[mode];
6006      if (icode == CODE_FOR_nothing)
6007	{
6008	  icode = sync_add_optab[mode];
6009	  if (icode != CODE_FOR_nothing)
6010	    {
6011	      val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6012	      code = PLUS;
6013	    }
6014	}
6015      break;
6016
6017    default:
6018      gcc_unreachable ();
6019    }
6020
6021  /* Generate the direct operation, if present.  */
6022  if (icode != CODE_FOR_nothing)
6023    {
6024      if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6025	val = convert_modes (mode, GET_MODE (val), val, 1);
6026      if (!insn_data[icode].operand[1].predicate (val, mode))
6027	val = force_reg (mode, val);
6028
6029      insn = GEN_FCN (icode) (mem, val);
6030      if (insn)
6031	{
6032	  emit_insn (insn);
6033	  return const0_rtx;
6034	}
6035    }
6036
6037  /* Failing that, generate a compare-and-swap loop in which we perform the
6038     operation with normal arithmetic instructions.  */
6039  if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6040    {
6041      rtx t0 = gen_reg_rtx (mode), t1;
6042
6043      start_sequence ();
6044
6045      t1 = t0;
6046      if (code == NOT)
6047	{
6048	  t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
6049	  code = AND;
6050	}
6051      t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6052				true, OPTAB_LIB_WIDEN);
6053
6054      insn = get_insns ();
6055      end_sequence ();
6056
6057      if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6058	return const0_rtx;
6059    }
6060
6061  return NULL_RTX;
6062}
6063
6064/* This function generates the atomic operation MEM CODE= VAL.  In this
6065   case, we do care about the resulting value: if AFTER is true then
6066   return the value MEM holds after the operation, if AFTER is false
6067   then return the value MEM holds before the operation.  TARGET is an
6068   optional place for the result value to be stored.  */
6069
6070rtx
6071expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
6072			     bool after, rtx target)
6073{
6074  enum machine_mode mode = GET_MODE (mem);
6075  enum insn_code old_code, new_code, icode;
6076  bool compensate;
6077  rtx insn;
6078
6079  /* Look to see if the target supports the operation directly.  */
6080  switch (code)
6081    {
6082    case PLUS:
6083      old_code = sync_old_add_optab[mode];
6084      new_code = sync_new_add_optab[mode];
6085      break;
6086    case IOR:
6087      old_code = sync_old_ior_optab[mode];
6088      new_code = sync_new_ior_optab[mode];
6089      break;
6090    case XOR:
6091      old_code = sync_old_xor_optab[mode];
6092      new_code = sync_new_xor_optab[mode];
6093      break;
6094    case AND:
6095      old_code = sync_old_and_optab[mode];
6096      new_code = sync_new_and_optab[mode];
6097      break;
6098    case NOT:
6099      old_code = sync_old_nand_optab[mode];
6100      new_code = sync_new_nand_optab[mode];
6101      break;
6102
6103    case MINUS:
6104      old_code = sync_old_sub_optab[mode];
6105      new_code = sync_new_sub_optab[mode];
6106      if (old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
6107	{
6108	  old_code = sync_old_add_optab[mode];
6109	  new_code = sync_new_add_optab[mode];
6110	  if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
6111	    {
6112	      val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6113	      code = PLUS;
6114	    }
6115	}
6116      break;
6117
6118    default:
6119      gcc_unreachable ();
6120    }
6121
6122  /* If the target does supports the proper new/old operation, great.  But
6123     if we only support the opposite old/new operation, check to see if we
6124     can compensate.  In the case in which the old value is supported, then
6125     we can always perform the operation again with normal arithmetic.  In
6126     the case in which the new value is supported, then we can only handle
6127     this in the case the operation is reversible.  */
6128  compensate = false;
6129  if (after)
6130    {
6131      icode = new_code;
6132      if (icode == CODE_FOR_nothing)
6133	{
6134	  icode = old_code;
6135	  if (icode != CODE_FOR_nothing)
6136	    compensate = true;
6137	}
6138    }
6139  else
6140    {
6141      icode = old_code;
6142      if (icode == CODE_FOR_nothing
6143	  && (code == PLUS || code == MINUS || code == XOR))
6144	{
6145	  icode = new_code;
6146	  if (icode != CODE_FOR_nothing)
6147	    compensate = true;
6148	}
6149    }
6150
6151  /* If we found something supported, great.  */
6152  if (icode != CODE_FOR_nothing)
6153    {
6154      if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6155	target = gen_reg_rtx (mode);
6156
6157      if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6158	val = convert_modes (mode, GET_MODE (val), val, 1);
6159      if (!insn_data[icode].operand[2].predicate (val, mode))
6160	val = force_reg (mode, val);
6161
6162      insn = GEN_FCN (icode) (target, mem, val);
6163      if (insn)
6164	{
6165	  emit_insn (insn);
6166
6167	  /* If we need to compensate for using an operation with the
6168	     wrong return value, do so now.  */
6169	  if (compensate)
6170	    {
6171	      if (!after)
6172		{
6173		  if (code == PLUS)
6174		    code = MINUS;
6175		  else if (code == MINUS)
6176		    code = PLUS;
6177		}
6178
6179	      if (code == NOT)
6180		target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
6181	      target = expand_simple_binop (mode, code, target, val, NULL_RTX,
6182					    true, OPTAB_LIB_WIDEN);
6183	    }
6184
6185	  return target;
6186	}
6187    }
6188
6189  /* Failing that, generate a compare-and-swap loop in which we perform the
6190     operation with normal arithmetic instructions.  */
6191  if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6192    {
6193      rtx t0 = gen_reg_rtx (mode), t1;
6194
6195      if (!target || !register_operand (target, mode))
6196	target = gen_reg_rtx (mode);
6197
6198      start_sequence ();
6199
6200      if (!after)
6201	emit_move_insn (target, t0);
6202      t1 = t0;
6203      if (code == NOT)
6204	{
6205	  t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
6206	  code = AND;
6207	}
6208      t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6209				true, OPTAB_LIB_WIDEN);
6210      if (after)
6211	emit_move_insn (target, t1);
6212
6213      insn = get_insns ();
6214      end_sequence ();
6215
6216      if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6217	return target;
6218    }
6219
6220  return NULL_RTX;
6221}
6222
6223/* This function expands a test-and-set operation.  Ideally we atomically
6224   store VAL in MEM and return the previous value in MEM.  Some targets
6225   may not support this operation and only support VAL with the constant 1;
6226   in this case while the return value will be 0/1, but the exact value
6227   stored in MEM is target defined.  TARGET is an option place to stick
6228   the return value.  */
6229
6230rtx
6231expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
6232{
6233  enum machine_mode mode = GET_MODE (mem);
6234  enum insn_code icode;
6235  rtx insn;
6236
6237  /* If the target supports the test-and-set directly, great.  */
6238  icode = sync_lock_test_and_set[mode];
6239  if (icode != CODE_FOR_nothing)
6240    {
6241      if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6242	target = gen_reg_rtx (mode);
6243
6244      if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6245	val = convert_modes (mode, GET_MODE (val), val, 1);
6246      if (!insn_data[icode].operand[2].predicate (val, mode))
6247	val = force_reg (mode, val);
6248
6249      insn = GEN_FCN (icode) (target, mem, val);
6250      if (insn)
6251	{
6252	  emit_insn (insn);
6253	  return target;
6254	}
6255    }
6256
6257  /* Otherwise, use a compare-and-swap loop for the exchange.  */
6258  if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6259    {
6260      if (!target || !register_operand (target, mode))
6261	target = gen_reg_rtx (mode);
6262      if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6263	val = convert_modes (mode, GET_MODE (val), val, 1);
6264      if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6265	return target;
6266    }
6267
6268  return NULL_RTX;
6269}
6270
6271#include "gt-optabs.h"
6272