/* Expand the basic unary and binary arithmetic operations, for GNU compiler.
   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */


#include "config.h"
#include "system.h"
#include "toplev.h"

/* Include insn-config.h before expr.h so that HAVE_conditional_move
   is properly defined.  */
#include "insn-config.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
#include "flags.h"
#include "function.h"
#include "except.h"
#include "expr.h"
#include "optabs.h"
#include "libfuncs.h"
#include "recog.h"
#include "reload.h"
#include "ggc.h"
#include "real.h"
#include "basic-block.h"

/* Each optab contains info on how this target machine
   can perform a particular operation
   for all sizes and kinds of operands.

   The operation to be performed is often specified
   by passing one of these optabs as an argument.

   See expr.h for documentation of these optabs.  */

optab optab_table[OTI_MAX];

rtx libfunc_table[LTI_MAX];

/* Tables of patterns for extending one integer mode to another.  */
enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];

/* Tables of patterns for converting between fixed and floating point.  */
enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];

/* Contains the optab used for each rtx code.  */
optab code_to_optab[NUM_RTX_CODE + 1];

/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
   gives the gen_function to make a branch to test that condition.  */

rtxfun bcc_gen_fctn[NUM_RTX_CODE];

/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
   gives the insn code to make a store-condition insn
   to test that condition.  */

enum insn_code setcc_gen_code[NUM_RTX_CODE];

#ifdef HAVE_conditional_move
/* Indexed by the machine mode, gives the insn code to make a conditional
   move insn.  This is not indexed by the rtx-code like bcc_gen_fctn and
   setcc_gen_code to cut down on the number of named patterns.  Consider a day
   when a lot more rtx codes are conditional (eg: for the ARM).  */

enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
#endif

/* The insn generating function can not take an rtx_code argument.
   TRAP_RTX is used as an rtx argument.  Its code is replaced with
   the code to be used in the trap insn and all other fields are ignored.  */
static GTY(()) rtx trap_rtx;

static int add_equal_note	PARAMS ((rtx, rtx, enum rtx_code, rtx, rtx));
static rtx widen_operand	PARAMS ((rtx, enum machine_mode,
				       enum machine_mode, int, int));
static int expand_cmplxdiv_straight PARAMS ((rtx, rtx, rtx, rtx,
					   rtx, rtx, enum machine_mode,
					   int, enum optab_methods,
					   enum mode_class, optab));
static int expand_cmplxdiv_wide PARAMS ((rtx, rtx, rtx, rtx,
				       rtx, rtx, enum machine_mode,
				       int, enum optab_methods,
				       enum mode_class, optab));
static void prepare_cmp_insn PARAMS ((rtx *, rtx *, enum rtx_code *, rtx,
				      enum machine_mode *, int *,
				      enum can_compare_purpose));
static enum insn_code can_fix_p	PARAMS ((enum machine_mode, enum machine_mode,
				       int, int *));
static enum insn_code can_float_p PARAMS ((enum machine_mode,
					   enum machine_mode,
					   int));
static rtx ftruncify	PARAMS ((rtx));
static optab new_optab	PARAMS ((void));
static inline optab init_optab	PARAMS ((enum rtx_code));
static inline optab init_optabv	PARAMS ((enum rtx_code));
static void init_libfuncs PARAMS ((optab, int, int, const char *, int));
static void init_integral_libfuncs PARAMS ((optab, const char *, int));
static void init_floating_libfuncs PARAMS ((optab, const char *, int));
static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode,
					    enum rtx_code, int, rtx));
static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
					 enum machine_mode *, int *));
static rtx expand_vector_binop PARAMS ((enum machine_mode, optab,
					rtx, rtx, rtx, int,
					enum optab_methods));
static rtx expand_vector_unop PARAMS ((enum machine_mode, optab, rtx, rtx,
				       int));

#ifndef HAVE_conditional_trap
#define HAVE_conditional_trap 0
#define gen_conditional_trap(a,b) (abort (), NULL_RTX)
#endif

/* Add a REG_EQUAL note to the last insn in INSNS.  TARGET is being set to
   the result of operation CODE applied to OP0 (and OP1 if it is a binary
   operation).

   If the last insn does not set TARGET, don't do anything, but return 1.

   If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
   don't add the REG_EQUAL note but return 0.  Our caller can then try
   again, ensuring that TARGET is not one of the operands.  */

static int
add_equal_note (insns, target, code, op0, op1)
     rtx insns;
     rtx target;
     enum rtx_code code;
     rtx op0, op1;
{
  rtx last_insn, insn, set;
  rtx note;

  if (! insns
      || ! INSN_P (insns)
      || NEXT_INSN (insns) == NULL_RTX)
    abort ();

  if (GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
      && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
    return 1;

  if (GET_CODE (target) == ZERO_EXTRACT)
    return 1;

  for (last_insn = insns;
       NEXT_INSN (last_insn) != NULL_RTX;
       last_insn = NEXT_INSN (last_insn))
    ;

  set = single_set (last_insn);
  if (set == NULL_RTX)
    return 1;

  if (! rtx_equal_p (SET_DEST (set), target)
      /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
	 SUBREG.  */
      && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
	  || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
			    target)))
    return 1;

  /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
     besides the last insn.  */
  if (reg_overlap_mentioned_p (target, op0)
      || (op1 && reg_overlap_mentioned_p (target, op1)))
    {
      insn = PREV_INSN (last_insn);
      while (insn != NULL_RTX)
	{
	  if (reg_set_p (target, insn))
	    return 0;

	  insn = PREV_INSN (insn);
	}
    }

  if (GET_RTX_CLASS (code) == '1')
    note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
  else
    note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));

  set_unique_reg_note (last_insn, REG_EQUAL, note);

  return 1;
}

/* Widen OP to MODE and return the rtx for the widened operand.  UNSIGNEDP
   says whether OP is signed or unsigned.  NO_EXTEND is nonzero if we need
   not actually do a sign-extend or zero-extend, but can leave the 
   higher-order bits of the result rtx undefined, for example, in the case
   of logical operations, but not right shifts.  */

static rtx
widen_operand (op, mode, oldmode, unsignedp, no_extend)
     rtx op;
     enum machine_mode mode, oldmode;
     int unsignedp;
     int no_extend;
{
  rtx result;

  /* If we don't have to extend and this is a constant, return it.  */
  if (no_extend && GET_MODE (op) == VOIDmode)
    return op;

  /* If we must extend do so.  If OP is a SUBREG for a promoted object, also
     extend since it will be more efficient to do so unless the signedness of
     a promoted object differs from our extension.  */
  if (! no_extend
      || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
	  && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
    return convert_modes (mode, oldmode, op, unsignedp);

  /* If MODE is no wider than a single word, we return a paradoxical
     SUBREG.  */
  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
    return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);

  /* Otherwise, get an object of MODE, clobber it, and set the low-order
     part to OP.  */

  result = gen_reg_rtx (mode);
  emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
  emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
  return result;
}

/* Generate code to perform a straightforward complex divide.  */

static int
expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
			  unsignedp, methods, class, binoptab)
     rtx real0, real1, imag0, imag1, realr, imagr;
     enum machine_mode submode;
     int unsignedp;
     enum optab_methods methods;
     enum mode_class class;
     optab binoptab;
{
  rtx divisor;
  rtx real_t, imag_t;
  rtx temp1, temp2;
  rtx res;
  optab this_add_optab = add_optab;
  optab this_sub_optab = sub_optab;
  optab this_neg_optab = neg_optab;
  optab this_mul_optab = smul_optab;
	      
  if (binoptab == sdivv_optab)
    {
      this_add_optab = addv_optab;
      this_sub_optab = subv_optab;
      this_neg_optab = negv_optab;
      this_mul_optab = smulv_optab;
    }

  /* Don't fetch these from memory more than once.  */
  real0 = force_reg (submode, real0);
  real1 = force_reg (submode, real1);

  if (imag0 != 0)
    imag0 = force_reg (submode, imag0);

  imag1 = force_reg (submode, imag1);

  /* Divisor: c*c + d*d.  */
  temp1 = expand_binop (submode, this_mul_optab, real1, real1,
			NULL_RTX, unsignedp, methods);

  temp2 = expand_binop (submode, this_mul_optab, imag1, imag1,
			NULL_RTX, unsignedp, methods);

  if (temp1 == 0 || temp2 == 0)
    return 0;

  divisor = expand_binop (submode, this_add_optab, temp1, temp2,
			  NULL_RTX, unsignedp, methods);
  if (divisor == 0)
    return 0;

  if (imag0 == 0)
    {
      /* Mathematically, ((a)(c-id))/divisor.  */
      /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)).  */

      /* Calculate the dividend.  */
      real_t = expand_binop (submode, this_mul_optab, real0, real1,
			     NULL_RTX, unsignedp, methods);
		  
      imag_t = expand_binop (submode, this_mul_optab, real0, imag1,
			     NULL_RTX, unsignedp, methods);

      if (real_t == 0 || imag_t == 0)
	return 0;

      imag_t = expand_unop (submode, this_neg_optab, imag_t,
			    NULL_RTX, unsignedp);
    }
  else
    {
      /* Mathematically, ((a+ib)(c-id))/divider.  */
      /* Calculate the dividend.  */
      temp1 = expand_binop (submode, this_mul_optab, real0, real1,
			    NULL_RTX, unsignedp, methods);

      temp2 = expand_binop (submode, this_mul_optab, imag0, imag1,
			    NULL_RTX, unsignedp, methods);

      if (temp1 == 0 || temp2 == 0)
	return 0;

      real_t = expand_binop (submode, this_add_optab, temp1, temp2,
			     NULL_RTX, unsignedp, methods);
		  
      temp1 = expand_binop (submode, this_mul_optab, imag0, real1,
			    NULL_RTX, unsignedp, methods);

      temp2 = expand_binop (submode, this_mul_optab, real0, imag1,
			    NULL_RTX, unsignedp, methods);

      if (temp1 == 0 || temp2 == 0)
	return 0;

      imag_t = expand_binop (submode, this_sub_optab, temp1, temp2,
			     NULL_RTX, unsignedp, methods);

      if (real_t == 0 || imag_t == 0)
	return 0;
    }

  if (class == MODE_COMPLEX_FLOAT)
    res = expand_binop (submode, binoptab, real_t, divisor,
			realr, unsignedp, methods);
  else
    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
			 real_t, divisor, realr, unsignedp);

  if (res == 0)
    return 0;

  if (res != realr)
    emit_move_insn (realr, res);

  if (class == MODE_COMPLEX_FLOAT)
    res = expand_binop (submode, binoptab, imag_t, divisor,
			imagr, unsignedp, methods);
  else
    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
			 imag_t, divisor, imagr, unsignedp);

  if (res == 0)
    return 0;

  if (res != imagr)
    emit_move_insn (imagr, res);

  return 1;
}

/* Generate code to perform a wide-input-range-acceptable complex divide.  */

static int
expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
		      unsignedp, methods, class, binoptab)
     rtx real0, real1, imag0, imag1, realr, imagr;
     enum machine_mode submode;
     int unsignedp;
     enum optab_methods methods;
     enum mode_class class;
     optab binoptab;
{
  rtx ratio, divisor;
  rtx real_t, imag_t;
  rtx temp1, temp2, lab1, lab2;
  enum machine_mode mode;
  rtx res;
  optab this_add_optab = add_optab;
  optab this_sub_optab = sub_optab;
  optab this_neg_optab = neg_optab;
  optab this_mul_optab = smul_optab;

  if (binoptab == sdivv_optab)
    {
      this_add_optab = addv_optab;
      this_sub_optab = subv_optab;
      this_neg_optab = negv_optab;
      this_mul_optab = smulv_optab;
    }
	      
  /* Don't fetch these from memory more than once.  */
  real0 = force_reg (submode, real0);
  real1 = force_reg (submode, real1);

  if (imag0 != 0)
    imag0 = force_reg (submode, imag0);

  imag1 = force_reg (submode, imag1);

  /* XXX What's an "unsigned" complex number?  */
  if (unsignedp)
    {
      temp1 = real1;
      temp2 = imag1;
    }
  else
    {
      temp1 = expand_abs (submode, real1, NULL_RTX, unsignedp, 1);
      temp2 = expand_abs (submode, imag1, NULL_RTX, unsignedp, 1);
    }

  if (temp1 == 0 || temp2 == 0)
    return 0;

  mode = GET_MODE (temp1);
  lab1 = gen_label_rtx ();
  emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX,
			   mode, unsignedp, lab1);

  /* |c| >= |d|; use ratio d/c to scale dividend and divisor.  */

  if (class == MODE_COMPLEX_FLOAT)
    ratio = expand_binop (submode, binoptab, imag1, real1,
			  NULL_RTX, unsignedp, methods);
  else
    ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
			   imag1, real1, NULL_RTX, unsignedp);

  if (ratio == 0)
    return 0;

  /* Calculate divisor.  */

  temp1 = expand_binop (submode, this_mul_optab, imag1, ratio,
			NULL_RTX, unsignedp, methods);

  if (temp1 == 0)
    return 0;

  divisor = expand_binop (submode, this_add_optab, temp1, real1,
			  NULL_RTX, unsignedp, methods);

  if (divisor == 0)
    return 0;

  /* Calculate dividend.  */

  if (imag0 == 0)
    {
      real_t = real0;

      /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)).  */

      imag_t = expand_binop (submode, this_mul_optab, real0, ratio,
			     NULL_RTX, unsignedp, methods);

      if (imag_t == 0)
	return 0;

      imag_t = expand_unop (submode, this_neg_optab, imag_t,
			    NULL_RTX, unsignedp);

      if (real_t == 0 || imag_t == 0)
	return 0;
    }
  else
    {
      /* Compute (a+ib)/(c+id) as
	 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)).  */

      temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
			    NULL_RTX, unsignedp, methods);

      if (temp1 == 0)
	return 0;

      real_t = expand_binop (submode, this_add_optab, temp1, real0,
			     NULL_RTX, unsignedp, methods);

      temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
			    NULL_RTX, unsignedp, methods);

      if (temp1 == 0)
	return 0;

      imag_t = expand_binop (submode, this_sub_optab, imag0, temp1,
			     NULL_RTX, unsignedp, methods);

      if (real_t == 0 || imag_t == 0)
	return 0;
    }

  if (class == MODE_COMPLEX_FLOAT)
    res = expand_binop (submode, binoptab, real_t, divisor,
			realr, unsignedp, methods);
  else
    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
			 real_t, divisor, realr, unsignedp);

  if (res == 0)
    return 0;

  if (res != realr)
    emit_move_insn (realr, res);

  if (class == MODE_COMPLEX_FLOAT)
    res = expand_binop (submode, binoptab, imag_t, divisor,
			imagr, unsignedp, methods);
  else
    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
			 imag_t, divisor, imagr, unsignedp);

  if (res == 0)
    return 0;

  if (res != imagr)
    emit_move_insn (imagr, res);

  lab2 = gen_label_rtx ();
  emit_jump_insn (gen_jump (lab2));
  emit_barrier ();

  emit_label (lab1);

  /* |d| > |c|; use ratio c/d to scale dividend and divisor.  */

  if (class == MODE_COMPLEX_FLOAT)
    ratio = expand_binop (submode, binoptab, real1, imag1,
			  NULL_RTX, unsignedp, methods);
  else
    ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
			   real1, imag1, NULL_RTX, unsignedp);

  if (ratio == 0)
    return 0;

  /* Calculate divisor.  */

  temp1 = expand_binop (submode, this_mul_optab, real1, ratio,
			NULL_RTX, unsignedp, methods);

  if (temp1 == 0)
    return 0;

  divisor = expand_binop (submode, this_add_optab, temp1, imag1,
			  NULL_RTX, unsignedp, methods);

  if (divisor == 0)
    return 0;

  /* Calculate dividend.  */

  if (imag0 == 0)
    {
      /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d).  */

      real_t = expand_binop (submode, this_mul_optab, real0, ratio,
			     NULL_RTX, unsignedp, methods);

      imag_t = expand_unop (submode, this_neg_optab, real0,
			    NULL_RTX, unsignedp);

      if (real_t == 0 || imag_t == 0)
	return 0;
    }
  else
    {
      /* Compute (a+ib)/(c+id) as
	 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d).  */

      temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
			    NULL_RTX, unsignedp, methods);

      if (temp1 == 0)
	return 0;

      real_t = expand_binop (submode, this_add_optab, temp1, imag0,
			     NULL_RTX, unsignedp, methods);

      temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
			    NULL_RTX, unsignedp, methods);

      if (temp1 == 0)
	return 0;

      imag_t = expand_binop (submode, this_sub_optab, temp1, real0,
			     NULL_RTX, unsignedp, methods);

      if (real_t == 0 || imag_t == 0)
	return 0;
    }

  if (class == MODE_COMPLEX_FLOAT)
    res = expand_binop (submode, binoptab, real_t, divisor,
			realr, unsignedp, methods);
  else
    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
			 real_t, divisor, realr, unsignedp);

  if (res == 0)
    return 0;

  if (res != realr)
    emit_move_insn (realr, res);

  if (class == MODE_COMPLEX_FLOAT)
    res = expand_binop (submode, binoptab, imag_t, divisor,
			imagr, unsignedp, methods);
  else
    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
			 imag_t, divisor, imagr, unsignedp);

  if (res == 0)
    return 0;

  if (res != imagr)
    emit_move_insn (imagr, res);

  emit_label (lab2);

  return 1;
}

/* Wrapper around expand_binop which takes an rtx code to specify
   the operation to perform, not an optab pointer.  All other
   arguments are the same.  */
rtx
expand_simple_binop (mode, code, op0, op1, target, unsignedp, methods)
     enum machine_mode mode;
     enum rtx_code code;
     rtx op0, op1;
     rtx target;
     int unsignedp;
     enum optab_methods methods;
{
  optab binop = code_to_optab[(int) code];
  if (binop == 0)
    abort ();

  return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
}

/* Generate code to perform an operation specified by BINOPTAB
   on operands OP0 and OP1, with result having machine-mode MODE.

   UNSIGNEDP is for the case where we have to widen the operands
   to perform the operation.  It says to use zero-extension.

   If TARGET is nonzero, the value
   is generated there, if it is convenient to do so.
   In all cases an rtx is returned for the locus of the value;
   this may or may not be TARGET.  */

rtx
expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
     enum machine_mode mode;
     optab binoptab;
     rtx op0, op1;
     rtx target;
     int unsignedp;
     enum optab_methods methods;
{
  enum optab_methods next_methods
    = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
       ? OPTAB_WIDEN : methods);
  enum mode_class class;
  enum machine_mode wider_mode;
  rtx temp;
  int commutative_op = 0;
  int shift_op = (binoptab->code == ASHIFT
		  || binoptab->code == ASHIFTRT
		  || binoptab->code == LSHIFTRT
		  || binoptab->code == ROTATE
		  || binoptab->code == ROTATERT);
  rtx entry_last = get_last_insn ();
  rtx last;

  class = GET_MODE_CLASS (mode);

  op0 = protect_from_queue (op0, 0);
  op1 = protect_from_queue (op1, 0);
  if (target)
    target = protect_from_queue (target, 1);

  if (flag_force_mem)
    {
      op0 = force_not_mem (op0);
      op1 = force_not_mem (op1);
    }

  /* If subtracting an integer constant, convert this into an addition of
     the negated constant.  */

  if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
    {
      op1 = negate_rtx (mode, op1);
      binoptab = add_optab;
    }

  /* If we are inside an appropriately-short loop and one operand is an
     expensive constant, force it into a register.  */
  if (CONSTANT_P (op0) && preserve_subexpressions_p ()
      && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
    op0 = force_reg (mode, op0);

  if (CONSTANT_P (op1) && preserve_subexpressions_p ()
      && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
    op1 = force_reg (mode, op1);

  /* Record where to delete back to if we backtrack.  */
  last = get_last_insn ();

  /* If operation is commutative,
     try to make the first operand a register.
     Even better, try to make it the same as the target.
     Also try to make the last operand a constant.  */
  if (GET_RTX_CLASS (binoptab->code) == 'c'
      || binoptab == smul_widen_optab
      || binoptab == umul_widen_optab
      || binoptab == smul_highpart_optab
      || binoptab == umul_highpart_optab)
    {
      commutative_op = 1;

      if (((target == 0 || GET_CODE (target) == REG)
	   ? ((GET_CODE (op1) == REG
	       && GET_CODE (op0) != REG)
	      || target == op1)
	   : rtx_equal_p (op1, target))
	  || GET_CODE (op0) == CONST_INT)
	{
	  temp = op1;
	  op1 = op0;
	  op0 = temp;
	}
    }

  /* If we can do it with a three-operand insn, do so.  */

  if (methods != OPTAB_MUST_WIDEN
      && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
    {
      int icode = (int) binoptab->handlers[(int) mode].insn_code;
      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
      enum machine_mode mode1 = insn_data[icode].operand[2].mode;
      rtx pat;
      rtx xop0 = op0, xop1 = op1;

      if (target)
	temp = target;
      else
	temp = gen_reg_rtx (mode);

      /* If it is a commutative operator and the modes would match
	 if we would swap the operands, we can save the conversions.  */
      if (commutative_op)
	{
	  if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
	      && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
	    {
	      rtx tmp;

	      tmp = op0; op0 = op1; op1 = tmp;
	      tmp = xop0; xop0 = xop1; xop1 = tmp;
	    }
	}

      /* In case the insn wants input operands in modes different from
	 those of the actual operands, convert the operands.  It would
	 seem that we don't need to convert CONST_INTs, but we do, so
	 that they're properly zero-extended, sign-extended or truncated
	 for their mode.  */

      if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
	xop0 = convert_modes (mode0,
			      GET_MODE (op0) != VOIDmode
			      ? GET_MODE (op0)
			      : mode,
			      xop0, unsignedp);

      if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
	xop1 = convert_modes (mode1,
			      GET_MODE (op1) != VOIDmode
			      ? GET_MODE (op1)
			      : mode,
			      xop1, unsignedp);

      /* Now, if insn's predicates don't allow our operands, put them into
	 pseudo regs.  */

      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)
	  && mode0 != VOIDmode)
	xop0 = copy_to_mode_reg (mode0, xop0);

      if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
	  && mode1 != VOIDmode)
	xop1 = copy_to_mode_reg (mode1, xop1);

      if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
	temp = gen_reg_rtx (mode);

      pat = GEN_FCN (icode) (temp, xop0, xop1);
      if (pat)
	{
	  /* If PAT is composed of more than one insn, try to add an appropriate
	     REG_EQUAL note to it.  If we can't because TEMP conflicts with an
	     operand, call ourselves again, this time without a target.  */
	  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
	      && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
	    {
	      delete_insns_since (last);
	      return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
				   unsignedp, methods);
	    }

	  emit_insn (pat);
	  return temp;
	}
      else
	delete_insns_since (last);
    }

  /* If this is a multiply, see if we can do a widening operation that
     takes operands of this mode and makes a wider mode.  */

  if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
      && (((unsignedp ? umul_widen_optab : smul_widen_optab)
	   ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
	  != CODE_FOR_nothing))
    {
      temp = expand_binop (GET_MODE_WIDER_MODE (mode),
			   unsignedp ? umul_widen_optab : smul_widen_optab,
			   op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);

      if (temp != 0)
	{
	  if (GET_MODE_CLASS (mode) == MODE_INT)
	    return gen_lowpart (mode, temp);
	  else
	    return convert_to_mode (mode, temp, unsignedp);
	}
    }

  /* Look for a wider mode of the same class for which we think we
     can open-code the operation.  Check for a widening multiply at the
     wider mode as well.  */

  if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
      && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
    for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
	 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
      {
	if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
	    || (binoptab == smul_optab
		&& GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
		&& (((unsignedp ? umul_widen_optab : smul_widen_optab)
		     ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
		    != CODE_FOR_nothing)))
	  {
	    rtx xop0 = op0, xop1 = op1;
	    int no_extend = 0;

	    /* For certain integer operations, we need not actually extend
	       the narrow operands, as long as we will truncate
	       the results to the same narrowness.  */

	    if ((binoptab == ior_optab || binoptab == and_optab
		 || binoptab == xor_optab
		 || binoptab == add_optab || binoptab == sub_optab
		 || binoptab == smul_optab || binoptab == ashl_optab)
		&& class == MODE_INT)
	      no_extend = 1;

	    xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);

	    /* The second operand of a shift must always be extended.  */
	    xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
				  no_extend && binoptab != ashl_optab);

	    temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
				 unsignedp, OPTAB_DIRECT);
	    if (temp)
	      {
		if (class != MODE_INT)
		  {
		    if (target == 0)
		      target = gen_reg_rtx (mode);
		    convert_move (target, temp, 0);
		    return target;
		  }
		else
		  return gen_lowpart (mode, temp);
	      }
	    else
	      delete_insns_since (last);
	  }
      }

  /* These can be done a word at a time.  */
  if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
      && class == MODE_INT
      && GET_MODE_SIZE (mode) > UNITS_PER_WORD
      && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
    {
      int i;
      rtx insns;
      rtx equiv_value;

      /* If TARGET is the same as one of the operands, the REG_EQUAL note
	 won't be accurate, so use a new target.  */
      if (target == 0 || target == op0 || target == op1)
	target = gen_reg_rtx (mode);

      start_sequence ();

      /* Do the actual arithmetic.  */
      for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
	{
	  rtx target_piece = operand_subword (target, i, 1, mode);
	  rtx x = expand_binop (word_mode, binoptab,
				operand_subword_force (op0, i, mode),
				operand_subword_force (op1, i, mode),
				target_piece, unsignedp, next_methods);

	  if (x == 0)
	    break;

	  if (target_piece != x)
	    emit_move_insn (target_piece, x);
	}

      insns = get_insns ();
      end_sequence ();

      if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
	{
	  if (binoptab->code != UNKNOWN)
	    equiv_value
	      = gen_rtx_fmt_ee (binoptab->code, mode,
				copy_rtx (op0), copy_rtx (op1));
	  else
	    equiv_value = 0;

	  emit_no_conflict_block (insns, target, op0, op1, equiv_value);
	  return target;
	}
    }

  /* Synthesize double word shifts from single word shifts.  */
  if ((binoptab == lshr_optab || binoptab == ashl_optab
       || binoptab == ashr_optab)
      && class == MODE_INT
      && GET_CODE (op1) == CONST_INT
      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
      && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
      && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
      && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
    {
      rtx insns, inter, equiv_value;
      rtx into_target, outof_target;
      rtx into_input, outof_input;
      int shift_count, left_shift, outof_word;

      /* If TARGET is the same as one of the operands, the REG_EQUAL note
	 won't be accurate, so use a new target.  */
      if (target == 0 || target == op0 || target == op1)
	target = gen_reg_rtx (mode);

      start_sequence ();

      shift_count = INTVAL (op1);

      /* OUTOF_* is the word we are shifting bits away from, and
	 INTO_* is the word that we are shifting bits towards, thus
	 they differ depending on the direction of the shift and
	 WORDS_BIG_ENDIAN.  */

      left_shift = binoptab == ashl_optab;
      outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;

      outof_target = operand_subword (target, outof_word, 1, mode);
      into_target = operand_subword (target, 1 - outof_word, 1, mode);

      outof_input = operand_subword_force (op0, outof_word, mode);
      into_input = operand_subword_force (op0, 1 - outof_word, mode);

      if (shift_count >= BITS_PER_WORD)
	{
	  inter = expand_binop (word_mode, binoptab,
			       outof_input,
			       GEN_INT (shift_count - BITS_PER_WORD),
			       into_target, unsignedp, next_methods);

	  if (inter != 0 && inter != into_target)
	    emit_move_insn (into_target, inter);

	  /* For a signed right shift, we must fill the word we are shifting
	     out of with copies of the sign bit.  Otherwise it is zeroed.  */
	  if (inter != 0 && binoptab != ashr_optab)
	    inter = CONST0_RTX (word_mode);
	  else if (inter != 0)
	    inter = expand_binop (word_mode, binoptab,
				  outof_input,
				  GEN_INT (BITS_PER_WORD - 1),
				  outof_target, unsignedp, next_methods);

	  if (inter != 0 && inter != outof_target)
	    emit_move_insn (outof_target, inter);
	}
      else
	{
	  rtx carries;
	  optab reverse_unsigned_shift, unsigned_shift;

	  /* For a shift of less then BITS_PER_WORD, to compute the carry,
	     we must do a logical shift in the opposite direction of the
	     desired shift.  */

	  reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);

	  /* For a shift of less than BITS_PER_WORD, to compute the word
	     shifted towards, we need to unsigned shift the orig value of
	     that word.  */

	  unsigned_shift = (left_shift ? ashl_optab : lshr_optab);

	  carries = expand_binop (word_mode, reverse_unsigned_shift,
				  outof_input,
				  GEN_INT (BITS_PER_WORD - shift_count),
				  0, unsignedp, next_methods);

	  if (carries == 0)
	    inter = 0;
	  else
	    inter = expand_binop (word_mode, unsigned_shift, into_input,
				  op1, 0, unsignedp, next_methods);

	  if (inter != 0)
	    inter = expand_binop (word_mode, ior_optab, carries, inter,
				  into_target, unsignedp, next_methods);

	  if (inter != 0 && inter != into_target)
	    emit_move_insn (into_target, inter);

	  if (inter != 0)
	    inter = expand_binop (word_mode, binoptab, outof_input,
				  op1, outof_target, unsignedp, next_methods);
	  
	  if (inter != 0 && inter != outof_target)
	    emit_move_insn (outof_target, inter);
	}

      insns = get_insns ();
      end_sequence ();

      if (inter != 0)
	{
	  if (binoptab->code != UNKNOWN)
	    equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
	  else
	    equiv_value = 0;

	  emit_no_conflict_block (insns, target, op0, op1, equiv_value);
	  return target;
	}
    }

  /* Synthesize double word rotates from single word shifts.  */
  if ((binoptab == rotl_optab || binoptab == rotr_optab)
      && class == MODE_INT
      && GET_CODE (op1) == CONST_INT
      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
      && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
      && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
    {
      rtx insns, equiv_value;
      rtx into_target, outof_target;
      rtx into_input, outof_input;
      rtx inter;
      int shift_count, left_shift, outof_word;

      /* If TARGET is the same as one of the operands, the REG_EQUAL note
	 won't be accurate, so use a new target.  */
      if (target == 0 || target == op0 || target == op1)
	target = gen_reg_rtx (mode);

      start_sequence ();

      shift_count = INTVAL (op1);

      /* OUTOF_* is the word we are shifting bits away from, and
	 INTO_* is the word that we are shifting bits towards, thus
	 they differ depending on the direction of the shift and
	 WORDS_BIG_ENDIAN.  */

      left_shift = (binoptab == rotl_optab);
      outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;

      outof_target = operand_subword (target, outof_word, 1, mode);
      into_target = operand_subword (target, 1 - outof_word, 1, mode);

      outof_input = operand_subword_force (op0, outof_word, mode);
      into_input = operand_subword_force (op0, 1 - outof_word, mode);

      if (shift_count == BITS_PER_WORD)
	{
	  /* This is just a word swap.  */
	  emit_move_insn (outof_target, into_input);
	  emit_move_insn (into_target, outof_input);
	  inter = const0_rtx;
	}
      else
	{
	  rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
	  rtx first_shift_count, second_shift_count;
	  optab reverse_unsigned_shift, unsigned_shift;

	  reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
				    ? lshr_optab : ashl_optab);

	  unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
			    ? ashl_optab : lshr_optab);

	  if (shift_count > BITS_PER_WORD)
	    {
	      first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
	      second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
	    }
	  else
	    {
	      first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
	      second_shift_count = GEN_INT (shift_count);
	    }

	  into_temp1 = expand_binop (word_mode, unsigned_shift,
				     outof_input, first_shift_count,
				     NULL_RTX, unsignedp, next_methods);
	  into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
				     into_input, second_shift_count,
				     NULL_RTX, unsignedp, next_methods);

	  if (into_temp1 != 0 && into_temp2 != 0)
	    inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
				  into_target, unsignedp, next_methods);
	  else
	    inter = 0;

	  if (inter != 0 && inter != into_target)
	    emit_move_insn (into_target, inter);

	  outof_temp1 = expand_binop (word_mode, unsigned_shift,
				      into_input, first_shift_count,
				      NULL_RTX, unsignedp, next_methods);
	  outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
				      outof_input, second_shift_count,
				      NULL_RTX, unsignedp, next_methods);

	  if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
	    inter = expand_binop (word_mode, ior_optab,
				  outof_temp1, outof_temp2,
				  outof_target, unsignedp, next_methods);

	  if (inter != 0 && inter != outof_target)
	    emit_move_insn (outof_target, inter);
	}

      insns = get_insns ();
      end_sequence ();

      if (inter != 0)
	{
	  if (binoptab->code != UNKNOWN)
	    equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
	  else
	    equiv_value = 0;

	  /* We can't make this a no conflict block if this is a word swap,
	     because the word swap case fails if the input and output values
	     are in the same register.  */
	  if (shift_count != BITS_PER_WORD)
	    emit_no_conflict_block (insns, target, op0, op1, equiv_value);
	  else
	    emit_insn (insns);


	  return target;
	}
    }

  /* These can be done a word at a time by propagating carries.  */
  if ((binoptab == add_optab || binoptab == sub_optab)
      && class == MODE_INT
      && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
      && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
    {
      unsigned int i;
      optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
      const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
      rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
      rtx xop0, xop1, xtarget;

      /* We can handle either a 1 or -1 value for the carry.  If STORE_FLAG
	 value is one of those, use it.  Otherwise, use 1 since it is the
	 one easiest to get.  */
#if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
      int normalizep = STORE_FLAG_VALUE;
#else
      int normalizep = 1;
#endif

      /* Prepare the operands.  */
      xop0 = force_reg (mode, op0);
      xop1 = force_reg (mode, op1);

      xtarget = gen_reg_rtx (mode);

      if (target == 0 || GET_CODE (target) != REG)
	target = xtarget;

      /* Indicate for flow that the entire target reg is being set.  */
      if (GET_CODE (target) == REG)
	emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));

      /* Do the actual arithmetic.  */
      for (i = 0; i < nwords; i++)
	{
	  int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
	  rtx target_piece = operand_subword (xtarget, index, 1, mode);
	  rtx op0_piece = operand_subword_force (xop0, index, mode);
	  rtx op1_piece = operand_subword_force (xop1, index, mode);
	  rtx x;

	  /* Main add/subtract of the input operands.  */
	  x = expand_binop (word_mode, binoptab,
			    op0_piece, op1_piece,
			    target_piece, unsignedp, next_methods);
	  if (x == 0)
	    break;

	  if (i + 1 < nwords)
	    {
	      /* Store carry from main add/subtract.  */
	      carry_out = gen_reg_rtx (word_mode);
	      carry_out = emit_store_flag_force (carry_out,
						 (binoptab == add_optab
						  ? LT : GT),
						 x, op0_piece,
						 word_mode, 1, normalizep);
	    }

	  if (i > 0)
	    {
	      rtx newx;
	      
	      /* Add/subtract previous carry to main result.  */
	      newx = expand_binop (word_mode,
				   normalizep == 1 ? binoptab : otheroptab,
				   x, carry_in,
				   NULL_RTX, 1, next_methods);

	      if (i + 1 < nwords)
		{
		  /* Get out carry from adding/subtracting carry in.  */
		  rtx carry_tmp = gen_reg_rtx (word_mode);
		  carry_tmp = emit_store_flag_force (carry_tmp,
						     (binoptab == add_optab
						      ? LT : GT),
						     newx, x,
						     word_mode, 1, normalizep);

		  /* Logical-ior the two poss. carry together.  */
		  carry_out = expand_binop (word_mode, ior_optab,
					    carry_out, carry_tmp,
					    carry_out, 0, next_methods);
		  if (carry_out == 0)
		    break;
		}
	      emit_move_insn (target_piece, newx);
	    }

	  carry_in = carry_out;
	}	

      if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
	{
	  if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
	    {
	      rtx temp = emit_move_insn (target, xtarget);

	      set_unique_reg_note (temp,
	      			   REG_EQUAL,
				   gen_rtx_fmt_ee (binoptab->code, mode,
						   copy_rtx (xop0),
						   copy_rtx (xop1)));
	    }
	  else
	    target = xtarget;

	  return target;
	}

      else
	delete_insns_since (last);
    }

  /* If we want to multiply two two-word values and have normal and widening
     multiplies of single-word values, we can do this with three smaller
     multiplications.  Note that we do not make a REG_NO_CONFLICT block here
     because we are not operating on one word at a time. 

     The multiplication proceeds as follows:
			         _______________________
			        [__op0_high_|__op0_low__]
			         _______________________
        *			[__op1_high_|__op1_low__]
        _______________________________________________
			         _______________________
    (1)				[__op0_low__*__op1_low__]
		     _______________________
    (2a)	    [__op0_low__*__op1_high_]
		     _______________________
    (2b)	    [__op0_high_*__op1_low__]
         _______________________
    (3) [__op0_high_*__op1_high_]


    This gives a 4-word result.  Since we are only interested in the
    lower 2 words, partial result (3) and the upper words of (2a) and
    (2b) don't need to be calculated.  Hence (2a) and (2b) can be
    calculated using non-widening multiplication.

    (1), however, needs to be calculated with an unsigned widening
    multiplication.  If this operation is not directly supported we
    try using a signed widening multiplication and adjust the result.
    This adjustment works as follows:

      If both operands are positive then no adjustment is needed.

      If the operands have different signs, for example op0_low < 0 and
      op1_low >= 0, the instruction treats the most significant bit of
      op0_low as a sign bit instead of a bit with significance
      2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
      with 2**BITS_PER_WORD - op0_low, and two's complements the
      result.  Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
      the result.

      Similarly, if both operands are negative, we need to add
      (op0_low + op1_low) * 2**BITS_PER_WORD.

      We use a trick to adjust quickly.  We logically shift op0_low right
      (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
      op0_high (op1_high) before it is used to calculate 2b (2a).  If no
      logical shift exists, we do an arithmetic right shift and subtract
      the 0 or -1.  */

  if (binoptab == smul_optab
      && class == MODE_INT
      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
      && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
      && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
      && ((umul_widen_optab->handlers[(int) mode].insn_code
	   != CODE_FOR_nothing)
	  || (smul_widen_optab->handlers[(int) mode].insn_code
	      != CODE_FOR_nothing)))
    {
      int low = (WORDS_BIG_ENDIAN ? 1 : 0);
      int high = (WORDS_BIG_ENDIAN ? 0 : 1);
      rtx op0_high = operand_subword_force (op0, high, mode);
      rtx op0_low = operand_subword_force (op0, low, mode);
      rtx op1_high = operand_subword_force (op1, high, mode);
      rtx op1_low = operand_subword_force (op1, low, mode);
      rtx product = 0;
      rtx op0_xhigh = NULL_RTX;
      rtx op1_xhigh = NULL_RTX;

      /* If the target is the same as one of the inputs, don't use it.  This
	 prevents problems with the REG_EQUAL note.  */
      if (target == op0 || target == op1
	  || (target != 0 && GET_CODE (target) != REG))
	target = 0;

      /* Multiply the two lower words to get a double-word product.
	 If unsigned widening multiplication is available, use that;
	 otherwise use the signed form and compensate.  */

      if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
	{
	  product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
				  target, 1, OPTAB_DIRECT);

	  /* If we didn't succeed, delete everything we did so far.  */
	  if (product == 0)
	    delete_insns_since (last);
	  else
	    op0_xhigh = op0_high, op1_xhigh = op1_high;
	}

      if (product == 0
	  && smul_widen_optab->handlers[(int) mode].insn_code
	       != CODE_FOR_nothing)
	{
	  rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
	  product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
				  target, 1, OPTAB_DIRECT);
	  op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
				    NULL_RTX, 1, next_methods);
	  if (op0_xhigh)
	    op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
				      op0_xhigh, op0_xhigh, 0, next_methods);
	  else
	    {
	      op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
					NULL_RTX, 0, next_methods);
	      if (op0_xhigh)
		op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
					  op0_xhigh, op0_xhigh, 0,
					  next_methods);
	    }

	  op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
				    NULL_RTX, 1, next_methods);
	  if (op1_xhigh)
	    op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
				      op1_xhigh, op1_xhigh, 0, next_methods);
	  else
	    {
	      op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
					NULL_RTX, 0, next_methods);
	      if (op1_xhigh)
		op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
					  op1_xhigh, op1_xhigh, 0,
					  next_methods);
	    }
	}

      /* If we have been able to directly compute the product of the
	 low-order words of the operands and perform any required adjustments
	 of the operands, we proceed by trying two more multiplications
	 and then computing the appropriate sum.

	 We have checked above that the required addition is provided.
	 Full-word addition will normally always succeed, especially if
	 it is provided at all, so we don't worry about its failure.  The
	 multiplication may well fail, however, so we do handle that.  */

      if (product && op0_xhigh && op1_xhigh)
	{
	  rtx product_high = operand_subword (product, high, 1, mode);
	  rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
				   NULL_RTX, 0, OPTAB_DIRECT);

	  if (!REG_P (product_high))
	    product_high = force_reg (word_mode, product_high);

	  if (temp != 0)
	    temp = expand_binop (word_mode, add_optab, temp, product_high,
				 product_high, 0, next_methods);

	  if (temp != 0 && temp != product_high)
	    emit_move_insn (product_high, temp);

	  if (temp != 0)
	    temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh, 
				 NULL_RTX, 0, OPTAB_DIRECT);

	  if (temp != 0)
	    temp = expand_binop (word_mode, add_optab, temp,
				 product_high, product_high,
				 0, next_methods);

	  if (temp != 0 && temp != product_high)
	    emit_move_insn (product_high, temp);

	  emit_move_insn (operand_subword (product, high, 1, mode), product_high);

	  if (temp != 0)
	    {
	      if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
		{
		  temp = emit_move_insn (product, product);
		  set_unique_reg_note (temp,
		  		       REG_EQUAL,
				       gen_rtx_fmt_ee (MULT, mode,
						       copy_rtx (op0),
						       copy_rtx (op1)));
		}

	      return product;
	    }
	}

      /* If we get here, we couldn't do it for some reason even though we
	 originally thought we could.  Delete anything we've emitted in
	 trying to do it.  */

      delete_insns_since (last);
    }

  /* Open-code the vector operations if we have no hardware support
     for them.  */
  if (class == MODE_VECTOR_INT || class == MODE_VECTOR_FLOAT)
    return expand_vector_binop (mode, binoptab, op0, op1, target,
				unsignedp, methods);

  /* We need to open-code the complex type operations: '+, -, * and /' */

  /* At this point we allow operations between two similar complex
     numbers, and also if one of the operands is not a complex number
     but rather of MODE_FLOAT or MODE_INT. However, the caller
     must make sure that the MODE of the non-complex operand matches
     the SUBMODE of the complex operand.  */

  if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
    {
      rtx real0 = 0, imag0 = 0;
      rtx real1 = 0, imag1 = 0;
      rtx realr, imagr, res;
      rtx seq;
      rtx equiv_value;
      int ok = 0;

      /* Find the correct mode for the real and imaginary parts */
      enum machine_mode submode = GET_MODE_INNER(mode);

      if (submode == BLKmode)
	abort ();

      if (! target)
	target = gen_reg_rtx (mode);

      start_sequence ();

      realr = gen_realpart (submode, target);
      imagr = gen_imagpart (submode, target);

      if (GET_MODE (op0) == mode)
	{
	  real0 = gen_realpart (submode, op0);
	  imag0 = gen_imagpart (submode, op0);
	}
      else
	real0 = op0;

      if (GET_MODE (op1) == mode)
	{
	  real1 = gen_realpart (submode, op1);
	  imag1 = gen_imagpart (submode, op1);
	}
      else
	real1 = op1;

      if (real0 == 0 || real1 == 0 || ! (imag0 != 0 || imag1 != 0))
	abort ();

      switch (binoptab->code)
	{
	case PLUS:
	  /* (a+ib) + (c+id) = (a+c) + i(b+d) */
	case MINUS:
	  /* (a+ib) - (c+id) = (a-c) + i(b-d) */
	  res = expand_binop (submode, binoptab, real0, real1,
			      realr, unsignedp, methods);

	  if (res == 0)
	    break;
	  else if (res != realr)
	    emit_move_insn (realr, res);

	  if (imag0 != 0 && imag1 != 0)
	    res = expand_binop (submode, binoptab, imag0, imag1,
				imagr, unsignedp, methods);
	  else if (imag0 != 0)
	    res = imag0;
	  else if (binoptab->code == MINUS)
            res = expand_unop (submode,
                                binoptab == subv_optab ? negv_optab : neg_optab,
                                imag1, imagr, unsignedp);
	  else
	    res = imag1;

	  if (res == 0)
	    break;
	  else if (res != imagr)
	    emit_move_insn (imagr, res);

	  ok = 1;
	  break;

	case MULT:
	  /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */

	  if (imag0 != 0 && imag1 != 0)
	    {
	      rtx temp1, temp2;

	      /* Don't fetch these from memory more than once.  */
	      real0 = force_reg (submode, real0);
	      real1 = force_reg (submode, real1);
	      imag0 = force_reg (submode, imag0);
	      imag1 = force_reg (submode, imag1);

	      temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
				    unsignedp, methods);

	      temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
				    unsignedp, methods);

	      if (temp1 == 0 || temp2 == 0)
		break;

	      res = (expand_binop
                     (submode,
                      binoptab == smulv_optab ? subv_optab : sub_optab,
                      temp1, temp2, realr, unsignedp, methods));

	      if (res == 0)
		break;
	      else if (res != realr)
		emit_move_insn (realr, res);

	      temp1 = expand_binop (submode, binoptab, real0, imag1,
				    NULL_RTX, unsignedp, methods);

	      temp2 = expand_binop (submode, binoptab, real1, imag0,
				    NULL_RTX, unsignedp, methods);

	      if (temp1 == 0 || temp2 == 0)
		break;

	      res = (expand_binop
                     (submode,
                      binoptab == smulv_optab ? addv_optab : add_optab,
                      temp1, temp2, imagr, unsignedp, methods));

	      if (res == 0)
		break;
	      else if (res != imagr)
		emit_move_insn (imagr, res);

	      ok = 1;
	    }
	  else
	    {
	      /* Don't fetch these from memory more than once.  */
	      real0 = force_reg (submode, real0);
	      real1 = force_reg (submode, real1);

	      res = expand_binop (submode, binoptab, real0, real1,
				  realr, unsignedp, methods);
	      if (res == 0)
		break;
	      else if (res != realr)
		emit_move_insn (realr, res);

	      if (imag0 != 0)
		res = expand_binop (submode, binoptab,
				    real1, imag0, imagr, unsignedp, methods);
	      else
		res = expand_binop (submode, binoptab,
				    real0, imag1, imagr, unsignedp, methods);

	      if (res == 0)
		break;
	      else if (res != imagr)
		emit_move_insn (imagr, res);

	      ok = 1;
	    }
	  break;

	case DIV:
	  /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
	  
	  if (imag1 == 0)
	    {
	      /* (a+ib) / (c+i0) = (a/c) + i(b/c) */

	      /* Don't fetch these from memory more than once.  */
	      real1 = force_reg (submode, real1);

	      /* Simply divide the real and imaginary parts by `c' */
	      if (class == MODE_COMPLEX_FLOAT)
		res = expand_binop (submode, binoptab, real0, real1,
				    realr, unsignedp, methods);
	      else
		res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
				     real0, real1, realr, unsignedp);

	      if (res == 0)
		break;
	      else if (res != realr)
		emit_move_insn (realr, res);

	      if (class == MODE_COMPLEX_FLOAT)
		res = expand_binop (submode, binoptab, imag0, real1,
				    imagr, unsignedp, methods);
	      else
		res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
				     imag0, real1, imagr, unsignedp);

	      if (res == 0)
		break;
	      else if (res != imagr)
		emit_move_insn (imagr, res);

	      ok = 1;
	    }
	  else
	    {
	      switch (flag_complex_divide_method)
		{
		case 0:
		  ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
						 realr, imagr, submode,
						 unsignedp, methods,
						 class, binoptab);
		  break;

		case 1:
		  ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
					     realr, imagr, submode,
					     unsignedp, methods,
					     class, binoptab);
		  break;

		default:
		  abort ();
		}
	    }
	  break;
	  
	default:
	  abort ();
	}

      seq = get_insns ();
      end_sequence ();

      if (ok)
	{
	  if (binoptab->code != UNKNOWN)
	    equiv_value
	      = gen_rtx_fmt_ee (binoptab->code, mode,
				copy_rtx (op0), copy_rtx (op1));
	  else
	    equiv_value = 0;
	  
	  emit_no_conflict_block (seq, target, op0, op1, equiv_value);
      
	  return target;
	}
    }

  /* It can't be open-coded in this mode.
     Use a library call if one is available and caller says that's ok.  */

  if (binoptab->handlers[(int) mode].libfunc
      && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
    {
      rtx insns;
      rtx op1x = op1;
      enum machine_mode op1_mode = mode;
      rtx value;

      start_sequence ();

      if (shift_op)
	{
	  op1_mode = word_mode;
	  /* Specify unsigned here,
	     since negative shift counts are meaningless.  */
	  op1x = convert_to_mode (word_mode, op1, 1);
	}

      if (GET_MODE (op0) != VOIDmode
	  && GET_MODE (op0) != mode)
	op0 = convert_to_mode (mode, op0, unsignedp);

      /* Pass 1 for NO_QUEUE so we don't lose any increments
	 if the libcall is cse'd or moved.  */
      value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
				       NULL_RTX, LCT_CONST, mode, 2,
				       op0, mode, op1x, op1_mode);

      insns = get_insns ();
      end_sequence ();

      target = gen_reg_rtx (mode);
      emit_libcall_block (insns, target, value,
			  gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));

      return target;
    }

  delete_insns_since (last);

  /* It can't be done in this mode.  Can we do it in a wider mode?  */

  if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
	 || methods == OPTAB_MUST_WIDEN))
    {
      /* Caller says, don't even try.  */
      delete_insns_since (entry_last);
      return 0;
    }

  /* Compute the value of METHODS to pass to recursive calls.
     Don't allow widening to be tried recursively.  */

  methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);

  /* Look for a wider mode of the same class for which it appears we can do
     the operation.  */

  if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
    {
      for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
	{
	  if ((binoptab->handlers[(int) wider_mode].insn_code
	       != CODE_FOR_nothing)
	      || (methods == OPTAB_LIB
		  && binoptab->handlers[(int) wider_mode].libfunc))
	    {
	      rtx xop0 = op0, xop1 = op1;
	      int no_extend = 0;

	      /* For certain integer operations, we need not actually extend
		 the narrow operands, as long as we will truncate
		 the results to the same narrowness.  */

	      if ((binoptab == ior_optab || binoptab == and_optab
		   || binoptab == xor_optab
		   || binoptab == add_optab || binoptab == sub_optab
		   || binoptab == smul_optab || binoptab == ashl_optab)
		  && class == MODE_INT)
		no_extend = 1;

	      xop0 = widen_operand (xop0, wider_mode, mode,
				    unsignedp, no_extend);

	      /* The second operand of a shift must always be extended.  */
	      xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
				    no_extend && binoptab != ashl_optab);

	      temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
				   unsignedp, methods);
	      if (temp)
		{
		  if (class != MODE_INT)
		    {
		      if (target == 0)
			target = gen_reg_rtx (mode);
		      convert_move (target, temp, 0);
		      return target;
		    }
		  else
		    return gen_lowpart (mode, temp);
		}
	      else
		delete_insns_since (last);
	    }
	}
    }

  delete_insns_since (entry_last);
  return 0;
}

/* Like expand_binop, but for open-coding vectors binops.  */

static rtx
expand_vector_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
     enum machine_mode mode;
     optab binoptab;
     rtx op0, op1;
     rtx target;
     int unsignedp;
     enum optab_methods methods;
{
  enum machine_mode submode, tmode;
  int size, elts, subsize, subbitsize, i;
  rtx t, a, b, res, seq;
  enum mode_class class;

  class = GET_MODE_CLASS (mode);

  size = GET_MODE_SIZE (mode);
  submode = GET_MODE_INNER (mode);

  /* Search for the widest vector mode with the same inner mode that is
     still narrower than MODE and that allows to open-code this operator.
     Note, if we find such a mode and the handler later decides it can't
     do the expansion, we'll be called recursively with the narrower mode.  */
  for (tmode = GET_CLASS_NARROWEST_MODE (class);
       GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode);
       tmode = GET_MODE_WIDER_MODE (tmode))
    {
      if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode)
	  && binoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing)
	submode = tmode;
    }

  switch (binoptab->code)
    {
    case AND:
    case IOR:
    case XOR:
      tmode = int_mode_for_mode (mode);
      if (tmode != BLKmode)
	submode = tmode;
    case PLUS:
    case MINUS:
    case MULT:
    case DIV:
      subsize = GET_MODE_SIZE (submode);
      subbitsize = GET_MODE_BITSIZE (submode);
      elts = size / subsize;

      /* If METHODS is OPTAB_DIRECT, we don't insist on the exact mode,
	 but that we operate on more than one element at a time.  */
      if (subsize == GET_MODE_UNIT_SIZE (mode) && methods == OPTAB_DIRECT)
	return 0;

      start_sequence ();

      /* Errors can leave us with a const0_rtx as operand.  */
      if (GET_MODE (op0) != mode)
	op0 = copy_to_mode_reg (mode, op0);
      if (GET_MODE (op1) != mode)
	op1 = copy_to_mode_reg (mode, op1);

      if (!target)
	target = gen_reg_rtx (mode);

      for (i = 0; i < elts; ++i)
	{
	  /* If this is part of a register, and not the first item in the
	     word, we can't store using a SUBREG - that would clobber
	     previous results.
	     And storing with a SUBREG is only possible for the least
	     significant part, hence we can't do it for big endian
	     (unless we want to permute the evaluation order.  */
	  if (GET_CODE (target) == REG
	      && (BYTES_BIG_ENDIAN
		  ? subsize < UNITS_PER_WORD
		  : ((i * subsize) % UNITS_PER_WORD) != 0))
	    t = NULL_RTX;
	  else
	    t = simplify_gen_subreg (submode, target, mode, i * subsize);
	  if (CONSTANT_P (op0))
	    a = simplify_gen_subreg (submode, op0, mode, i * subsize);
	  else
	    a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp,
				   NULL_RTX, submode, submode, size);
	  if (CONSTANT_P (op1))
	    b = simplify_gen_subreg (submode, op1, mode, i * subsize);
	  else
	    b = extract_bit_field (op1, subbitsize, i * subbitsize, unsignedp,
				   NULL_RTX, submode, submode, size);

	  if (binoptab->code == DIV)
	    {
	      if (class == MODE_VECTOR_FLOAT)
		res = expand_binop (submode, binoptab, a, b, t,
				    unsignedp, methods);
	      else
		res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
				     a, b, t, unsignedp);
	    }
	  else
	    res = expand_binop (submode, binoptab, a, b, t,
				unsignedp, methods);

	  if (res == 0)
	    break;

	  if (t)
	    emit_move_insn (t, res);
	  else
	    store_bit_field (target, subbitsize, i * subbitsize, submode, res,
			     size);
	}
      break;

    default:
      abort ();
    }

  seq = get_insns ();
  end_sequence ();
  emit_insn (seq);

  return target;
}

/* Like expand_unop but for open-coding vector unops.  */

static rtx
expand_vector_unop (mode, unoptab, op0, target, unsignedp)
     enum machine_mode mode;
     optab unoptab;
     rtx op0;
     rtx target;
     int unsignedp;
{
  enum machine_mode submode, tmode;
  int size, elts, subsize, subbitsize, i;
  rtx t, a, res, seq;

  size = GET_MODE_SIZE (mode);
  submode = GET_MODE_INNER (mode);

  /* Search for the widest vector mode with the same inner mode that is
     still narrower than MODE and that allows to open-code this operator.
     Note, if we find such a mode and the handler later decides it can't
     do the expansion, we'll be called recursively with the narrower mode.  */
  for (tmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (mode));
       GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode);
       tmode = GET_MODE_WIDER_MODE (tmode))
    {
      if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode)
	  && unoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing)
	submode = tmode;
    }
  /* If there is no negate operation, try doing a subtract from zero.  */
  if (unoptab == neg_optab && GET_MODE_CLASS (submode) == MODE_INT
      /* Avoid infinite recursion when an
	 error has left us with the wrong mode.  */
      && GET_MODE (op0) == mode)
    {    
      rtx temp;
      temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
                           target, unsignedp, OPTAB_DIRECT);
      if (temp)
	return temp;
    }

  if (unoptab == one_cmpl_optab)
    {
      tmode = int_mode_for_mode (mode);
      if (tmode != BLKmode)
	submode = tmode;
    }

  subsize = GET_MODE_SIZE (submode);
  subbitsize = GET_MODE_BITSIZE (submode);
  elts = size / subsize;

  /* Errors can leave us with a const0_rtx as operand.  */
  if (GET_MODE (op0) != mode)
    op0 = copy_to_mode_reg (mode, op0);

  if (!target)
    target = gen_reg_rtx (mode);

  start_sequence ();

  for (i = 0; i < elts; ++i)
    {
      /* If this is part of a register, and not the first item in the
	 word, we can't store using a SUBREG - that would clobber
	 previous results.
	 And storing with a SUBREG is only possible for the least
	 significant part, hence we can't do it for big endian
	 (unless we want to permute the evaluation order.  */
      if (GET_CODE (target) == REG
	  && (BYTES_BIG_ENDIAN
	      ?  subsize < UNITS_PER_WORD
	      : ((i * subsize) % UNITS_PER_WORD) != 0))
	t = NULL_RTX;
      else
	t = simplify_gen_subreg (submode, target, mode, i * subsize);
      if (CONSTANT_P (op0))
	a = simplify_gen_subreg (submode, op0, mode, i * subsize);
      else
	a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp,
			       t, submode, submode, size);

      res = expand_unop (submode, unoptab, a, t, unsignedp);

      if (t)
	emit_move_insn (t, res);
      else
	store_bit_field (target, subbitsize, i * subbitsize, submode, res,
			 size);
    }

  seq = get_insns ();
  end_sequence ();
  emit_insn (seq);

  return target;
}

/* Expand a binary operator which has both signed and unsigned forms.
   UOPTAB is the optab for unsigned operations, and SOPTAB is for
   signed operations.

   If we widen unsigned operands, we may use a signed wider operation instead
   of an unsigned wider operation, since the result would be the same.  */

rtx
sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
     enum machine_mode mode;
     optab uoptab, soptab;
     rtx op0, op1, target;
     int unsignedp;
     enum optab_methods methods;
{
  rtx temp;
  optab direct_optab = unsignedp ? uoptab : soptab;
  struct optab wide_soptab;

  /* Do it without widening, if possible.  */
  temp = expand_binop (mode, direct_optab, op0, op1, target,
		       unsignedp, OPTAB_DIRECT);
  if (temp || methods == OPTAB_DIRECT)
    return temp;

  /* Try widening to a signed int.  Make a fake signed optab that
     hides any signed insn for direct use.  */
  wide_soptab = *soptab;
  wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
  wide_soptab.handlers[(int) mode].libfunc = 0;

  temp = expand_binop (mode, &wide_soptab, op0, op1, target,
		       unsignedp, OPTAB_WIDEN);

  /* For unsigned operands, try widening to an unsigned int.  */
  if (temp == 0 && unsignedp)
    temp = expand_binop (mode, uoptab, op0, op1, target,
			 unsignedp, OPTAB_WIDEN);
  if (temp || methods == OPTAB_WIDEN)
    return temp;

  /* Use the right width lib call if that exists.  */
  temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
  if (temp || methods == OPTAB_LIB)
    return temp;

  /* Must widen and use a lib call, use either signed or unsigned.  */
  temp = expand_binop (mode, &wide_soptab, op0, op1, target,
		       unsignedp, methods);
  if (temp != 0)
    return temp;
  if (unsignedp)
    return expand_binop (mode, uoptab, op0, op1, target,
			 unsignedp, methods);
  return 0;
}

/* Generate code to perform an operation specified by BINOPTAB
   on operands OP0 and OP1, with two results to TARG1 and TARG2.
   We assume that the order of the operands for the instruction
   is TARG0, OP0, OP1, TARG1, which would fit a pattern like
   [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].

   Either TARG0 or TARG1 may be zero, but what that means is that
   the result is not actually wanted.  We will generate it into
   a dummy pseudo-reg and discard it.  They may not both be zero.

   Returns 1 if this operation can be performed; 0 if not.  */

int
expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
     optab binoptab;
     rtx op0, op1;
     rtx targ0, targ1;
     int unsignedp;
{
  enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
  enum mode_class class;
  enum machine_mode wider_mode;
  rtx entry_last = get_last_insn ();
  rtx last;

  class = GET_MODE_CLASS (mode);

  op0 = protect_from_queue (op0, 0);
  op1 = protect_from_queue (op1, 0);

  if (flag_force_mem)
    {
      op0 = force_not_mem (op0);
      op1 = force_not_mem (op1);
    }

  /* If we are inside an appropriately-short loop and one operand is an
     expensive constant, force it into a register.  */
  if (CONSTANT_P (op0) && preserve_subexpressions_p ()
      && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
    op0 = force_reg (mode, op0);

  if (CONSTANT_P (op1) && preserve_subexpressions_p ()
      && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
    op1 = force_reg (mode, op1);

  if (targ0)
    targ0 = protect_from_queue (targ0, 1);
  else
    targ0 = gen_reg_rtx (mode);
  if (targ1)
    targ1 = protect_from_queue (targ1, 1);
  else
    targ1 = gen_reg_rtx (mode);

  /* Record where to go back to if we fail.  */
  last = get_last_insn ();

  if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
    {
      int icode = (int) binoptab->handlers[(int) mode].insn_code;
      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
      enum machine_mode mode1 = insn_data[icode].operand[2].mode;
      rtx pat;
      rtx xop0 = op0, xop1 = op1;

      /* In case the insn wants input operands in modes different from
	 those of the actual operands, convert the operands.  It would
	 seem that we don't need to convert CONST_INTs, but we do, so
	 that they're properly zero-extended, sign-extended or truncated
	 for their mode.  */

      if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
	xop0 = convert_modes (mode0,
			      GET_MODE (op0) != VOIDmode
			      ? GET_MODE (op0)
			      : mode,
			      xop0, unsignedp);

      if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
	xop1 = convert_modes (mode1,
			      GET_MODE (op1) != VOIDmode
			      ? GET_MODE (op1)
			      : mode,
			      xop1, unsignedp);

      /* Now, if insn doesn't accept these operands, put them into pseudos.  */
      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
	xop0 = copy_to_mode_reg (mode0, xop0);

      if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
	xop1 = copy_to_mode_reg (mode1, xop1);

      /* We could handle this, but we should always be called with a pseudo
	 for our targets and all insns should take them as outputs.  */
      if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
	  || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
	abort ();
	
      pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
      if (pat)
	{
	  emit_insn (pat);
	  return 1;
	}
      else
	delete_insns_since (last);
    }

  /* It can't be done in this mode.  Can we do it in a wider mode?  */

  if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
    {
      for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
	{
	  if (binoptab->handlers[(int) wider_mode].insn_code
	      != CODE_FOR_nothing)
	    {
	      rtx t0 = gen_reg_rtx (wider_mode);
	      rtx t1 = gen_reg_rtx (wider_mode);
	      rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
	      rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);

	      if (expand_twoval_binop (binoptab, cop0, cop1,
				       t0, t1, unsignedp))
		{
		  convert_move (targ0, t0, unsignedp);
		  convert_move (targ1, t1, unsignedp);
		  return 1;
		}
	      else
		delete_insns_since (last);
	    }
	}
    }

  delete_insns_since (entry_last);
  return 0;
}

/* Wrapper around expand_unop which takes an rtx code to specify
   the operation to perform, not an optab pointer.  All other
   arguments are the same.  */
rtx
expand_simple_unop (mode, code, op0, target, unsignedp)
     enum machine_mode mode;
     enum rtx_code code;
     rtx op0;
     rtx target;
     int unsignedp;
{
  optab unop = code_to_optab[(int) code];
  if (unop == 0)
    abort ();

  return expand_unop (mode, unop, op0, target, unsignedp);
}

/* Generate code to perform an operation specified by UNOPTAB
   on operand OP0, with result having machine-mode MODE.

   UNSIGNEDP is for the case where we have to widen the operands
   to perform the operation.  It says to use zero-extension.

   If TARGET is nonzero, the value
   is generated there, if it is convenient to do so.
   In all cases an rtx is returned for the locus of the value;
   this may or may not be TARGET.  */

rtx
expand_unop (mode, unoptab, op0, target, unsignedp)
     enum machine_mode mode;
     optab unoptab;
     rtx op0;
     rtx target;
     int unsignedp;
{
  enum mode_class class;
  enum machine_mode wider_mode;
  rtx temp;
  rtx last = get_last_insn ();
  rtx pat;

  class = GET_MODE_CLASS (mode);

  op0 = protect_from_queue (op0, 0);

  if (flag_force_mem)
    {
      op0 = force_not_mem (op0);
    }

  if (target)
    target = protect_from_queue (target, 1);

  if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
    {
      int icode = (int) unoptab->handlers[(int) mode].insn_code;
      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
      rtx xop0 = op0;

      if (target)
	temp = target;
      else
	temp = gen_reg_rtx (mode);

      if (GET_MODE (xop0) != VOIDmode
	  && GET_MODE (xop0) != mode0)
	xop0 = convert_to_mode (mode0, xop0, unsignedp);

      /* Now, if insn doesn't accept our operand, put it into a pseudo.  */

      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
	xop0 = copy_to_mode_reg (mode0, xop0);

      if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
	temp = gen_reg_rtx (mode);

      pat = GEN_FCN (icode) (temp, xop0);
      if (pat)
	{
	  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
	      && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
	    {
	      delete_insns_since (last);
	      return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
	    }

	  emit_insn (pat);
	  
	  return temp;
	}
      else
	delete_insns_since (last);
    }

  /* It can't be done in this mode.  Can we open-code it in a wider mode?  */

  if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
    for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
	 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
      {
	if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
	  {
	    rtx xop0 = op0;

	    /* For certain operations, we need not actually extend
	       the narrow operand, as long as we will truncate the
	       results to the same narrowness.  */

	    xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
				  (unoptab == neg_optab
				   || unoptab == one_cmpl_optab)
				  && class == MODE_INT);
	      
	    temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
				unsignedp);

	    if (temp)
	      {
		if (class != MODE_INT)
		  {
		    if (target == 0)
		      target = gen_reg_rtx (mode);
		    convert_move (target, temp, 0);
		    return target;
		  }
		else
		  return gen_lowpart (mode, temp);
	      }
	    else
	      delete_insns_since (last);
	  }
      }

  /* These can be done a word at a time.  */
  if (unoptab == one_cmpl_optab
      && class == MODE_INT
      && GET_MODE_SIZE (mode) > UNITS_PER_WORD
      && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
    {
      int i;
      rtx insns;

      if (target == 0 || target == op0)
	target = gen_reg_rtx (mode);

      start_sequence ();

      /* Do the actual arithmetic.  */
      for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
	{
	  rtx target_piece = operand_subword (target, i, 1, mode);
	  rtx x = expand_unop (word_mode, unoptab,
			       operand_subword_force (op0, i, mode),
			       target_piece, unsignedp);

	  if (target_piece != x)
	    emit_move_insn (target_piece, x);
	}

      insns = get_insns ();
      end_sequence ();

      emit_no_conflict_block (insns, target, op0, NULL_RTX,
			      gen_rtx_fmt_e (unoptab->code, mode,
					     copy_rtx (op0)));
      return target;
    }

  /* Open-code the complex negation operation.  */
  else if (unoptab->code == NEG
	   && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
    {
      rtx target_piece;
      rtx x;
      rtx seq;

      /* Find the correct mode for the real and imaginary parts */
      enum machine_mode submode = GET_MODE_INNER (mode);

      if (submode == BLKmode)
	abort ();

      if (target == 0)
	target = gen_reg_rtx (mode);
      
      start_sequence ();

      target_piece = gen_imagpart (submode, target);
      x = expand_unop (submode, unoptab,
		       gen_imagpart (submode, op0),
		       target_piece, unsignedp);
      if (target_piece != x)
	emit_move_insn (target_piece, x);

      target_piece = gen_realpart (submode, target);
      x = expand_unop (submode, unoptab,
		       gen_realpart (submode, op0),
		       target_piece, unsignedp);
      if (target_piece != x)
	emit_move_insn (target_piece, x);

      seq = get_insns ();
      end_sequence ();

      emit_no_conflict_block (seq, target, op0, 0,
			      gen_rtx_fmt_e (unoptab->code, mode,
					     copy_rtx (op0)));
      return target;
    }

  /* Now try a library call in this mode.  */
  if (unoptab->handlers[(int) mode].libfunc)
    {
      rtx insns;
      rtx value;

      start_sequence ();

      /* Pass 1 for NO_QUEUE so we don't lose any increments
	 if the libcall is cse'd or moved.  */
      value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
				       NULL_RTX, LCT_CONST, mode, 1, op0, mode);
      insns = get_insns ();
      end_sequence ();

      target = gen_reg_rtx (mode);
      emit_libcall_block (insns, target, value,
			  gen_rtx_fmt_e (unoptab->code, mode, op0));

      return target;
    }

  if (class == MODE_VECTOR_FLOAT || class == MODE_VECTOR_INT)
    return expand_vector_unop (mode, unoptab, op0, target, unsignedp);

  /* It can't be done in this mode.  Can we do it in a wider mode?  */

  if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
    {
      for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
	{
	  if ((unoptab->handlers[(int) wider_mode].insn_code
	       != CODE_FOR_nothing)
	      || unoptab->handlers[(int) wider_mode].libfunc)
	    {
	      rtx xop0 = op0;

	      /* For certain operations, we need not actually extend
		 the narrow operand, as long as we will truncate the
		 results to the same narrowness.  */

	      xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
				    (unoptab == neg_optab
				     || unoptab == one_cmpl_optab)
				    && class == MODE_INT);
	      
	      temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
				  unsignedp);

	      if (temp)
		{
		  if (class != MODE_INT)
		    {
		      if (target == 0)
			target = gen_reg_rtx (mode);
		      convert_move (target, temp, 0);
		      return target;
		    }
		  else
		    return gen_lowpart (mode, temp);
		}
	      else
		delete_insns_since (last);
	    }
	}
    }

  /* If there is no negate operation, try doing a subtract from zero.
     The US Software GOFAST library needs this.  */
  if (unoptab->code == NEG)
    {    
      rtx temp;
      temp = expand_binop (mode,
                           unoptab == negv_optab ? subv_optab : sub_optab,
                           CONST0_RTX (mode), op0,
                           target, unsignedp, OPTAB_LIB_WIDEN);
      if (temp)
	return temp;
    }
      
  return 0;
}

/* Emit code to compute the absolute value of OP0, with result to
   TARGET if convenient.  (TARGET may be 0.)  The return value says
   where the result actually is to be found.

   MODE is the mode of the operand; the mode of the result is
   different but can be deduced from MODE.

 */

rtx
expand_abs (mode, op0, target, result_unsignedp, safe)
     enum machine_mode mode;
     rtx op0;
     rtx target;
     int result_unsignedp;
     int safe;
{
  rtx temp, op1;

  if (! flag_trapv)
    result_unsignedp = 1;

  /* First try to do it with a special abs instruction.  */
  temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
                      op0, target, 0);
  if (temp != 0)
    return temp;

  /* If we have a MAX insn, we can do this as MAX (x, -x).  */
  if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
    {
      rtx last = get_last_insn ();

      temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
      if (temp != 0)
	temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
			     OPTAB_WIDEN);

      if (temp != 0)
	return temp;

      delete_insns_since (last);
    }

  /* If this machine has expensive jumps, we can do integer absolute
     value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
     where W is the width of MODE.  */

  if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
    {
      rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
				   size_int (GET_MODE_BITSIZE (mode) - 1),
				   NULL_RTX, 0);

      temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
			   OPTAB_LIB_WIDEN);
      if (temp != 0)
	temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
                             temp, extended, target, 0, OPTAB_LIB_WIDEN);

      if (temp != 0)
	return temp;
    }

  /* If that does not win, use conditional jump and negate.  */

  /* It is safe to use the target if it is the same
     as the source if this is also a pseudo register */
  if (op0 == target && GET_CODE (op0) == REG
      && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
    safe = 1;

  op1 = gen_label_rtx ();
  if (target == 0 || ! safe
      || GET_MODE (target) != mode
      || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
      || (GET_CODE (target) == REG
	  && REGNO (target) < FIRST_PSEUDO_REGISTER))
    target = gen_reg_rtx (mode);

  emit_move_insn (target, op0);
  NO_DEFER_POP;

  /* If this mode is an integer too wide to compare properly,
     compare word by word.  Rely on CSE to optimize constant cases.  */
  if (GET_MODE_CLASS (mode) == MODE_INT
      && ! can_compare_p (GE, mode, ccp_jump))
    do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx, 
				  NULL_RTX, op1);
  else
    do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
			     NULL_RTX, NULL_RTX, op1);

  op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
                     target, target, 0);
  if (op0 != target)
    emit_move_insn (target, op0);
  emit_label (op1);
  OK_DEFER_POP;
  return target;
}

/* Emit code to compute the absolute value of OP0, with result to
   TARGET if convenient.  (TARGET may be 0.)  The return value says
   where the result actually is to be found.

   MODE is the mode of the operand; the mode of the result is
   different but can be deduced from MODE.

   UNSIGNEDP is relevant for complex integer modes.  */

rtx
expand_complex_abs (mode, op0, target, unsignedp)
     enum machine_mode mode;
     rtx op0;
     rtx target;
     int unsignedp;
{
  enum mode_class class = GET_MODE_CLASS (mode);
  enum machine_mode wider_mode;
  rtx temp;
  rtx entry_last = get_last_insn ();
  rtx last;
  rtx pat;
  optab this_abs_optab;

  /* Find the correct mode for the real and imaginary parts.  */
  enum machine_mode submode = GET_MODE_INNER (mode);

  if (submode == BLKmode)
    abort ();

  op0 = protect_from_queue (op0, 0);

  if (flag_force_mem)
    {
      op0 = force_not_mem (op0);
    }

  last = get_last_insn ();

  if (target)
    target = protect_from_queue (target, 1);

  this_abs_optab = ! unsignedp && flag_trapv
                   && (GET_MODE_CLASS(mode) == MODE_INT)
                   ? absv_optab : abs_optab;

  if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
    {
      int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
      rtx xop0 = op0;

      if (target)
	temp = target;
      else
	temp = gen_reg_rtx (submode);

      if (GET_MODE (xop0) != VOIDmode
	  && GET_MODE (xop0) != mode0)
	xop0 = convert_to_mode (mode0, xop0, unsignedp);

      /* Now, if insn doesn't accept our operand, put it into a pseudo.  */

      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
	xop0 = copy_to_mode_reg (mode0, xop0);

      if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
	temp = gen_reg_rtx (submode);

      pat = GEN_FCN (icode) (temp, xop0);
      if (pat)
	{
	  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
	      && ! add_equal_note (pat, temp, this_abs_optab->code, xop0, 
				   NULL_RTX))
	    {
	      delete_insns_since (last);
	      return expand_unop (mode, this_abs_optab, op0, NULL_RTX, 
				  unsignedp);
	    }

	  emit_insn (pat);
	  
	  return temp;
	}
      else
	delete_insns_since (last);
    }

  /* It can't be done in this mode.  Can we open-code it in a wider mode?  */

  for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
    {
      if (this_abs_optab->handlers[(int) wider_mode].insn_code 
	  != CODE_FOR_nothing)
	{
	  rtx xop0 = op0;

	  xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
	  temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);

	  if (temp)
	    {
	      if (class != MODE_COMPLEX_INT)
		{
		  if (target == 0)
		    target = gen_reg_rtx (submode);
		  convert_move (target, temp, 0);
		  return target;
		}
	      else
		return gen_lowpart (submode, temp);
	    }
	  else
	    delete_insns_since (last);
	}
    }

  /* Open-code the complex absolute-value operation
     if we can open-code sqrt.  Otherwise it's not worth while.  */
  if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
      && ! flag_trapv)
    {
      rtx real, imag, total;

      real = gen_realpart (submode, op0);
      imag = gen_imagpart (submode, op0);

      /* Square both parts.  */
      real = expand_mult (submode, real, real, NULL_RTX, 0);
      imag = expand_mult (submode, imag, imag, NULL_RTX, 0);

      /* Sum the parts.  */
      total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
			    0, OPTAB_LIB_WIDEN);

      /* Get sqrt in TARGET.  Set TARGET to where the result is.  */
      target = expand_unop (submode, sqrt_optab, total, target, 0);
      if (target == 0)
	delete_insns_since (last);
      else
	return target;
    }

  /* Now try a library call in this mode.  */
  if (this_abs_optab->handlers[(int) mode].libfunc)
    {
      rtx insns;
      rtx value;

      start_sequence ();

      /* Pass 1 for NO_QUEUE so we don't lose any increments
	 if the libcall is cse'd or moved.  */
      value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
				       NULL_RTX, LCT_CONST, submode, 1, op0, mode);
      insns = get_insns ();
      end_sequence ();

      target = gen_reg_rtx (submode);
      emit_libcall_block (insns, target, value,
			  gen_rtx_fmt_e (this_abs_optab->code, mode, op0));

      return target;
    }

  /* It can't be done in this mode.  Can we do it in a wider mode?  */

  for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
    {
      if ((this_abs_optab->handlers[(int) wider_mode].insn_code
	   != CODE_FOR_nothing)
	  || this_abs_optab->handlers[(int) wider_mode].libfunc)
	{
	  rtx xop0 = op0;

	  xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);

	  temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);

	  if (temp)
	    {
	      if (class != MODE_COMPLEX_INT)
		{
		  if (target == 0)
		    target = gen_reg_rtx (submode);
		  convert_move (target, temp, 0);
		  return target;
		}
	      else
		return gen_lowpart (submode, temp);
	    }
	  else
	    delete_insns_since (last);
	}
    }

  delete_insns_since (entry_last);
  return 0;
}

/* Generate an instruction whose insn-code is INSN_CODE,
   with two operands: an output TARGET and an input OP0.
   TARGET *must* be nonzero, and the output is always stored there.
   CODE is an rtx code such that (CODE OP0) is an rtx that describes
   the value that is stored into TARGET.  */

void
emit_unop_insn (icode, target, op0, code)
     int icode;
     rtx target;
     rtx op0;
     enum rtx_code code;
{
  rtx temp;
  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
  rtx pat;

  temp = target = protect_from_queue (target, 1);

  op0 = protect_from_queue (op0, 0);

  /* Sign and zero extension from memory is often done specially on
     RISC machines, so forcing into a register here can pessimize
     code.  */
  if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
    op0 = force_not_mem (op0);

  /* Now, if insn does not accept our operands, put them into pseudos.  */

  if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
    op0 = copy_to_mode_reg (mode0, op0);

  if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
      || (flag_force_mem && GET_CODE (temp) == MEM))
    temp = gen_reg_rtx (GET_MODE (temp));

  pat = GEN_FCN (icode) (temp, op0);

  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
    add_equal_note (pat, temp, code, op0, NULL_RTX);
  
  emit_insn (pat);

  if (temp != target)
    emit_move_insn (target, temp);
}

/* Emit code to perform a series of operations on a multi-word quantity, one
   word at a time.

   Such a block is preceded by a CLOBBER of the output, consists of multiple
   insns, each setting one word of the output, and followed by a SET copying
   the output to itself.

   Each of the insns setting words of the output receives a REG_NO_CONFLICT
   note indicating that it doesn't conflict with the (also multi-word)
   inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
   notes.

   INSNS is a block of code generated to perform the operation, not including
   the CLOBBER and final copy.  All insns that compute intermediate values
   are first emitted, followed by the block as described above.  

   TARGET, OP0, and OP1 are the output and inputs of the operations,
   respectively.  OP1 may be zero for a unary operation.

   EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
   on the last insn.

   If TARGET is not a register, INSNS is simply emitted with no special
   processing.  Likewise if anything in INSNS is not an INSN or if
   there is a libcall block inside INSNS.

   The final insn emitted is returned.  */

rtx
emit_no_conflict_block (insns, target, op0, op1, equiv)
     rtx insns;
     rtx target;
     rtx op0, op1;
     rtx equiv;
{
  rtx prev, next, first, last, insn;

  if (GET_CODE (target) != REG || reload_in_progress)
    return emit_insn (insns);
  else
    for (insn = insns; insn; insn = NEXT_INSN (insn))
      if (GET_CODE (insn) != INSN
	  || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
	return emit_insn (insns);

  /* First emit all insns that do not store into words of the output and remove
     these from the list.  */
  for (insn = insns; insn; insn = next)
    {
      rtx set = 0, note;
      int i;

      next = NEXT_INSN (insn);

      /* Some ports (cris) create an libcall regions at their own.  We must
	 avoid any potential nesting of LIBCALLs.  */
      if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
	remove_note (insn, note);
      if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
	remove_note (insn, note);

      if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
	  || GET_CODE (PATTERN (insn)) == CLOBBER)
	set = PATTERN (insn);
      else if (GET_CODE (PATTERN (insn)) == PARALLEL)
	{
	  for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
	    if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
	      {
		set = XVECEXP (PATTERN (insn), 0, i);
		break;
	      }
	}

      if (set == 0)
	abort ();

      if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
	{
	  if (PREV_INSN (insn))
	    NEXT_INSN (PREV_INSN (insn)) = next;
	  else
	    insns = next;

	  if (next)
	    PREV_INSN (next) = PREV_INSN (insn);

	  add_insn (insn);
	}
    }

  prev = get_last_insn ();

  /* Now write the CLOBBER of the output, followed by the setting of each
     of the words, followed by the final copy.  */
  if (target != op0 && target != op1)
    emit_insn (gen_rtx_CLOBBER (VOIDmode, target));

  for (insn = insns; insn; insn = next)
    {
      next = NEXT_INSN (insn);
      add_insn (insn);

      if (op1 && GET_CODE (op1) == REG)
	REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
					      REG_NOTES (insn));

      if (op0 && GET_CODE (op0) == REG)
	REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
					      REG_NOTES (insn));
    }

  if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
      != CODE_FOR_nothing)
    {
      last = emit_move_insn (target, target);
      if (equiv)
	set_unique_reg_note (last, REG_EQUAL, equiv);
    }
  else
    {
      last = get_last_insn ();

      /* Remove any existing REG_EQUAL note from "last", or else it will
	 be mistaken for a note referring to the full contents of the
	 alleged libcall value when found together with the REG_RETVAL
	 note added below.  An existing note can come from an insn
	 expansion at "last".  */
      remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
    }

  if (prev == 0)
    first = get_insns ();
  else
    first = NEXT_INSN (prev);

  /* Encapsulate the block so it gets manipulated as a unit.  */
  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
					 REG_NOTES (first));
  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));

  return last;
}

/* Emit code to make a call to a constant function or a library call.

   INSNS is a list containing all insns emitted in the call.
   These insns leave the result in RESULT.  Our block is to copy RESULT
   to TARGET, which is logically equivalent to EQUIV.

   We first emit any insns that set a pseudo on the assumption that these are
   loading constants into registers; doing so allows them to be safely cse'ed
   between blocks.  Then we emit all the other insns in the block, followed by
   an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
   note with an operand of EQUIV.

   Moving assignments to pseudos outside of the block is done to improve
   the generated code, but is not required to generate correct code,
   hence being unable to move an assignment is not grounds for not making
   a libcall block.  There are two reasons why it is safe to leave these
   insns inside the block: First, we know that these pseudos cannot be
   used in generated RTL outside the block since they are created for
   temporary purposes within the block.  Second, CSE will not record the
   values of anything set inside a libcall block, so we know they must
   be dead at the end of the block.

   Except for the first group of insns (the ones setting pseudos), the
   block is delimited by REG_RETVAL and REG_LIBCALL notes.  */

void
emit_libcall_block (insns, target, result, equiv)
     rtx insns;
     rtx target;
     rtx result;
     rtx equiv;
{
  rtx final_dest = target;
  rtx prev, next, first, last, insn;

  /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
     into a MEM later.  Protect the libcall block from this change.  */
  if (! REG_P (target) || REG_USERVAR_P (target))
    target = gen_reg_rtx (GET_MODE (target));
  
  /* If we're using non-call exceptions, a libcall corresponding to an
     operation that may trap may also trap.  */
  if (flag_non_call_exceptions && may_trap_p (equiv))
    {
      for (insn = insns; insn; insn = NEXT_INSN (insn))
	if (GET_CODE (insn) == CALL_INSN)
	  {
	    rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
	    
	    if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
	      remove_note (insn, note);
	  }
    }
  else
  /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
     reg note to indicate that this call cannot throw or execute a nonlocal
     goto (unless there is already a REG_EH_REGION note, in which case
     we update it).  */
    for (insn = insns; insn; insn = NEXT_INSN (insn))
      if (GET_CODE (insn) == CALL_INSN)
	{
	  rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
	
	  if (note != 0)
	    XEXP (note, 0) = GEN_INT (-1);
	  else
	    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
						  REG_NOTES (insn));
	}

  /* First emit all insns that set pseudos.  Remove them from the list as
     we go.  Avoid insns that set pseudos which were referenced in previous
     insns.  These can be generated by move_by_pieces, for example,
     to update an address.  Similarly, avoid insns that reference things
     set in previous insns.  */

  for (insn = insns; insn; insn = next)
    {
      rtx set = single_set (insn);
      rtx note;

      /* Some ports (cris) create an libcall regions at their own.  We must
	 avoid any potential nesting of LIBCALLs.  */
      if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
	remove_note (insn, note);
      if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
	remove_note (insn, note);

      next = NEXT_INSN (insn);

      if (set != 0 && GET_CODE (SET_DEST (set)) == REG
	  && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
	  && (insn == insns
	      || ((! INSN_P(insns)
		   || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
		  && ! reg_used_between_p (SET_DEST (set), insns, insn)
		  && ! modified_in_p (SET_SRC (set), insns)
		  && ! modified_between_p (SET_SRC (set), insns, insn))))
	{
	  if (PREV_INSN (insn))
	    NEXT_INSN (PREV_INSN (insn)) = next;
	  else
	    insns = next;

	  if (next)
	    PREV_INSN (next) = PREV_INSN (insn);

	  add_insn (insn);
	}
    }

  prev = get_last_insn ();

  /* Write the remaining insns followed by the final copy.  */

  for (insn = insns; insn; insn = next)
    {
      next = NEXT_INSN (insn);

      add_insn (insn);
    }

  last = emit_move_insn (target, result);
  if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
      != CODE_FOR_nothing)
    set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
  else
    {
      /* Remove any existing REG_EQUAL note from "last", or else it will
	 be mistaken for a note referring to the full contents of the
	 libcall value when found together with the REG_RETVAL note added
	 below.  An existing note can come from an insn expansion at
	 "last".  */
      remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
    }

  if (final_dest != target)
    emit_move_insn (final_dest, target);

  if (prev == 0)
    first = get_insns ();
  else
    first = NEXT_INSN (prev);

  /* Encapsulate the block so it gets manipulated as a unit.  */
  if (!flag_non_call_exceptions || !may_trap_p (equiv))
    {
      /* We can't attach the REG_LIBCALL and REG_RETVAL notes
	 when the encapsulated region would not be in one basic block,
	 i.e. when there is a control_flow_insn_p insn between FIRST and LAST.
       */
      bool attach_libcall_retval_notes = true;
      next = NEXT_INSN (last);
      for (insn = first; insn != next; insn = NEXT_INSN (insn))
	if (control_flow_insn_p (insn))
	  {
	    attach_libcall_retval_notes = false;
	    break;
	  }

      if (attach_libcall_retval_notes)
	{
	  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
						 REG_NOTES (first));
	  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
						REG_NOTES (last));
	}
    }
}

/* Generate code to store zero in X.  */

void
emit_clr_insn (x)
     rtx x;
{
  emit_move_insn (x, const0_rtx);
}

/* Generate code to store 1 in X
   assuming it contains zero beforehand.  */

void
emit_0_to_1_insn (x)
     rtx x;
{
  emit_move_insn (x, const1_rtx);
}

/* Nonzero if we can perform a comparison of mode MODE straightforwardly.
   PURPOSE describes how this comparison will be used.  CODE is the rtx
   comparison code we will be using.

   ??? Actually, CODE is slightly weaker than that.  A target is still
   required to implement all of the normal bcc operations, but not 
   required to implement all (or any) of the unordered bcc operations.  */
  
int
can_compare_p (code, mode, purpose)
     enum rtx_code code;
     enum machine_mode mode;
     enum can_compare_purpose purpose;
{
  do
    {
      if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
	{
	  if (purpose == ccp_jump)
	    return bcc_gen_fctn[(int) code] != NULL;
	  else if (purpose == ccp_store_flag)
	    return setcc_gen_code[(int) code] != CODE_FOR_nothing;
	  else
	    /* There's only one cmov entry point, and it's allowed to fail.  */
	    return 1;
	}
      if (purpose == ccp_jump
	  && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
	return 1;
      if (purpose == ccp_cmov
	  && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
	return 1;
      if (purpose == ccp_store_flag
	  && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
	return 1;

      mode = GET_MODE_WIDER_MODE (mode);
    }
  while (mode != VOIDmode);

  return 0;
}

/* This function is called when we are going to emit a compare instruction that
   compares the values found in *PX and *PY, using the rtl operator COMPARISON.

   *PMODE is the mode of the inputs (in case they are const_int).
   *PUNSIGNEDP nonzero says that the operands are unsigned;
   this matters if they need to be widened.

   If they have mode BLKmode, then SIZE specifies the size of both operands.

   This function performs all the setup necessary so that the caller only has
   to emit a single comparison insn.  This setup can involve doing a BLKmode
   comparison or emitting a library call to perform the comparison if no insn
   is available to handle it.
   The values which are passed in through pointers can be modified; the caller
   should perform the comparison on the modified values.  */

static void
prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose)
     rtx *px, *py;
     enum rtx_code *pcomparison;
     rtx size;
     enum machine_mode *pmode;
     int *punsignedp;
     enum can_compare_purpose purpose;
{
  enum machine_mode mode = *pmode;
  rtx x = *px, y = *py;
  int unsignedp = *punsignedp;
  enum mode_class class;

  class = GET_MODE_CLASS (mode);

  /* They could both be VOIDmode if both args are immediate constants,
     but we should fold that at an earlier stage.
     With no special code here, this will call abort,
     reminding the programmer to implement such folding.  */

  if (mode != BLKmode && flag_force_mem)
    {
      x = force_not_mem (x);
      y = force_not_mem (y);
    }

  /* If we are inside an appropriately-short loop and one operand is an
     expensive constant, force it into a register.  */
  if (CONSTANT_P (x) && preserve_subexpressions_p ()
      && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
    x = force_reg (mode, x);

  if (CONSTANT_P (y) && preserve_subexpressions_p ()
      && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
    y = force_reg (mode, y);

#ifdef HAVE_cc0
  /* Abort if we have a non-canonical comparison.  The RTL documentation
     states that canonical comparisons are required only for targets which
     have cc0.  */
  if (CONSTANT_P (x) && ! CONSTANT_P (y))
    abort ();
#endif

  /* Don't let both operands fail to indicate the mode.  */
  if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
    x = force_reg (mode, x);

  /* Handle all BLKmode compares.  */

  if (mode == BLKmode)
    {
      rtx result;
      enum machine_mode result_mode;
      rtx opalign ATTRIBUTE_UNUSED
	= GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);

      emit_queue ();
      x = protect_from_queue (x, 0);
      y = protect_from_queue (y, 0);

      if (size == 0)
	abort ();
#ifdef HAVE_cmpmemqi
      if (HAVE_cmpmemqi
	  && GET_CODE (size) == CONST_INT
	  && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
	{
	  result_mode = insn_data[(int) CODE_FOR_cmpmemqi].operand[0].mode;
	  result = gen_reg_rtx (result_mode);
	  emit_insn (gen_cmpmemqi (result, x, y, size, opalign));
	}
      else
#endif
#ifdef HAVE_cmpmemhi
      if (HAVE_cmpmemhi
	  && GET_CODE (size) == CONST_INT
	  && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
	{
	  result_mode = insn_data[(int) CODE_FOR_cmpmemhi].operand[0].mode;
	  result = gen_reg_rtx (result_mode);
	  emit_insn (gen_cmpmemhi (result, x, y, size, opalign));
	}
      else
#endif
#ifdef HAVE_cmpmemsi
      if (HAVE_cmpmemsi)
	{
	  result_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
	  result = gen_reg_rtx (result_mode);
	  size = protect_from_queue (size, 0);
	  emit_insn (gen_cmpmemsi (result, x, y,
				   convert_to_mode (SImode, size, 1),
				   opalign));
	}
      else
#endif
#ifdef HAVE_cmpstrqi
      if (HAVE_cmpstrqi
	  && GET_CODE (size) == CONST_INT
	  && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
	{
	  result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
	  result = gen_reg_rtx (result_mode);
	  emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
	}
      else
#endif
#ifdef HAVE_cmpstrhi
      if (HAVE_cmpstrhi
	  && GET_CODE (size) == CONST_INT
	  && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
	{
	  result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
	  result = gen_reg_rtx (result_mode);
	  emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
	}
      else
#endif
#ifdef HAVE_cmpstrsi
      if (HAVE_cmpstrsi)
	{
	  result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
	  result = gen_reg_rtx (result_mode);
	  size = protect_from_queue (size, 0);
	  emit_insn (gen_cmpstrsi (result, x, y,
				   convert_to_mode (SImode, size, 1),
				   opalign));
	}
      else
#endif
	{
#ifdef TARGET_MEM_FUNCTIONS
	  result = emit_library_call_value (memcmp_libfunc, NULL_RTX, LCT_PURE_MAKE_BLOCK,
					    TYPE_MODE (integer_type_node), 3,
					    XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
					    convert_to_mode (TYPE_MODE (sizetype), size,
							     TREE_UNSIGNED (sizetype)),
					    TYPE_MODE (sizetype));
#else
	  result = emit_library_call_value (bcmp_libfunc, NULL_RTX, LCT_PURE_MAKE_BLOCK,
					    TYPE_MODE (integer_type_node), 3,
					    XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
					    convert_to_mode (TYPE_MODE (integer_type_node),
							     size,
							     TREE_UNSIGNED (integer_type_node)),
					    TYPE_MODE (integer_type_node));
#endif

	  result_mode = TYPE_MODE (integer_type_node);
	}
      *px = result;
      *py = const0_rtx;
      *pmode = result_mode;
      return;
    }

  /* Don't allow operands to the compare to trap, as that can put the
     compare and branch in different basic blocks.  */
  if (flag_non_call_exceptions)
    {
      if (may_trap_p (x))
	x = force_reg (mode, x);
      if (may_trap_p (y))
	y = force_reg (mode, y);
    }

  *px = x;
  *py = y;
  if (can_compare_p (*pcomparison, mode, purpose))
    return;

  /* Handle a lib call just for the mode we are using.  */

  if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
    {
      rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
      rtx result;

      /* If we want unsigned, and this mode has a distinct unsigned
	 comparison routine, use that.  */
      if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
	libfunc = ucmp_optab->handlers[(int) mode].libfunc;

      result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
					word_mode, 2, x, mode, y, mode);

      /* Integer comparison returns a result that must be compared against 1,
	 so that even if we do an unsigned compare afterward,
	 there is still a value that can represent the result "less than".  */
      *px = result;
      *py = const1_rtx;
      *pmode = word_mode;
      return;
    }

  if (class == MODE_FLOAT)
    prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);

  else
    abort ();
}

/* Before emitting an insn with code ICODE, make sure that X, which is going
   to be used for operand OPNUM of the insn, is converted from mode MODE to
   WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
   that it is accepted by the operand predicate.  Return the new value.  */

rtx
prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
     int icode;
     rtx x;
     int opnum;
     enum machine_mode mode, wider_mode;
     int unsignedp;
{
  x = protect_from_queue (x, 0);

  if (mode != wider_mode)
    x = convert_modes (wider_mode, mode, x, unsignedp);

  if (! (*insn_data[icode].operand[opnum].predicate)
      (x, insn_data[icode].operand[opnum].mode))
    {
      if (no_new_pseudos)
	return NULL_RTX;
      x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
    }

  return x;
}

/* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
   we can do the comparison.
   The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
   be NULL_RTX which indicates that only a comparison is to be generated.  */

static void
emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
     rtx x, y;
     enum machine_mode mode;
     enum rtx_code comparison;
     int unsignedp;
     rtx label;
{
  rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
  enum mode_class class = GET_MODE_CLASS (mode);
  enum machine_mode wider_mode = mode;

  /* Try combined insns first.  */
  do
    {
      enum insn_code icode;
      PUT_MODE (test, wider_mode);

      if (label)
	{	  
	  icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
	  
	  if (icode != CODE_FOR_nothing
	      && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
	    {
	      x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
	      y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
	      emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
	      return;
	    }
	}

      /* Handle some compares against zero.  */
      icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
      if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
	{
	  x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
	  emit_insn (GEN_FCN (icode) (x));
	  if (label)
	    emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
	  return;
	}

      /* Handle compares for which there is a directly suitable insn.  */

      icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
      if (icode != CODE_FOR_nothing)
	{
	  x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
	  y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
	  emit_insn (GEN_FCN (icode) (x, y));
	  if (label)
	    emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
	  return;
	}

      if (class != MODE_INT && class != MODE_FLOAT
	  && class != MODE_COMPLEX_FLOAT)
	break;

      wider_mode = GET_MODE_WIDER_MODE (wider_mode);
    }
  while (wider_mode != VOIDmode);

  abort ();
}

/* Generate code to compare X with Y so that the condition codes are
   set and to jump to LABEL if the condition is true.  If X is a
   constant and Y is not a constant, then the comparison is swapped to
   ensure that the comparison RTL has the canonical form.

   UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
   need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
   the proper branch condition code.

   If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.

   MODE is the mode of the inputs (in case they are const_int).

   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
   be passed unchanged to emit_cmp_insn, then potentially converted into an
   unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */

void
emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, label)
     rtx x, y;
     enum rtx_code comparison;
     rtx size;
     enum machine_mode mode;
     int unsignedp;
     rtx label;
{
  rtx op0 = x, op1 = y;

  /* Swap operands and condition to ensure canonical RTL.  */
  if (swap_commutative_operands_p (x, y))
    {
      /* If we're not emitting a branch, this means some caller
         is out of sync.  */
      if (! label)
	abort ();

      op0 = y, op1 = x;
      comparison = swap_condition (comparison);
    }

#ifdef HAVE_cc0
  /* If OP0 is still a constant, then both X and Y must be constants.  Force
     X into a register to avoid aborting in emit_cmp_insn due to non-canonical
     RTL.  */
  if (CONSTANT_P (op0))
    op0 = force_reg (mode, op0);
#endif

  emit_queue ();
  if (unsignedp)
    comparison = unsigned_condition (comparison);

  prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
		    ccp_jump);
  emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
}

/* Like emit_cmp_and_jump_insns, but generate only the comparison.  */

void
emit_cmp_insn (x, y, comparison, size, mode, unsignedp)
     rtx x, y;
     enum rtx_code comparison;
     rtx size;
     enum machine_mode mode;
     int unsignedp;
{
  emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
}

/* Emit a library call comparison between floating point X and Y.
   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */

static void
prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
     rtx *px, *py;
     enum rtx_code *pcomparison;
     enum machine_mode *pmode;
     int *punsignedp;
{
  enum rtx_code comparison = *pcomparison;
  rtx tmp;
  rtx x = *px = protect_from_queue (*px, 0);
  rtx y = *py = protect_from_queue (*py, 0);
  enum machine_mode mode = GET_MODE (x);
  rtx libfunc = 0;
  rtx result;

  if (mode == HFmode)
    switch (comparison)
      {
      case EQ:
	libfunc = eqhf2_libfunc;
	break;

      case NE:
	libfunc = nehf2_libfunc;
	break;

      case GT:
	libfunc = gthf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = LT;
	    libfunc = lthf2_libfunc;
	  }
	break;

      case GE:
	libfunc = gehf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = LE;
	    libfunc = lehf2_libfunc;
	  }
	break;

      case LT:
	libfunc = lthf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = GT;
	    libfunc = gthf2_libfunc;
	  }
	break;

      case LE:
	libfunc = lehf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = GE;
	    libfunc = gehf2_libfunc;
	  }
	break;

      case UNORDERED:
	libfunc = unordhf2_libfunc;
	break;

      default:
	break;
      }
  else if (mode == SFmode)
    switch (comparison)
      {
      case EQ:
	libfunc = eqsf2_libfunc;
	break;

      case NE:
	libfunc = nesf2_libfunc;
	break;

      case GT:
	libfunc = gtsf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = LT;
	    libfunc = ltsf2_libfunc;
	  }
	break;

      case GE:
	libfunc = gesf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = LE;
	    libfunc = lesf2_libfunc;
	  }
	break;

      case LT:
	libfunc = ltsf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = GT;
	    libfunc = gtsf2_libfunc;
	  }
	break;

      case LE:
	libfunc = lesf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = GE;
	    libfunc = gesf2_libfunc;
	  }
	break;

      case UNORDERED:
	libfunc = unordsf2_libfunc;
	break;

      default:
	break;
      }
  else if (mode == DFmode)
    switch (comparison)
      {
      case EQ:
	libfunc = eqdf2_libfunc;
	break;

      case NE:
	libfunc = nedf2_libfunc;
	break;

      case GT:
	libfunc = gtdf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = LT;
	    libfunc = ltdf2_libfunc;
	  }
	break;

      case GE:
	libfunc = gedf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = LE;
	    libfunc = ledf2_libfunc;
	  }
	break;

      case LT:
	libfunc = ltdf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = GT;
	    libfunc = gtdf2_libfunc;
	  }
	break;

      case LE:
	libfunc = ledf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = GE;
	    libfunc = gedf2_libfunc;
	  }
	break;

      case UNORDERED:
	libfunc = unorddf2_libfunc;
	break;

      default:
	break;
      }
  else if (mode == XFmode)
    switch (comparison)
      {
      case EQ:
	libfunc = eqxf2_libfunc;
	break;

      case NE:
	libfunc = nexf2_libfunc;
	break;

      case GT:
	libfunc = gtxf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = LT;
	    libfunc = ltxf2_libfunc;
	  }
	break;

      case GE:
	libfunc = gexf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = LE;
	    libfunc = lexf2_libfunc;
	  }
	break;

      case LT:
	libfunc = ltxf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = GT;
	    libfunc = gtxf2_libfunc;
	  }
	break;

      case LE:
	libfunc = lexf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = GE;
	    libfunc = gexf2_libfunc;
	  }
	break;

      case UNORDERED:
	libfunc = unordxf2_libfunc;
	break;

      default:
	break;
      }
  else if (mode == TFmode)
    switch (comparison)
      {
      case EQ:
	libfunc = eqtf2_libfunc;
	break;

      case NE:
	libfunc = netf2_libfunc;
	break;

      case GT:
	libfunc = gttf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = LT;
	    libfunc = lttf2_libfunc;
	  }
	break;

      case GE:
	libfunc = getf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = LE;
	    libfunc = letf2_libfunc;
	  }
	break;

      case LT:
	libfunc = lttf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = GT;
	    libfunc = gttf2_libfunc;
	  }
	break;

      case LE:
	libfunc = letf2_libfunc;
	if (libfunc == NULL_RTX)
	  {
	    tmp = x; x = y; y = tmp;
	    *pcomparison = GE;
	    libfunc = getf2_libfunc;
	  }
	break;

      case UNORDERED:
	libfunc = unordtf2_libfunc;
	break;

      default:
	break;
      }
  else
    {
      enum machine_mode wider_mode;

      for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
	{
	  if ((cmp_optab->handlers[(int) wider_mode].insn_code
	       != CODE_FOR_nothing)
	      || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
	    {
	      x = protect_from_queue (x, 0);
	      y = protect_from_queue (y, 0);
	      *px = convert_to_mode (wider_mode, x, 0);
	      *py = convert_to_mode (wider_mode, y, 0);
	      prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
	      return;
	    }
	}
      abort ();
    }

  if (libfunc == 0)
    abort ();

  result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
				    word_mode, 2, x, mode, y, mode);
  *px = result;
  *py = const0_rtx;
  *pmode = word_mode;
  if (comparison == UNORDERED)
    *pcomparison = NE;
#ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
  else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
    *pcomparison = NE;
#endif
  *punsignedp = 0;
}

/* Generate code to indirectly jump to a location given in the rtx LOC.  */

void
emit_indirect_jump (loc)
     rtx loc;
{
  if (! ((*insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate)
	 (loc, Pmode)))
    loc = copy_to_mode_reg (Pmode, loc);

  emit_jump_insn (gen_indirect_jump (loc));
  emit_barrier ();
}

#ifdef HAVE_conditional_move

/* Emit a conditional move instruction if the machine supports one for that
   condition and machine mode.

   OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
   the mode to use should they be constants.  If it is VOIDmode, they cannot
   both be constants.

   OP2 should be stored in TARGET if the comparison is true, otherwise OP3
   should be stored there.  MODE is the mode to use should they be constants.
   If it is VOIDmode, they cannot both be constants.

   The result is either TARGET (perhaps modified) or NULL_RTX if the operation
   is not supported.  */

rtx
emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
		       unsignedp)
     rtx target;
     enum rtx_code code;
     rtx op0, op1;
     enum machine_mode cmode;
     rtx op2, op3;
     enum machine_mode mode;
     int unsignedp;
{
  rtx tem, subtarget, comparison, insn;
  enum insn_code icode;
  enum rtx_code reversed;

  /* If one operand is constant, make it the second one.  Only do this
     if the other operand is not constant as well.  */

  if (swap_commutative_operands_p (op0, op1))
    {
      tem = op0;
      op0 = op1;
      op1 = tem;
      code = swap_condition (code);
    }

  /* get_condition will prefer to generate LT and GT even if the old
     comparison was against zero, so undo that canonicalization here since
     comparisons against zero are cheaper.  */
  if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
    code = LE, op1 = const0_rtx;
  else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
    code = GE, op1 = const0_rtx;

  if (cmode == VOIDmode)
    cmode = GET_MODE (op0);

  if (swap_commutative_operands_p (op2, op3)
      && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
          != UNKNOWN))
    {
      tem = op2;
      op2 = op3;
      op3 = tem;
      code = reversed;
    }

  if (mode == VOIDmode)
    mode = GET_MODE (op2);

  icode = movcc_gen_code[mode];

  if (icode == CODE_FOR_nothing)
    return 0;

  if (flag_force_mem)
    {
      op2 = force_not_mem (op2);
      op3 = force_not_mem (op3);
    }

  if (target)
    target = protect_from_queue (target, 1);
  else
    target = gen_reg_rtx (mode);

  subtarget = target;

  emit_queue ();

  op2 = protect_from_queue (op2, 0);
  op3 = protect_from_queue (op3, 0);

  /* If the insn doesn't accept these operands, put them in pseudos.  */

  if (! (*insn_data[icode].operand[0].predicate)
      (subtarget, insn_data[icode].operand[0].mode))
    subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);

  if (! (*insn_data[icode].operand[2].predicate)
      (op2, insn_data[icode].operand[2].mode))
    op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);

  if (! (*insn_data[icode].operand[3].predicate)
      (op3, insn_data[icode].operand[3].mode))
    op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);

  /* Everything should now be in the suitable form, so emit the compare insn
     and then the conditional move.  */

  comparison 
    = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);

  /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
  /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
     return NULL and let the caller figure out how best to deal with this
     situation.  */
  if (GET_CODE (comparison) != code)
    return NULL_RTX;
  
  insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);

  /* If that failed, then give up.  */
  if (insn == 0)
    return 0;

  emit_insn (insn);

  if (subtarget != target)
    convert_move (target, subtarget, 0);

  return target;
}

/* Return nonzero if a conditional move of mode MODE is supported.

   This function is for combine so it can tell whether an insn that looks
   like a conditional move is actually supported by the hardware.  If we
   guess wrong we lose a bit on optimization, but that's it.  */
/* ??? sparc64 supports conditionally moving integers values based on fp
   comparisons, and vice versa.  How do we handle them?  */

int
can_conditionally_move_p (mode)
     enum machine_mode mode;
{
  if (movcc_gen_code[mode] != CODE_FOR_nothing)
    return 1;

  return 0;
}

#endif /* HAVE_conditional_move */

/* These functions generate an insn body and return it
   rather than emitting the insn.

   They do not protect from queued increments,
   because they may be used 1) in protect_from_queue itself
   and 2) in other passes where there is no queue.  */

/* Generate and return an insn body to add Y to X.  */

rtx
gen_add2_insn (x, y)
     rtx x, y;
{
  int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 

  if (! ((*insn_data[icode].operand[0].predicate)
	 (x, insn_data[icode].operand[0].mode))
      || ! ((*insn_data[icode].operand[1].predicate)
	    (x, insn_data[icode].operand[1].mode))
      || ! ((*insn_data[icode].operand[2].predicate)
	    (y, insn_data[icode].operand[2].mode)))
    abort ();

  return (GEN_FCN (icode) (x, x, y));
}

/* Generate and return an insn body to add r1 and c,
   storing the result in r0.  */
rtx
gen_add3_insn (r0, r1, c)
     rtx r0, r1, c;
{
  int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;

  if (icode == CODE_FOR_nothing
      || ! ((*insn_data[icode].operand[0].predicate)
	    (r0, insn_data[icode].operand[0].mode))
      || ! ((*insn_data[icode].operand[1].predicate)
	    (r1, insn_data[icode].operand[1].mode))
      || ! ((*insn_data[icode].operand[2].predicate)
	    (c, insn_data[icode].operand[2].mode)))
    return NULL_RTX;

  return (GEN_FCN (icode) (r0, r1, c));
}

int
have_add2_insn (x, y)
     rtx x, y;
{
  int icode;

  if (GET_MODE (x) == VOIDmode)
    abort ();

  icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 

  if (icode == CODE_FOR_nothing)
    return 0;

  if (! ((*insn_data[icode].operand[0].predicate)
	 (x, insn_data[icode].operand[0].mode))
      || ! ((*insn_data[icode].operand[1].predicate)
	    (x, insn_data[icode].operand[1].mode))
      || ! ((*insn_data[icode].operand[2].predicate)
	    (y, insn_data[icode].operand[2].mode)))
    return 0;

  return 1;
}

/* Generate and return an insn body to subtract Y from X.  */

rtx
gen_sub2_insn (x, y)
     rtx x, y;
{
  int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 

  if (! ((*insn_data[icode].operand[0].predicate)
	 (x, insn_data[icode].operand[0].mode))
      || ! ((*insn_data[icode].operand[1].predicate)
	    (x, insn_data[icode].operand[1].mode))
      || ! ((*insn_data[icode].operand[2].predicate)
	    (y, insn_data[icode].operand[2].mode)))
    abort ();

  return (GEN_FCN (icode) (x, x, y));
}

/* Generate and return an insn body to subtract r1 and c,
   storing the result in r0.  */
rtx
gen_sub3_insn (r0, r1, c)
     rtx r0, r1, c;
{
  int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;

  if (icode == CODE_FOR_nothing
      || ! ((*insn_data[icode].operand[0].predicate)
	    (r0, insn_data[icode].operand[0].mode))
      || ! ((*insn_data[icode].operand[1].predicate)
	    (r1, insn_data[icode].operand[1].mode))
      || ! ((*insn_data[icode].operand[2].predicate)
	    (c, insn_data[icode].operand[2].mode)))
    return NULL_RTX;

  return (GEN_FCN (icode) (r0, r1, c));
}

int
have_sub2_insn (x, y)
     rtx x, y;
{
  int icode;

  if (GET_MODE (x) == VOIDmode)
    abort ();

  icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 

  if (icode == CODE_FOR_nothing)
    return 0;

  if (! ((*insn_data[icode].operand[0].predicate)
	 (x, insn_data[icode].operand[0].mode))
      || ! ((*insn_data[icode].operand[1].predicate)
	    (x, insn_data[icode].operand[1].mode))
      || ! ((*insn_data[icode].operand[2].predicate)
	    (y, insn_data[icode].operand[2].mode)))
    return 0;

  return 1;
}

/* Generate the body of an instruction to copy Y into X.
   It may be a list of insns, if one insn isn't enough.  */

rtx
gen_move_insn (x, y)
     rtx x, y;
{
  enum machine_mode mode = GET_MODE (x);
  enum insn_code insn_code;
  rtx seq;

  if (mode == VOIDmode)
    mode = GET_MODE (y); 

  insn_code = mov_optab->handlers[(int) mode].insn_code;

  /* Handle MODE_CC modes:  If we don't have a special move insn for this mode,
     find a mode to do it in.  If we have a movcc, use it.  Otherwise,
     find the MODE_INT mode of the same width.  */

  if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
    {
      enum machine_mode tmode = VOIDmode;
      rtx x1 = x, y1 = y;

      if (mode != CCmode
	  && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
	tmode = CCmode;
      else
	for (tmode = QImode; tmode != VOIDmode;
	     tmode = GET_MODE_WIDER_MODE (tmode))
	  if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
	    break;

      if (tmode == VOIDmode)
	abort ();

      /* Get X and Y in TMODE.  We can't use gen_lowpart here because it
	 may call change_address which is not appropriate if we were
	 called when a reload was in progress.  We don't have to worry
	 about changing the address since the size in bytes is supposed to
	 be the same.  Copy the MEM to change the mode and move any
	 substitutions from the old MEM to the new one.  */

      if (reload_in_progress)
	{
	  x = gen_lowpart_common (tmode, x1);
	  if (x == 0 && GET_CODE (x1) == MEM)
	    {
	      x = adjust_address_nv (x1, tmode, 0);
	      copy_replacements (x1, x);
	    }

	  y = gen_lowpart_common (tmode, y1);
	  if (y == 0 && GET_CODE (y1) == MEM)
	    {
	      y = adjust_address_nv (y1, tmode, 0);
	      copy_replacements (y1, y);
	    }
	}
      else
	{
	  x = gen_lowpart (tmode, x);
	  y = gen_lowpart (tmode, y);
	}
	  
      insn_code = mov_optab->handlers[(int) tmode].insn_code;
      return (GEN_FCN (insn_code) (x, y));
    }

  start_sequence ();
  emit_move_insn_1 (x, y);
  seq = get_insns ();
  end_sequence ();
  return seq;
}

/* Return the insn code used to extend FROM_MODE to TO_MODE.
   UNSIGNEDP specifies zero-extension instead of sign-extension.  If
   no such operation exists, CODE_FOR_nothing will be returned.  */

enum insn_code
can_extend_p (to_mode, from_mode, unsignedp)
     enum machine_mode to_mode, from_mode;
     int unsignedp;
{
#ifdef HAVE_ptr_extend
  if (unsignedp < 0)
    return CODE_FOR_ptr_extend;
  else
#endif
    return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
}

/* Generate the body of an insn to extend Y (with mode MFROM)
   into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */

rtx
gen_extend_insn (x, y, mto, mfrom, unsignedp)
     rtx x, y;
     enum machine_mode mto, mfrom;
     int unsignedp;
{
  return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
}

/* can_fix_p and can_float_p say whether the target machine
   can directly convert a given fixed point type to
   a given floating point type, or vice versa.
   The returned value is the CODE_FOR_... value to use,
   or CODE_FOR_nothing if these modes cannot be directly converted.

   *TRUNCP_PTR is set to 1 if it is necessary to output
   an explicit FTRUNC insn before the fix insn; otherwise 0.  */

static enum insn_code
can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
     enum machine_mode fltmode, fixmode;
     int unsignedp;
     int *truncp_ptr;
{
  *truncp_ptr = 0;
  if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
      != CODE_FOR_nothing)
    return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];

  if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
    {
      *truncp_ptr = 1;
      return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
    }
  return CODE_FOR_nothing;
}

static enum insn_code
can_float_p (fltmode, fixmode, unsignedp)
     enum machine_mode fixmode, fltmode;
     int unsignedp;
{
  return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
}

/* Generate code to convert FROM to floating point
   and store in TO.  FROM must be fixed point and not VOIDmode.
   UNSIGNEDP nonzero means regard FROM as unsigned.
   Normally this is done by correcting the final value
   if it is negative.  */

void
expand_float (to, from, unsignedp)
     rtx to, from;
     int unsignedp;
{
  enum insn_code icode;
  rtx target = to;
  enum machine_mode fmode, imode;

  /* Crash now, because we won't be able to decide which mode to use.  */
  if (GET_MODE (from) == VOIDmode)
    abort ();

  /* Look for an insn to do the conversion.  Do it in the specified
     modes if possible; otherwise convert either input, output or both to
     wider mode.  If the integer mode is wider than the mode of FROM,
     we can do the conversion signed even if the input is unsigned.  */

  for (fmode = GET_MODE (to); fmode != VOIDmode;
       fmode = GET_MODE_WIDER_MODE (fmode))
    for (imode = GET_MODE (from); imode != VOIDmode;
	 imode = GET_MODE_WIDER_MODE (imode))
      {
	int doing_unsigned = unsignedp;

	if (fmode != GET_MODE (to)
	    && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
	  continue;

	icode = can_float_p (fmode, imode, unsignedp);
	if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
	  icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;

	if (icode != CODE_FOR_nothing)
	  {
	    to = protect_from_queue (to, 1);
	    from = protect_from_queue (from, 0);

	    if (imode != GET_MODE (from))
	      from = convert_to_mode (imode, from, unsignedp);

	    if (fmode != GET_MODE (to))
	      target = gen_reg_rtx (fmode);

	    emit_unop_insn (icode, target, from,
			    doing_unsigned ? UNSIGNED_FLOAT : FLOAT);

	    if (target != to)
	      convert_move (to, target, 0);
	    return;
	  }
      }

  /* Unsigned integer, and no way to convert directly.
     Convert as signed, then conditionally adjust the result.  */
  if (unsignedp)
    {
      rtx label = gen_label_rtx ();
      rtx temp;
      REAL_VALUE_TYPE offset;

      emit_queue ();

      to = protect_from_queue (to, 1);
      from = protect_from_queue (from, 0);

      if (flag_force_mem)
	from = force_not_mem (from);

      /* Look for a usable floating mode FMODE wider than the source and at
	 least as wide as the target.  Using FMODE will avoid rounding woes
	 with unsigned values greater than the signed maximum value.  */

      for (fmode = GET_MODE (to);  fmode != VOIDmode;
	   fmode = GET_MODE_WIDER_MODE (fmode))
	if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
	    && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
	  break;

      if (fmode == VOIDmode)
	{
	  /* There is no such mode.  Pretend the target is wide enough.  */
	  fmode = GET_MODE (to);

	  /* Avoid double-rounding when TO is narrower than FROM.  */
	  if ((significand_size (fmode) + 1)
	      < GET_MODE_BITSIZE (GET_MODE (from)))
	    {
	      rtx temp1;
	      rtx neglabel = gen_label_rtx ();

	      /* Don't use TARGET if it isn't a register, is a hard register, 
		 or is the wrong mode.  */
	      if (GET_CODE (target) != REG
		  || REGNO (target) < FIRST_PSEUDO_REGISTER
		  || GET_MODE (target) != fmode)
		target = gen_reg_rtx (fmode);

	      imode = GET_MODE (from);
	      do_pending_stack_adjust ();

	      /* Test whether the sign bit is set.  */
	      emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
				       0, neglabel);

	      /* The sign bit is not set.  Convert as signed.  */
	      expand_float (target, from, 0);
	      emit_jump_insn (gen_jump (label));
	      emit_barrier ();

	      /* The sign bit is set.
		 Convert to a usable (positive signed) value by shifting right
		 one bit, while remembering if a nonzero bit was shifted
		 out; i.e., compute  (from & 1) | (from >> 1).  */

	      emit_label (neglabel);
	      temp = expand_binop (imode, and_optab, from, const1_rtx,
				   NULL_RTX, 1, OPTAB_LIB_WIDEN);
	      temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
				    NULL_RTX, 1);
	      temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1, 
				   OPTAB_LIB_WIDEN);
	      expand_float (target, temp, 0);

	      /* Multiply by 2 to undo the shift above.  */
	      temp = expand_binop (fmode, add_optab, target, target,
				   target, 0, OPTAB_LIB_WIDEN);
	      if (temp != target)
		emit_move_insn (target, temp);

	      do_pending_stack_adjust ();
	      emit_label (label);
	      goto done;
	    }
	}

      /* If we are about to do some arithmetic to correct for an
	 unsigned operand, do it in a pseudo-register.  */

      if (GET_MODE (to) != fmode
	  || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
	target = gen_reg_rtx (fmode);

      /* Convert as signed integer to floating.  */
      expand_float (target, from, 0);

      /* If FROM is negative (and therefore TO is negative),
	 correct its value by 2**bitwidth.  */

      do_pending_stack_adjust ();
      emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
			       0, label);

      
      real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
      temp = expand_binop (fmode, add_optab, target,
			   CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
			   target, 0, OPTAB_LIB_WIDEN);
      if (temp != target)
	emit_move_insn (target, temp);

      do_pending_stack_adjust ();
      emit_label (label);
      goto done;
    }

  /* No hardware instruction available; call a library routine to convert from
     SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode.  */
    {
      rtx libfcn;
      rtx insns;
      rtx value;

      to = protect_from_queue (to, 1);
      from = protect_from_queue (from, 0);

      if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
	from = convert_to_mode (SImode, from, unsignedp);

      if (flag_force_mem)
	from = force_not_mem (from);

      if (GET_MODE (to) == SFmode)
	{
	  if (GET_MODE (from) == SImode)
	    libfcn = floatsisf_libfunc;
	  else if (GET_MODE (from) == DImode)
	    libfcn = floatdisf_libfunc;
	  else if (GET_MODE (from) == TImode)
	    libfcn = floattisf_libfunc;
	  else
	    abort ();
	}
      else if (GET_MODE (to) == DFmode)
	{
	  if (GET_MODE (from) == SImode)
	    libfcn = floatsidf_libfunc;
	  else if (GET_MODE (from) == DImode)
	    libfcn = floatdidf_libfunc;
	  else if (GET_MODE (from) == TImode)
	    libfcn = floattidf_libfunc;
	  else
	    abort ();
	}
      else if (GET_MODE (to) == XFmode)
	{
	  if (GET_MODE (from) == SImode)
	    libfcn = floatsixf_libfunc;
	  else if (GET_MODE (from) == DImode)
	    libfcn = floatdixf_libfunc;
	  else if (GET_MODE (from) == TImode)
	    libfcn = floattixf_libfunc;
	  else
	    abort ();
	}
      else if (GET_MODE (to) == TFmode)
	{
	  if (GET_MODE (from) == SImode)
	    libfcn = floatsitf_libfunc;
	  else if (GET_MODE (from) == DImode)
	    libfcn = floatditf_libfunc;
	  else if (GET_MODE (from) == TImode)
	    libfcn = floattitf_libfunc;
	  else
	    abort ();
	}
      else
	abort ();

      start_sequence ();

      value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
				       GET_MODE (to), 1, from,
				       GET_MODE (from));
      insns = get_insns ();
      end_sequence ();

      emit_libcall_block (insns, target, value,
			  gen_rtx_FLOAT (GET_MODE (to), from));
    }

 done:

  /* Copy result to requested destination
     if we have been computing in a temp location.  */

  if (target != to)
    {
      if (GET_MODE (target) == GET_MODE (to))
	emit_move_insn (to, target);
      else
	convert_move (to, target, 0);
    }
}

/* expand_fix: generate code to convert FROM to fixed point
   and store in TO.  FROM must be floating point.  */

static rtx
ftruncify (x)
     rtx x;
{
  rtx temp = gen_reg_rtx (GET_MODE (x));
  return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
}

void
expand_fix (to, from, unsignedp)
     rtx to, from;
     int unsignedp;
{
  enum insn_code icode;
  rtx target = to;
  enum machine_mode fmode, imode;
  int must_trunc = 0;
  rtx libfcn = 0;

  /* We first try to find a pair of modes, one real and one integer, at
     least as wide as FROM and TO, respectively, in which we can open-code
     this conversion.  If the integer mode is wider than the mode of TO,
     we can do the conversion either signed or unsigned.  */

  for (fmode = GET_MODE (from); fmode != VOIDmode;
       fmode = GET_MODE_WIDER_MODE (fmode))
    for (imode = GET_MODE (to); imode != VOIDmode;
	 imode = GET_MODE_WIDER_MODE (imode))
      {
	int doing_unsigned = unsignedp;

	icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
	if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
	  icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;

	if (icode != CODE_FOR_nothing)
	  {
	    to = protect_from_queue (to, 1);
	    from = protect_from_queue (from, 0);

	    if (fmode != GET_MODE (from))
	      from = convert_to_mode (fmode, from, 0);

	    if (must_trunc)
	      from = ftruncify (from);

	    if (imode != GET_MODE (to))
	      target = gen_reg_rtx (imode);

	    emit_unop_insn (icode, target, from,
			    doing_unsigned ? UNSIGNED_FIX : FIX);
	    if (target != to)
	      convert_move (to, target, unsignedp);
	    return;
	  }
      }

  /* For an unsigned conversion, there is one more way to do it.
     If we have a signed conversion, we generate code that compares
     the real value to the largest representable positive number.  If if
     is smaller, the conversion is done normally.  Otherwise, subtract
     one plus the highest signed number, convert, and add it back.

     We only need to check all real modes, since we know we didn't find
     anything with a wider integer mode.  */

  if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
    for (fmode = GET_MODE (from); fmode != VOIDmode;
	 fmode = GET_MODE_WIDER_MODE (fmode))
      /* Make sure we won't lose significant bits doing this.  */
      if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
	  && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
					    &must_trunc))
	{
	  int bitsize;
	  REAL_VALUE_TYPE offset;
	  rtx limit, lab1, lab2, insn;

	  bitsize = GET_MODE_BITSIZE (GET_MODE (to));
	  real_2expN (&offset, bitsize - 1);
	  limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
	  lab1 = gen_label_rtx ();
	  lab2 = gen_label_rtx ();

	  emit_queue ();
	  to = protect_from_queue (to, 1);
	  from = protect_from_queue (from, 0);

	  if (flag_force_mem)
	    from = force_not_mem (from);

	  if (fmode != GET_MODE (from))
	    from = convert_to_mode (fmode, from, 0);

	  /* See if we need to do the subtraction.  */
	  do_pending_stack_adjust ();
	  emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
				   0, lab1);

	  /* If not, do the signed "fix" and branch around fixup code.  */
	  expand_fix (to, from, 0);
	  emit_jump_insn (gen_jump (lab2));
	  emit_barrier ();

	  /* Otherwise, subtract 2**(N-1), convert to signed number,
	     then add 2**(N-1).  Do the addition using XOR since this
	     will often generate better code.  */
	  emit_label (lab1);
	  target = expand_binop (GET_MODE (from), sub_optab, from, limit,
				 NULL_RTX, 0, OPTAB_LIB_WIDEN);
	  expand_fix (to, target, 0);
	  target = expand_binop (GET_MODE (to), xor_optab, to,
				 gen_int_mode
				 ((HOST_WIDE_INT) 1 << (bitsize - 1),
				  GET_MODE (to)),
				 to, 1, OPTAB_LIB_WIDEN);

	  if (target != to)
	    emit_move_insn (to, target);

	  emit_label (lab2);

	  if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
	      != CODE_FOR_nothing)
	    {
	      /* Make a place for a REG_NOTE and add it.  */
	      insn = emit_move_insn (to, to);
	      set_unique_reg_note (insn,
	                           REG_EQUAL,
				   gen_rtx_fmt_e (UNSIGNED_FIX,
						  GET_MODE (to),
						  copy_rtx (from)));
	    }

	  return;
	}

  /* We can't do it with an insn, so use a library call.  But first ensure
     that the mode of TO is at least as wide as SImode, since those are the
     only library calls we know about.  */

  if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
    {
      target = gen_reg_rtx (SImode);

      expand_fix (target, from, unsignedp);
    }
  else if (GET_MODE (from) == SFmode)
    {
      if (GET_MODE (to) == SImode)
	libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
      else if (GET_MODE (to) == DImode)
	libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
      else if (GET_MODE (to) == TImode)
	libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
      else
	abort ();
    }
  else if (GET_MODE (from) == DFmode)
    {
      if (GET_MODE (to) == SImode)
	libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
      else if (GET_MODE (to) == DImode)
	libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
      else if (GET_MODE (to) == TImode)
	libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
      else
	abort ();
    }
  else if (GET_MODE (from) == XFmode)
    {
      if (GET_MODE (to) == SImode)
	libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
      else if (GET_MODE (to) == DImode)
	libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
      else if (GET_MODE (to) == TImode)
	libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
      else
	abort ();
    }
  else if (GET_MODE (from) == TFmode)
    {
      if (GET_MODE (to) == SImode)
	libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
      else if (GET_MODE (to) == DImode)
	libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
      else if (GET_MODE (to) == TImode)
	libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
      else
	abort ();
    }
  else
    abort ();

  if (libfcn)
    {
      rtx insns;
      rtx value;

      to = protect_from_queue (to, 1);
      from = protect_from_queue (from, 0);

      if (flag_force_mem)
	from = force_not_mem (from);

      start_sequence ();

      value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
				       GET_MODE (to), 1, from,
				       GET_MODE (from));
      insns = get_insns ();
      end_sequence ();

      emit_libcall_block (insns, target, value,
			  gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
					 GET_MODE (to), from));
    }
      
  if (target != to)
    {
      if (GET_MODE (to) == GET_MODE (target))
        emit_move_insn (to, target);
      else
        convert_move (to, target, 0);
    }
}

/* Report whether we have an instruction to perform the operation
   specified by CODE on operands of mode MODE.  */
int
have_insn_for (code, mode)
     enum rtx_code code;
     enum machine_mode mode;
{
  return (code_to_optab[(int) code] != 0
	  && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
	      != CODE_FOR_nothing));
}

/* Create a blank optab.  */
static optab
new_optab ()
{
  int i;
  optab op = (optab) ggc_alloc (sizeof (struct optab));
  for (i = 0; i < NUM_MACHINE_MODES; i++)
    {
      op->handlers[i].insn_code = CODE_FOR_nothing;
      op->handlers[i].libfunc = 0;
    }

  return op;
}

/* Same, but fill in its code as CODE, and write it into the
   code_to_optab table.  */
static inline optab
init_optab (code)
     enum rtx_code code;
{
  optab op = new_optab ();
  op->code = code;
  code_to_optab[(int) code] = op;
  return op;
}

/* Same, but fill in its code as CODE, and do _not_ write it into
   the code_to_optab table.  */
static inline optab
init_optabv (code)
     enum rtx_code code;
{
  optab op = new_optab ();
  op->code = code;
  return op;
}

/* Initialize the libfunc fields of an entire group of entries in some
   optab.  Each entry is set equal to a string consisting of a leading
   pair of underscores followed by a generic operation name followed by
   a mode name (downshifted to lower case) followed by a single character
   representing the number of operands for the given operation (which is
   usually one of the characters '2', '3', or '4').

   OPTABLE is the table in which libfunc fields are to be initialized.
   FIRST_MODE is the first machine mode index in the given optab to
     initialize.
   LAST_MODE is the last machine mode index in the given optab to
     initialize.
   OPNAME is the generic (string) name of the operation.
   SUFFIX is the character which specifies the number of operands for
     the given generic operation.
*/

static void
init_libfuncs (optable, first_mode, last_mode, opname, suffix)
     optab optable;
     int first_mode;
     int last_mode;
     const char *opname;
     int suffix;
{
  int mode;
  unsigned opname_len = strlen (opname);

  for (mode = first_mode; (int) mode <= (int) last_mode;
       mode = (enum machine_mode) ((int) mode + 1))
    {
      const char *mname = GET_MODE_NAME (mode);
      unsigned mname_len = strlen (mname);
      char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
      char *p;
      const char *q;

      p = libfunc_name;
      *p++ = '_';
      *p++ = '_';
      for (q = opname; *q; )
	*p++ = *q++;
      for (q = mname; *q; q++)
	*p++ = TOLOWER (*q);
      *p++ = suffix;
      *p = '\0';

      optable->handlers[(int) mode].libfunc
	= gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
						       p - libfunc_name));
    }
}

/* Initialize the libfunc fields of an entire group of entries in some
   optab which correspond to all integer mode operations.  The parameters
   have the same meaning as similarly named ones for the `init_libfuncs'
   routine.  (See above).  */

static void
init_integral_libfuncs (optable, opname, suffix)
     optab optable;
     const char *opname;
     int suffix;
{
  init_libfuncs (optable, SImode, TImode, opname, suffix);
}

/* Initialize the libfunc fields of an entire group of entries in some
   optab which correspond to all real mode operations.  The parameters
   have the same meaning as similarly named ones for the `init_libfuncs'
   routine.  (See above).  */

static void
init_floating_libfuncs (optable, opname, suffix)
     optab optable;
     const char *opname;
     int suffix;
{
  init_libfuncs (optable, SFmode, TFmode, opname, suffix);
}

rtx
init_one_libfunc (name)
     const char *name;
{
  /* Create a FUNCTION_DECL that can be passed to
     targetm.encode_section_info.  */
  /* ??? We don't have any type information except for this is
     a function.  Pretend this is "int foo()".  */
  tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
			  build_function_type (integer_type_node, NULL_TREE));
  DECL_ARTIFICIAL (decl) = 1;
  DECL_EXTERNAL (decl) = 1;
  TREE_PUBLIC (decl) = 1;

  /* Return the symbol_ref from the mem rtx.  */
  return XEXP (DECL_RTL (decl), 0);
}

/* Call this once to initialize the contents of the optabs
   appropriately for the current target machine.  */

void
init_optabs ()
{
  unsigned int i, j, k;

  /* Start by initializing all tables to contain CODE_FOR_nothing.  */

  for (i = 0; i < ARRAY_SIZE (fixtab); i++)
    for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
      for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
	fixtab[i][j][k] = CODE_FOR_nothing;

  for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
    for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
      for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
	fixtrunctab[i][j][k] = CODE_FOR_nothing;

  for (i = 0; i < ARRAY_SIZE (floattab); i++)
    for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
      for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
	floattab[i][j][k] = CODE_FOR_nothing;

  for (i = 0; i < ARRAY_SIZE (extendtab); i++)
    for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
      for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
	extendtab[i][j][k] = CODE_FOR_nothing;

  for (i = 0; i < NUM_RTX_CODE; i++)
    setcc_gen_code[i] = CODE_FOR_nothing;

#ifdef HAVE_conditional_move
  for (i = 0; i < NUM_MACHINE_MODES; i++)
    movcc_gen_code[i] = CODE_FOR_nothing;
#endif

  add_optab = init_optab (PLUS);
  addv_optab = init_optabv (PLUS);
  sub_optab = init_optab (MINUS);
  subv_optab = init_optabv (MINUS);
  smul_optab = init_optab (MULT);
  smulv_optab = init_optabv (MULT);
  smul_highpart_optab = init_optab (UNKNOWN);
  umul_highpart_optab = init_optab (UNKNOWN);
  smul_widen_optab = init_optab (UNKNOWN);
  umul_widen_optab = init_optab (UNKNOWN);
  sdiv_optab = init_optab (DIV);
  sdivv_optab = init_optabv (DIV);
  sdivmod_optab = init_optab (UNKNOWN);
  udiv_optab = init_optab (UDIV);
  udivmod_optab = init_optab (UNKNOWN);
  smod_optab = init_optab (MOD);
  umod_optab = init_optab (UMOD);
  ftrunc_optab = init_optab (UNKNOWN);
  and_optab = init_optab (AND);
  ior_optab = init_optab (IOR);
  xor_optab = init_optab (XOR);
  ashl_optab = init_optab (ASHIFT);
  ashr_optab = init_optab (ASHIFTRT);
  lshr_optab = init_optab (LSHIFTRT);
  rotl_optab = init_optab (ROTATE);
  rotr_optab = init_optab (ROTATERT);
  smin_optab = init_optab (SMIN);
  smax_optab = init_optab (SMAX);
  umin_optab = init_optab (UMIN);
  umax_optab = init_optab (UMAX);

  /* These three have codes assigned exclusively for the sake of
     have_insn_for.  */
  mov_optab = init_optab (SET);
  movstrict_optab = init_optab (STRICT_LOW_PART);
  cmp_optab = init_optab (COMPARE);

  ucmp_optab = init_optab (UNKNOWN);
  tst_optab = init_optab (UNKNOWN);
  neg_optab = init_optab (NEG);
  negv_optab = init_optabv (NEG);
  abs_optab = init_optab (ABS);
  absv_optab = init_optabv (ABS);
  one_cmpl_optab = init_optab (NOT);
  ffs_optab = init_optab (FFS);
  sqrt_optab = init_optab (SQRT);
  sin_optab = init_optab (UNKNOWN);
  cos_optab = init_optab (UNKNOWN);
  exp_optab = init_optab (UNKNOWN);
  log_optab = init_optab (UNKNOWN);
  strlen_optab = init_optab (UNKNOWN);
  cbranch_optab = init_optab (UNKNOWN);
  cmov_optab = init_optab (UNKNOWN);
  cstore_optab = init_optab (UNKNOWN);
  push_optab = init_optab (UNKNOWN);

  for (i = 0; i < NUM_MACHINE_MODES; i++)
    {
      movstr_optab[i] = CODE_FOR_nothing;
      clrstr_optab[i] = CODE_FOR_nothing;

#ifdef HAVE_SECONDARY_RELOADS
      reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
#endif
    }

  /* Fill in the optabs with the insns we support.  */
  init_all_optabs ();

#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
  /* This flag says the same insns that convert to a signed fixnum
     also convert validly to an unsigned one.  */
  for (i = 0; i < NUM_MACHINE_MODES; i++)
    for (j = 0; j < NUM_MACHINE_MODES; j++)
      fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
#endif

  /* Initialize the optabs with the names of the library functions.  */
  init_integral_libfuncs (add_optab, "add", '3');
  init_floating_libfuncs (add_optab, "add", '3');
  init_integral_libfuncs (addv_optab, "addv", '3');
  init_floating_libfuncs (addv_optab, "add", '3');
  init_integral_libfuncs (sub_optab, "sub", '3');
  init_floating_libfuncs (sub_optab, "sub", '3');
  init_integral_libfuncs (subv_optab, "subv", '3');
  init_floating_libfuncs (subv_optab, "sub", '3');
  init_integral_libfuncs (smul_optab, "mul", '3');
  init_floating_libfuncs (smul_optab, "mul", '3');
  init_integral_libfuncs (smulv_optab, "mulv", '3');
  init_floating_libfuncs (smulv_optab, "mul", '3');
  init_integral_libfuncs (sdiv_optab, "div", '3');
  init_floating_libfuncs (sdiv_optab, "div", '3');
  init_integral_libfuncs (sdivv_optab, "divv", '3');
  init_integral_libfuncs (udiv_optab, "udiv", '3');
  init_integral_libfuncs (sdivmod_optab, "divmod", '4');
  init_integral_libfuncs (udivmod_optab, "udivmod", '4');
  init_integral_libfuncs (smod_optab, "mod", '3');
  init_integral_libfuncs (umod_optab, "umod", '3');
  init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
  init_integral_libfuncs (and_optab, "and", '3');
  init_integral_libfuncs (ior_optab, "ior", '3');
  init_integral_libfuncs (xor_optab, "xor", '3');
  init_integral_libfuncs (ashl_optab, "ashl", '3');
  init_integral_libfuncs (ashr_optab, "ashr", '3');
  init_integral_libfuncs (lshr_optab, "lshr", '3');
  init_integral_libfuncs (smin_optab, "min", '3');
  init_floating_libfuncs (smin_optab, "min", '3');
  init_integral_libfuncs (smax_optab, "max", '3');
  init_floating_libfuncs (smax_optab, "max", '3');
  init_integral_libfuncs (umin_optab, "umin", '3');
  init_integral_libfuncs (umax_optab, "umax", '3');
  init_integral_libfuncs (neg_optab, "neg", '2');
  init_floating_libfuncs (neg_optab, "neg", '2');
  init_integral_libfuncs (negv_optab, "negv", '2');
  init_floating_libfuncs (negv_optab, "neg", '2');
  init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
  init_integral_libfuncs (ffs_optab, "ffs", '2');

  /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
  init_integral_libfuncs (cmp_optab, "cmp", '2');
  init_integral_libfuncs (ucmp_optab, "ucmp", '2');
  init_floating_libfuncs (cmp_optab, "cmp", '2');

#ifdef MULSI3_LIBCALL
  smul_optab->handlers[(int) SImode].libfunc
    = init_one_libfunc (MULSI3_LIBCALL);
#endif
#ifdef MULDI3_LIBCALL
  smul_optab->handlers[(int) DImode].libfunc
    = init_one_libfunc (MULDI3_LIBCALL);
#endif

#ifdef DIVSI3_LIBCALL
  sdiv_optab->handlers[(int) SImode].libfunc
    = init_one_libfunc (DIVSI3_LIBCALL);
#endif
#ifdef DIVDI3_LIBCALL
  sdiv_optab->handlers[(int) DImode].libfunc
    = init_one_libfunc (DIVDI3_LIBCALL);
#endif

#ifdef UDIVSI3_LIBCALL
  udiv_optab->handlers[(int) SImode].libfunc
    = init_one_libfunc (UDIVSI3_LIBCALL);
#endif
#ifdef UDIVDI3_LIBCALL
  udiv_optab->handlers[(int) DImode].libfunc
    = init_one_libfunc (UDIVDI3_LIBCALL);
#endif

#ifdef MODSI3_LIBCALL
  smod_optab->handlers[(int) SImode].libfunc
    = init_one_libfunc (MODSI3_LIBCALL);
#endif
#ifdef MODDI3_LIBCALL
  smod_optab->handlers[(int) DImode].libfunc
    = init_one_libfunc (MODDI3_LIBCALL);
#endif

#ifdef UMODSI3_LIBCALL
  umod_optab->handlers[(int) SImode].libfunc
    = init_one_libfunc (UMODSI3_LIBCALL);
#endif
#ifdef UMODDI3_LIBCALL
  umod_optab->handlers[(int) DImode].libfunc
    = init_one_libfunc (UMODDI3_LIBCALL);
#endif

  /* Use cabs for DC complex abs, since systems generally have cabs.
     Don't define any libcall for SCmode, so that cabs will be used.  */
  abs_optab->handlers[(int) DCmode].libfunc
    = init_one_libfunc ("cabs");

  /* The ffs function operates on `int'.  */
  ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
    = init_one_libfunc ("ffs");

  extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
  extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
  extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
  extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
  extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");

  truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
  truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
  trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
  truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
  trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");

  abort_libfunc = init_one_libfunc ("abort");
  memcpy_libfunc = init_one_libfunc ("memcpy");
  memmove_libfunc = init_one_libfunc ("memmove");
  bcopy_libfunc = init_one_libfunc ("bcopy");
  memcmp_libfunc = init_one_libfunc ("memcmp");
  bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
  memset_libfunc = init_one_libfunc ("memset");
  bzero_libfunc = init_one_libfunc ("bzero");

  unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
					    ? "_Unwind_SjLj_Resume"
					    : "_Unwind_Resume");
#ifndef DONT_USE_BUILTIN_SETJMP
  setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
  longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
#else
  setjmp_libfunc = init_one_libfunc ("setjmp");
  longjmp_libfunc = init_one_libfunc ("longjmp");
#endif
  unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
  unwind_sjlj_unregister_libfunc
    = init_one_libfunc ("_Unwind_SjLj_Unregister");

  eqhf2_libfunc = init_one_libfunc ("__eqhf2");
  nehf2_libfunc = init_one_libfunc ("__nehf2");
  gthf2_libfunc = init_one_libfunc ("__gthf2");
  gehf2_libfunc = init_one_libfunc ("__gehf2");
  lthf2_libfunc = init_one_libfunc ("__lthf2");
  lehf2_libfunc = init_one_libfunc ("__lehf2");
  unordhf2_libfunc = init_one_libfunc ("__unordhf2");

  eqsf2_libfunc = init_one_libfunc ("__eqsf2");
  nesf2_libfunc = init_one_libfunc ("__nesf2");
  gtsf2_libfunc = init_one_libfunc ("__gtsf2");
  gesf2_libfunc = init_one_libfunc ("__gesf2");
  ltsf2_libfunc = init_one_libfunc ("__ltsf2");
  lesf2_libfunc = init_one_libfunc ("__lesf2");
  unordsf2_libfunc = init_one_libfunc ("__unordsf2");

  eqdf2_libfunc = init_one_libfunc ("__eqdf2");
  nedf2_libfunc = init_one_libfunc ("__nedf2");
  gtdf2_libfunc = init_one_libfunc ("__gtdf2");
  gedf2_libfunc = init_one_libfunc ("__gedf2");
  ltdf2_libfunc = init_one_libfunc ("__ltdf2");
  ledf2_libfunc = init_one_libfunc ("__ledf2");
  unorddf2_libfunc = init_one_libfunc ("__unorddf2");

  eqxf2_libfunc = init_one_libfunc ("__eqxf2");
  nexf2_libfunc = init_one_libfunc ("__nexf2");
  gtxf2_libfunc = init_one_libfunc ("__gtxf2");
  gexf2_libfunc = init_one_libfunc ("__gexf2");
  ltxf2_libfunc = init_one_libfunc ("__ltxf2");
  lexf2_libfunc = init_one_libfunc ("__lexf2");
  unordxf2_libfunc = init_one_libfunc ("__unordxf2");

  eqtf2_libfunc = init_one_libfunc ("__eqtf2");
  netf2_libfunc = init_one_libfunc ("__netf2");
  gttf2_libfunc = init_one_libfunc ("__gttf2");
  getf2_libfunc = init_one_libfunc ("__getf2");
  lttf2_libfunc = init_one_libfunc ("__lttf2");
  letf2_libfunc = init_one_libfunc ("__letf2");
  unordtf2_libfunc = init_one_libfunc ("__unordtf2");

  floatsisf_libfunc = init_one_libfunc ("__floatsisf");
  floatdisf_libfunc = init_one_libfunc ("__floatdisf");
  floattisf_libfunc = init_one_libfunc ("__floattisf");

  floatsidf_libfunc = init_one_libfunc ("__floatsidf");
  floatdidf_libfunc = init_one_libfunc ("__floatdidf");
  floattidf_libfunc = init_one_libfunc ("__floattidf");

  floatsixf_libfunc = init_one_libfunc ("__floatsixf");
  floatdixf_libfunc = init_one_libfunc ("__floatdixf");
  floattixf_libfunc = init_one_libfunc ("__floattixf");

  floatsitf_libfunc = init_one_libfunc ("__floatsitf");
  floatditf_libfunc = init_one_libfunc ("__floatditf");
  floattitf_libfunc = init_one_libfunc ("__floattitf");

  fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
  fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
  fixsfti_libfunc = init_one_libfunc ("__fixsfti");

  fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
  fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
  fixdfti_libfunc = init_one_libfunc ("__fixdfti");

  fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
  fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
  fixxfti_libfunc = init_one_libfunc ("__fixxfti");

  fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
  fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
  fixtfti_libfunc = init_one_libfunc ("__fixtfti");

  fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
  fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
  fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");

  fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
  fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
  fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");

  fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
  fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
  fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");

  fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
  fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
  fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");

  /* For function entry/exit instrumentation.  */
  profile_function_entry_libfunc
    = init_one_libfunc ("__cyg_profile_func_enter");
  profile_function_exit_libfunc
    = init_one_libfunc ("__cyg_profile_func_exit");

  if (HAVE_conditional_trap)
    trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);

#ifdef INIT_TARGET_OPTABS
  /* Allow the target to add more libcalls or rename some, etc.  */
  INIT_TARGET_OPTABS;
#endif
}

/* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
   CODE.  Return 0 on failure.  */

rtx
gen_cond_trap (code, op1, op2, tcode)
     enum rtx_code code ATTRIBUTE_UNUSED;
     rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
{
  enum machine_mode mode = GET_MODE (op1);
  enum insn_code icode;
  rtx insn;

  if (!HAVE_conditional_trap)
    return 0;

  if (mode == VOIDmode)
    return 0;

  icode = cmp_optab->handlers[(int) mode].insn_code;
  if (icode == CODE_FOR_nothing)
    return 0;

  start_sequence ();
  op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
  op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
  if (!op1 || !op2)
    {
      end_sequence ();
      return 0;
    }
  emit_insn (GEN_FCN (icode) (op1, op2));

  PUT_CODE (trap_rtx, code);
  insn = gen_conditional_trap (trap_rtx, tcode);
  if (insn)
    {
      emit_insn (insn);
      insn = get_insns ();
    }
  end_sequence ();

  return insn;
}

#include "gt-optabs.h"
