/* Subroutines used for code generation on the DEC Alpha.
   Copyright (C) 1992-2021 Free Software Foundation, Inc.
   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)

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 3, 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 COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */


#define IN_TARGET_CODE 1

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "stringpool.h"
#include "attribs.h"
#include "memmodel.h"
#include "gimple.h"
#include "df.h"
#include "predict.h"
#include "tm_p.h"
#include "ssa.h"
#include "expmed.h"
#include "optabs.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "diagnostic-core.h"
#include "alias.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "calls.h"
#include "varasm.h"
#include "output.h"
#include "insn-attr.h"
#include "explow.h"
#include "expr.h"
#include "reload.h"
#include "except.h"
#include "common/common-target.h"
#include "debug.h"
#include "langhooks.h"
#include "cfgrtl.h"
#include "tree-pass.h"
#include "context.h"
#include "gimple-iterator.h"
#include "gimplify.h"
#include "tree-stdarg.h"
#include "tm-constrs.h"
#include "libfuncs.h"
#include "builtins.h"
#include "rtl-iter.h"
#include "flags.h"
#include "opts.h"

/* This file should be included last.  */
#include "target-def.h"

/* Specify which cpu to schedule for.  */
enum processor_type alpha_tune;

/* Which cpu we're generating code for.  */
enum processor_type alpha_cpu;

static const char * const alpha_cpu_name[] =
{
  "ev4", "ev5", "ev6"
};

/* Specify how accurate floating-point traps need to be.  */

enum alpha_trap_precision alpha_tp;

/* Specify the floating-point rounding mode.  */

enum alpha_fp_rounding_mode alpha_fprm;

/* Specify which things cause traps.  */

enum alpha_fp_trap_mode alpha_fptm;

/* Nonzero if inside of a function, because the Alpha asm can't
   handle .files inside of functions.  */

static int inside_function = FALSE;

/* The number of cycles of latency we should assume on memory reads.  */

static int alpha_memory_latency = 3;

/* Whether the function needs the GP.  */

static int alpha_function_needs_gp;

/* The assembler name of the current function.  */

static const char *alpha_fnname;

/* The next explicit relocation sequence number.  */
extern GTY(()) int alpha_next_sequence_number;
int alpha_next_sequence_number = 1;

/* The literal and gpdisp sequence numbers for this insn, as printed
   by %# and %* respectively.  */
extern GTY(()) int alpha_this_literal_sequence_number;
extern GTY(()) int alpha_this_gpdisp_sequence_number;
int alpha_this_literal_sequence_number;
int alpha_this_gpdisp_sequence_number;

/* Costs of various operations on the different architectures.  */

struct alpha_rtx_cost_data
{
  unsigned char fp_add;
  unsigned char fp_mult;
  unsigned char fp_div_sf;
  unsigned char fp_div_df;
  unsigned char int_mult_si;
  unsigned char int_mult_di;
  unsigned char int_shift;
  unsigned char int_cmov;
  unsigned short int_div;
};

static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
{
  { /* EV4 */
    COSTS_N_INSNS (6),		/* fp_add */
    COSTS_N_INSNS (6),		/* fp_mult */
    COSTS_N_INSNS (34),		/* fp_div_sf */
    COSTS_N_INSNS (63),		/* fp_div_df */
    COSTS_N_INSNS (23),		/* int_mult_si */
    COSTS_N_INSNS (23),		/* int_mult_di */
    COSTS_N_INSNS (2),		/* int_shift */
    COSTS_N_INSNS (2),		/* int_cmov */
    COSTS_N_INSNS (97),		/* int_div */
  },
  { /* EV5 */
    COSTS_N_INSNS (4),		/* fp_add */
    COSTS_N_INSNS (4),		/* fp_mult */
    COSTS_N_INSNS (15),		/* fp_div_sf */
    COSTS_N_INSNS (22),		/* fp_div_df */
    COSTS_N_INSNS (8),		/* int_mult_si */
    COSTS_N_INSNS (12),		/* int_mult_di */
    COSTS_N_INSNS (1) + 1,	/* int_shift */
    COSTS_N_INSNS (1),		/* int_cmov */
    COSTS_N_INSNS (83),		/* int_div */
  },
  { /* EV6 */
    COSTS_N_INSNS (4),		/* fp_add */
    COSTS_N_INSNS (4),		/* fp_mult */
    COSTS_N_INSNS (12),		/* fp_div_sf */
    COSTS_N_INSNS (15),		/* fp_div_df */
    COSTS_N_INSNS (7),		/* int_mult_si */
    COSTS_N_INSNS (7),		/* int_mult_di */
    COSTS_N_INSNS (1),		/* int_shift */
    COSTS_N_INSNS (2),		/* int_cmov */
    COSTS_N_INSNS (86),		/* int_div */
  },
};

/* Similar but tuned for code size instead of execution latency.  The
   extra +N is fractional cost tuning based on latency.  It's used to
   encourage use of cheaper insns like shift, but only if there's just
   one of them.  */

static struct alpha_rtx_cost_data const alpha_rtx_cost_size =
{
  COSTS_N_INSNS (1),		/* fp_add */
  COSTS_N_INSNS (1),		/* fp_mult */
  COSTS_N_INSNS (1),		/* fp_div_sf */
  COSTS_N_INSNS (1) + 1,	/* fp_div_df */
  COSTS_N_INSNS (1) + 1,	/* int_mult_si */
  COSTS_N_INSNS (1) + 2,	/* int_mult_di */
  COSTS_N_INSNS (1),		/* int_shift */
  COSTS_N_INSNS (1),		/* int_cmov */
  COSTS_N_INSNS (6),		/* int_div */
};

/* Get the number of args of a function in one of two ways.  */
#if TARGET_ABI_OPEN_VMS
#define NUM_ARGS crtl->args.info.num_args
#else
#define NUM_ARGS crtl->args.info
#endif

#define REG_PV 27
#define REG_RA 26

/* Declarations of static functions.  */
static struct machine_function *alpha_init_machine_status (void);
static rtx alpha_emit_xfloating_compare (enum rtx_code *, rtx, rtx);
static void alpha_handle_trap_shadows (void);
static void alpha_align_insns (void);
static void alpha_override_options_after_change (void);

#if TARGET_ABI_OPEN_VMS
static void alpha_write_linkage (FILE *, const char *);
static bool vms_valid_pointer_mode (scalar_int_mode);
#else
#define vms_patch_builtins()  gcc_unreachable()
#endif

static unsigned int
rest_of_handle_trap_shadows (void)
{
  alpha_handle_trap_shadows ();
  return 0;
}

namespace {

const pass_data pass_data_handle_trap_shadows =
{
  RTL_PASS,
  "trap_shadows",			/* name */
  OPTGROUP_NONE,			/* optinfo_flags */
  TV_NONE,				/* tv_id */
  0,					/* properties_required */
  0,					/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
  TODO_df_finish,			/* todo_flags_finish */
};

class pass_handle_trap_shadows : public rtl_opt_pass
{
public:
  pass_handle_trap_shadows(gcc::context *ctxt)
    : rtl_opt_pass(pass_data_handle_trap_shadows, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
    {
      return alpha_tp != ALPHA_TP_PROG || flag_exceptions;
    }

  virtual unsigned int execute (function *)
    {
      return rest_of_handle_trap_shadows ();
    }

}; // class pass_handle_trap_shadows

} // anon namespace

rtl_opt_pass *
make_pass_handle_trap_shadows (gcc::context *ctxt)
{
  return new pass_handle_trap_shadows (ctxt);
}

static unsigned int
rest_of_align_insns (void)
{
  alpha_align_insns ();
  return 0;
}

namespace {

const pass_data pass_data_align_insns =
{
  RTL_PASS,
  "align_insns",			/* name */
  OPTGROUP_NONE,			/* optinfo_flags */
  TV_NONE,				/* tv_id */
  0,					/* properties_required */
  0,					/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
  TODO_df_finish,			/* todo_flags_finish */
};

class pass_align_insns : public rtl_opt_pass
{
public:
  pass_align_insns(gcc::context *ctxt)
    : rtl_opt_pass(pass_data_align_insns, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
    {
      /* Due to the number of extra trapb insns, don't bother fixing up
	 alignment when trap precision is instruction.  Moreover, we can
	 only do our job when sched2 is run.  */
      return ((alpha_tune == PROCESSOR_EV4
	       || alpha_tune == PROCESSOR_EV5)
	      && optimize && !optimize_size
	      && alpha_tp != ALPHA_TP_INSN
	      && flag_schedule_insns_after_reload);
    }

  virtual unsigned int execute (function *)
    {
      return rest_of_align_insns ();
    }

}; // class pass_align_insns

} // anon namespace

rtl_opt_pass *
make_pass_align_insns (gcc::context *ctxt)
{
  return new pass_align_insns (ctxt);
}

#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
/* Implement TARGET_MANGLE_TYPE.  */

static const char *
alpha_mangle_type (const_tree type)
{
  if (TYPE_MAIN_VARIANT (type) == long_double_type_node
      && TARGET_LONG_DOUBLE_128)
    return "g";

  /* For all other types, use normal C++ mangling.  */
  return NULL;
}
#endif

/* Parse target option strings.  */

static void
alpha_option_override (void)
{
  static const struct cpu_table {
    const char *const name;
    const enum processor_type processor;
    const int flags;
    const unsigned short line_size; /* in bytes */
    const unsigned short l1_size;   /* in kb.  */
    const unsigned short l2_size;   /* in kb.  */
  } cpu_table[] = {
    /* EV4/LCA45 had 8k L1 caches; EV45 had 16k L1 caches.
       EV4/EV45 had 128k to 16M 32-byte direct Bcache.  LCA45
       had 64k to 8M 8-byte direct Bcache.  */
    { "ev4",	PROCESSOR_EV4, 0, 32, 8, 8*1024 },
    { "21064",	PROCESSOR_EV4, 0, 32, 8, 8*1024 },
    { "ev45",	PROCESSOR_EV4, 0, 32, 16, 16*1024 },

    /* EV5 or EV56 had 8k 32 byte L1, 96k 32 or 64 byte L2,
       and 1M to 16M 64 byte L3 (not modeled).
       PCA56 had 16k 64-byte cache; PCA57 had 32k Icache.
       PCA56 had 8k 64-byte cache; PCA57 had 16k Dcache.  */
    { "ev5",	PROCESSOR_EV5, 0, 32, 8, 96 },
    { "21164",	PROCESSOR_EV5, 0, 32, 8, 96 },
    { "ev56",	PROCESSOR_EV5, MASK_BWX, 32, 8, 96 },
    { "21164a",	PROCESSOR_EV5, MASK_BWX, 32, 8, 96 },
    { "pca56",	PROCESSOR_EV5, MASK_BWX|MASK_MAX, 64, 16, 4*1024 },
    { "21164PC",PROCESSOR_EV5, MASK_BWX|MASK_MAX, 64, 16, 4*1024 },
    { "21164pc",PROCESSOR_EV5, MASK_BWX|MASK_MAX, 64, 16, 4*1024 },

    /* EV6 had 64k 64 byte L1, 1M to 16M Bcache.  */
    { "ev6",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX, 64, 64, 16*1024 },
    { "21264",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX, 64, 64, 16*1024 },
    { "ev67",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX,
      64, 64, 16*1024 },
    { "21264a",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX,
      64, 64, 16*1024 }
  };

  int const ct_size = ARRAY_SIZE (cpu_table);
  int line_size = 0, l1_size = 0, l2_size = 0;
  int i;

#ifdef SUBTARGET_OVERRIDE_OPTIONS
  SUBTARGET_OVERRIDE_OPTIONS;
#endif

  /* Default to full IEEE compliance mode for Go language.  */
  if (strcmp (lang_hooks.name, "GNU Go") == 0
      && !(target_flags_explicit & MASK_IEEE))
    target_flags |= MASK_IEEE;

  alpha_fprm = ALPHA_FPRM_NORM;
  alpha_tp = ALPHA_TP_PROG;
  alpha_fptm = ALPHA_FPTM_N;

  if (TARGET_IEEE)
    {
      alpha_tp = ALPHA_TP_INSN;
      alpha_fptm = ALPHA_FPTM_SU;
    }
  if (TARGET_IEEE_WITH_INEXACT)
    {
      alpha_tp = ALPHA_TP_INSN;
      alpha_fptm = ALPHA_FPTM_SUI;
    }

  if (alpha_tp_string)
    {
      if (! strcmp (alpha_tp_string, "p"))
	alpha_tp = ALPHA_TP_PROG;
      else if (! strcmp (alpha_tp_string, "f"))
	alpha_tp = ALPHA_TP_FUNC;
      else if (! strcmp (alpha_tp_string, "i"))
	alpha_tp = ALPHA_TP_INSN;
      else
	error ("bad value %qs for %<-mtrap-precision%> switch",
	       alpha_tp_string);
    }

  if (alpha_fprm_string)
    {
      if (! strcmp (alpha_fprm_string, "n"))
	alpha_fprm = ALPHA_FPRM_NORM;
      else if (! strcmp (alpha_fprm_string, "m"))
	alpha_fprm = ALPHA_FPRM_MINF;
      else if (! strcmp (alpha_fprm_string, "c"))
	alpha_fprm = ALPHA_FPRM_CHOP;
      else if (! strcmp (alpha_fprm_string,"d"))
	alpha_fprm = ALPHA_FPRM_DYN;
      else
	error ("bad value %qs for %<-mfp-rounding-mode%> switch",
	       alpha_fprm_string);
    }

  if (alpha_fptm_string)
    {
      if (strcmp (alpha_fptm_string, "n") == 0)
	alpha_fptm = ALPHA_FPTM_N;
      else if (strcmp (alpha_fptm_string, "u") == 0)
	alpha_fptm = ALPHA_FPTM_U;
      else if (strcmp (alpha_fptm_string, "su") == 0)
	alpha_fptm = ALPHA_FPTM_SU;
      else if (strcmp (alpha_fptm_string, "sui") == 0)
	alpha_fptm = ALPHA_FPTM_SUI;
      else
	error ("bad value %qs for %<-mfp-trap-mode%> switch",
	       alpha_fptm_string);
    }

  if (alpha_cpu_string)
    {
      for (i = 0; i < ct_size; i++)
	if (! strcmp (alpha_cpu_string, cpu_table [i].name))
	  {
	    alpha_tune = alpha_cpu = cpu_table[i].processor;
	    line_size = cpu_table[i].line_size;
	    l1_size = cpu_table[i].l1_size;
	    l2_size = cpu_table[i].l2_size;
	    target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX);
	    target_flags |= cpu_table[i].flags;
	    break;
	  }
      if (i == ct_size)
	error ("bad value %qs for %<-mcpu%> switch", alpha_cpu_string);
    }

  if (alpha_tune_string)
    {
      for (i = 0; i < ct_size; i++)
	if (! strcmp (alpha_tune_string, cpu_table [i].name))
	  {
	    alpha_tune = cpu_table[i].processor;
	    line_size = cpu_table[i].line_size;
	    l1_size = cpu_table[i].l1_size;
	    l2_size = cpu_table[i].l2_size;
	    break;
	  }
      if (i == ct_size)
	error ("bad value %qs for %<-mtune%> switch", alpha_tune_string);
    }

  if (line_size)
    SET_OPTION_IF_UNSET (&global_options, &global_options_set,
			 param_l1_cache_line_size, line_size);
  if (l1_size)
    SET_OPTION_IF_UNSET (&global_options, &global_options_set,
			 param_l1_cache_size, l1_size);
  if (l2_size)
    SET_OPTION_IF_UNSET (&global_options, &global_options_set,
			 param_l2_cache_size, l2_size);

  /* Do some sanity checks on the above options.  */

  if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
      && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6)
    {
      warning (0, "fp software completion requires %<-mtrap-precision=i%>");
      alpha_tp = ALPHA_TP_INSN;
    }

  if (alpha_cpu == PROCESSOR_EV6)
    {
      /* Except for EV6 pass 1 (not released), we always have precise
	 arithmetic traps.  Which means we can do software completion
	 without minding trap shadows.  */
      alpha_tp = ALPHA_TP_PROG;
    }

  if (TARGET_FLOAT_VAX)
    {
      if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
	{
	  warning (0, "rounding mode not supported for VAX floats");
	  alpha_fprm = ALPHA_FPRM_NORM;
	}
      if (alpha_fptm == ALPHA_FPTM_SUI)
	{
	  warning (0, "trap mode not supported for VAX floats");
	  alpha_fptm = ALPHA_FPTM_SU;
	}
      if (target_flags_explicit & MASK_LONG_DOUBLE_128)
	warning (0, "128-bit %<long double%> not supported for VAX floats");
      target_flags &= ~MASK_LONG_DOUBLE_128;
    }

  {
    char *end;
    int lat;

    if (!alpha_mlat_string)
      alpha_mlat_string = "L1";

    if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
	&& (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
      ;
    else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
	     && ISDIGIT ((unsigned char)alpha_mlat_string[1])
	     && alpha_mlat_string[2] == '\0')
      {
	static int const cache_latency[][4] =
	{
	  { 3, 30, -1 },	/* ev4 -- Bcache is a guess */
	  { 2, 12, 38 },	/* ev5 -- Bcache from PC164 LMbench numbers */
	  { 3, 12, 30 },	/* ev6 -- Bcache from DS20 LMbench.  */
	};

	lat = alpha_mlat_string[1] - '0';
	if (lat <= 0 || lat > 3 || cache_latency[alpha_tune][lat-1] == -1)
	  {
	    warning (0, "L%d cache latency unknown for %s",
		     lat, alpha_cpu_name[alpha_tune]);
	    lat = 3;
	  }
	else
	  lat = cache_latency[alpha_tune][lat-1];
      }
    else if (! strcmp (alpha_mlat_string, "main"))
      {
	/* Most current memories have about 370ns latency.  This is
	   a reasonable guess for a fast cpu.  */
	lat = 150;
      }
    else
      {
	warning (0, "bad value %qs for %<-mmemory-latency%>",
		 alpha_mlat_string);
	lat = 3;
      }

    alpha_memory_latency = lat;
  }

  /* Default the definition of "small data" to 8 bytes.  */
  if (!OPTION_SET_P (g_switch_value))
    g_switch_value = 8;

  /* Infer TARGET_SMALL_DATA from -fpic/-fPIC.  */
  if (flag_pic == 1)
    target_flags |= MASK_SMALL_DATA;
  else if (flag_pic == 2)
    target_flags &= ~MASK_SMALL_DATA;

  alpha_override_options_after_change ();

  /* Register variables and functions with the garbage collector.  */

  /* Set up function hooks.  */
  init_machine_status = alpha_init_machine_status;

  /* Tell the compiler when we're using VAX floating point.  */
  if (TARGET_FLOAT_VAX)
    {
      REAL_MODE_FORMAT (SFmode) = &vax_f_format;
      REAL_MODE_FORMAT (DFmode) = &vax_g_format;
      REAL_MODE_FORMAT (TFmode) = NULL;
    }

#ifdef TARGET_DEFAULT_LONG_DOUBLE_128
  if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
    target_flags |= MASK_LONG_DOUBLE_128;
#endif

}

/* Implement targetm.override_options_after_change.  */

static void
alpha_override_options_after_change (void)
{
  /* Align labels and loops for optimal branching.  */
  /* ??? Kludge these by not doing anything if we don't optimize.  */
  if (optimize > 0)
    {
      if (flag_align_loops && !str_align_loops)
	str_align_loops = "16";
      if (flag_align_jumps && !str_align_jumps)
	str_align_jumps = "16";
    }
  if (flag_align_functions && !str_align_functions)
    str_align_functions = "16";
}

/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */

int
zap_mask (HOST_WIDE_INT value)
{
  int i;

  for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
       i++, value >>= 8)
    if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
      return 0;

  return 1;
}

/* Return true if OP is valid for a particular TLS relocation.
   We are already guaranteed that OP is a CONST.  */

int
tls_symbolic_operand_1 (rtx op, int size, int unspec)
{
  op = XEXP (op, 0);

  if (GET_CODE (op) != UNSPEC || XINT (op, 1) != unspec)
    return 0;
  op = XVECEXP (op, 0, 0);

  if (GET_CODE (op) != SYMBOL_REF)
    return 0;

  switch (SYMBOL_REF_TLS_MODEL (op))
    {
    case TLS_MODEL_LOCAL_DYNAMIC:
      return unspec == UNSPEC_DTPREL && size == alpha_tls_size;
    case TLS_MODEL_INITIAL_EXEC:
      return unspec == UNSPEC_TPREL && size == 64;
    case TLS_MODEL_LOCAL_EXEC:
      return unspec == UNSPEC_TPREL && size == alpha_tls_size;
    default:
      gcc_unreachable ();
    }
}

/* Used by aligned_memory_operand and unaligned_memory_operand to
   resolve what reload is going to do with OP if it's a register.  */

rtx
resolve_reload_operand (rtx op)
{
  if (reload_in_progress)
    {
      rtx tmp = op;
      if (SUBREG_P (tmp))
	tmp = SUBREG_REG (tmp);
      if (REG_P (tmp)
	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
	{
	  op = reg_equiv_memory_loc (REGNO (tmp));
	  if (op == 0)
	    return 0;
	}
    }
  return op;
}

/* The scalar modes supported differs from the default check-what-c-supports
   version in that sometimes TFmode is available even when long double
   indicates only DFmode.  */

static bool
alpha_scalar_mode_supported_p (scalar_mode mode)
{
  switch (mode)
    {
    case E_QImode:
    case E_HImode:
    case E_SImode:
    case E_DImode:
    case E_TImode: /* via optabs.c */
      return true;

    case E_SFmode:
    case E_DFmode:
      return true;

    case E_TFmode:
      return TARGET_HAS_XFLOATING_LIBS;

    default:
      return false;
    }
}

/* Alpha implements a couple of integer vector mode operations when
   TARGET_MAX is enabled.  We do not check TARGET_MAX here, however,
   which allows the vectorizer to operate on e.g. move instructions,
   or when expand_vector_operations can do something useful.  */

static bool
alpha_vector_mode_supported_p (machine_mode mode)
{
  return mode == V8QImode || mode == V4HImode || mode == V2SImode;
}

/* Return the TLS model to use for SYMBOL.  */

static enum tls_model
tls_symbolic_operand_type (rtx symbol)
{
  enum tls_model model;

  if (GET_CODE (symbol) != SYMBOL_REF)
    return TLS_MODEL_NONE;
  model = SYMBOL_REF_TLS_MODEL (symbol);

  /* Local-exec with a 64-bit size is the same code as initial-exec.  */
  if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64)
    model = TLS_MODEL_INITIAL_EXEC;

  return model;
}

/* Return true if the function DECL will share the same GP as any
   function in the current unit of translation.  */

static bool
decl_has_samegp (const_tree decl)
{
  /* Functions that are not local can be overridden, and thus may
     not share the same gp.  */
  if (!(*targetm.binds_local_p) (decl))
    return false;

  /* If -msmall-data is in effect, assume that there is only one GP
     for the module, and so any local symbol has this property.  We
     need explicit relocations to be able to enforce this for symbols
     not defined in this unit of translation, however.  */
  if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA)
    return true;

  /* Functions that are not external are defined in this UoT.  */
  /* ??? Irritatingly, static functions not yet emitted are still
     marked "external".  Apply this to non-static functions only.  */
  return !TREE_PUBLIC (decl) || !DECL_EXTERNAL (decl);
}

/* Return true if EXP should be placed in the small data section.  */

static bool
alpha_in_small_data_p (const_tree exp)
{
  /* We want to merge strings, so we never consider them small data.  */
  if (TREE_CODE (exp) == STRING_CST)
    return false;

  /* Functions are never in the small data area.  Duh.  */
  if (TREE_CODE (exp) == FUNCTION_DECL)
    return false;

  /* COMMON symbols are never small data.  */
  if (TREE_CODE (exp) == VAR_DECL && DECL_COMMON (exp))
    return false;

  if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
    {
      const char *section = DECL_SECTION_NAME (exp);
      if (strcmp (section, ".sdata") == 0
	  || strcmp (section, ".sbss") == 0)
	return true;
    }
  else
    {
      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));

      /* If this is an incomplete type with size 0, then we can't put it
	 in sdata because it might be too big when completed.  */
      if (size > 0 && size <= g_switch_value)
	return true;
    }

  return false;
}

#if TARGET_ABI_OPEN_VMS
static bool
vms_valid_pointer_mode (scalar_int_mode mode)
{
  return (mode == SImode || mode == DImode);
}

static bool
alpha_linkage_symbol_p (const char *symname)
{
  int symlen = strlen (symname);

  if (symlen > 4)
    return strcmp (&symname [symlen - 4], "..lk") == 0;

  return false;
}

#define LINKAGE_SYMBOL_REF_P(X) \
  ((GET_CODE (X) == SYMBOL_REF   \
    && alpha_linkage_symbol_p (XSTR (X, 0))) \
   || (GET_CODE (X) == CONST                 \
       && GET_CODE (XEXP (X, 0)) == PLUS     \
       && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
       && alpha_linkage_symbol_p (XSTR (XEXP (XEXP (X, 0), 0), 0))))
#endif

/* legitimate_address_p recognizes an RTL expression that is a valid
   memory address for an instruction.  The MODE argument is the
   machine mode for the MEM expression that wants to use this address.

   For Alpha, we have either a constant address or the sum of a
   register and a constant address, or just a register.  For DImode,
   any of those forms can be surrounded with an AND that clear the
   low-order three bits; this is an "unaligned" access.  */

static bool
alpha_legitimate_address_p (machine_mode mode, rtx x, bool strict)
{
  /* If this is an ldq_u type address, discard the outer AND.  */
  if (mode == DImode
      && GET_CODE (x) == AND
      && CONST_INT_P (XEXP (x, 1))
      && INTVAL (XEXP (x, 1)) == -8)
    x = XEXP (x, 0);

  /* Discard non-paradoxical subregs.  */
  if (SUBREG_P (x)
      && (GET_MODE_SIZE (GET_MODE (x))
	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
    x = SUBREG_REG (x);

  /* Unadorned general registers are valid.  */
  if (REG_P (x)
      && (strict
	  ? STRICT_REG_OK_FOR_BASE_P (x)
	  : NONSTRICT_REG_OK_FOR_BASE_P (x)))
    return true;

  /* Constant addresses (i.e. +/- 32k) are valid.  */
  if (CONSTANT_ADDRESS_P (x))
    return true;

#if TARGET_ABI_OPEN_VMS
  if (LINKAGE_SYMBOL_REF_P (x))
    return true;
#endif

  /* Register plus a small constant offset is valid.  */
  if (GET_CODE (x) == PLUS)
    {
      rtx ofs = XEXP (x, 1);
      x = XEXP (x, 0);

      /* Discard non-paradoxical subregs.  */
      if (SUBREG_P (x)
          && (GET_MODE_SIZE (GET_MODE (x))
	      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
	x = SUBREG_REG (x);

      if (REG_P (x))
	{
	  if (! strict
	      && NONSTRICT_REG_OK_FP_BASE_P (x)
	      && CONST_INT_P (ofs))
	    return true;
	  if ((strict
	       ? STRICT_REG_OK_FOR_BASE_P (x)
	       : NONSTRICT_REG_OK_FOR_BASE_P (x))
	      && CONSTANT_ADDRESS_P (ofs))
	    return true;
	}
    }

  /* If we're managing explicit relocations, LO_SUM is valid, as are small
     data symbols.  Avoid explicit relocations of modes larger than word
     mode since i.e. $LC0+8($1) can fold around +/- 32k offset.  */
  else if (TARGET_EXPLICIT_RELOCS
	   && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
    {
      if (small_symbolic_operand (x, Pmode))
	return true;

      if (GET_CODE (x) == LO_SUM)
	{
	  rtx ofs = XEXP (x, 1);
	  x = XEXP (x, 0);

	  /* Discard non-paradoxical subregs.  */
	  if (SUBREG_P (x)
	      && (GET_MODE_SIZE (GET_MODE (x))
		  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
	    x = SUBREG_REG (x);

	  /* Must have a valid base register.  */
	  if (! (REG_P (x)
		 && (strict
		     ? STRICT_REG_OK_FOR_BASE_P (x)
		     : NONSTRICT_REG_OK_FOR_BASE_P (x))))
	    return false;

	  /* The symbol must be local.  */
	  if (local_symbolic_operand (ofs, Pmode)
	      || dtp32_symbolic_operand (ofs, Pmode)
	      || tp32_symbolic_operand (ofs, Pmode))
	    return true;
	}
    }

  return false;
}

/* Build the SYMBOL_REF for __tls_get_addr.  */

static GTY(()) rtx tls_get_addr_libfunc;

static rtx
get_tls_get_addr (void)
{
  if (!tls_get_addr_libfunc)
    tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
  return tls_get_addr_libfunc;
}

/* Try machine-dependent ways of modifying an illegitimate address
   to be legitimate.  If we find one, return the new, valid address.  */

static rtx
alpha_legitimize_address_1 (rtx x, rtx scratch, machine_mode mode)
{
  HOST_WIDE_INT addend;

  /* If the address is (plus reg const_int) and the CONST_INT is not a
     valid offset, compute the high part of the constant and add it to
     the register.  Then our address is (plus temp low-part-const).  */
  if (GET_CODE (x) == PLUS
      && REG_P (XEXP (x, 0))
      && CONST_INT_P (XEXP (x, 1))
      && ! CONSTANT_ADDRESS_P (XEXP (x, 1)))
    {
      addend = INTVAL (XEXP (x, 1));
      x = XEXP (x, 0);
      goto split_addend;
    }

  /* If the address is (const (plus FOO const_int)), find the low-order
     part of the CONST_INT.  Then load FOO plus any high-order part of the
     CONST_INT into a register.  Our address is (plus reg low-part-const).
     This is done to reduce the number of GOT entries.  */
  if (can_create_pseudo_p ()
      && GET_CODE (x) == CONST
      && GET_CODE (XEXP (x, 0)) == PLUS
      && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
    {
      addend = INTVAL (XEXP (XEXP (x, 0), 1));
      x = force_reg (Pmode, XEXP (XEXP (x, 0), 0));
      goto split_addend;
    }

  /* If we have a (plus reg const), emit the load as in (2), then add
     the two registers, and finally generate (plus reg low-part-const) as
     our address.  */
  if (can_create_pseudo_p ()
      && GET_CODE (x) == PLUS
      && REG_P (XEXP (x, 0))
      && GET_CODE (XEXP (x, 1)) == CONST
      && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS
      && CONST_INT_P (XEXP (XEXP (XEXP (x, 1), 0), 1)))
    {
      addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1));
      x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0),
			       XEXP (XEXP (XEXP (x, 1), 0), 0),
			       NULL_RTX, 1, OPTAB_LIB_WIDEN);
      goto split_addend;
    }

  /* If this is a local symbol, split the address into HIGH/LO_SUM parts.
     Avoid modes larger than word mode since i.e. $LC0+8($1) can fold
     around +/- 32k offset.  */
  if (TARGET_EXPLICIT_RELOCS
      && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
      && symbolic_operand (x, Pmode))
    {
      rtx r0, r16, eqv, tga, tp, dest, seq;
      rtx_insn *insn;

      switch (tls_symbolic_operand_type (x))
	{
	case TLS_MODEL_NONE:
	  break;

	case TLS_MODEL_GLOBAL_DYNAMIC:
	  {
	    start_sequence ();

	    r0 = gen_rtx_REG (Pmode, 0);
	    r16 = gen_rtx_REG (Pmode, 16);
	    tga = get_tls_get_addr ();
	    dest = gen_reg_rtx (Pmode);
	    seq = GEN_INT (alpha_next_sequence_number++);

	    emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq));
	    rtx val = gen_call_value_osf_tlsgd (r0, tga, seq);
	    insn = emit_call_insn (val);
	    RTL_CONST_CALL_P (insn) = 1;
	    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);

	    insn = get_insns ();
	    end_sequence ();

	    emit_libcall_block (insn, dest, r0, x);
	    return dest;
	  }

	case TLS_MODEL_LOCAL_DYNAMIC:
	  {
	    start_sequence ();

	    r0 = gen_rtx_REG (Pmode, 0);
	    r16 = gen_rtx_REG (Pmode, 16);
	    tga = get_tls_get_addr ();
	    scratch = gen_reg_rtx (Pmode);
	    seq = GEN_INT (alpha_next_sequence_number++);

	    emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq));
	    rtx val = gen_call_value_osf_tlsldm (r0, tga, seq);
	    insn = emit_call_insn (val);
	    RTL_CONST_CALL_P (insn) = 1;
	    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);

	    insn = get_insns ();
	    end_sequence ();

	    eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
				  UNSPEC_TLSLDM_CALL);
	    emit_libcall_block (insn, scratch, r0, eqv);

	    eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPREL);
	    eqv = gen_rtx_CONST (Pmode, eqv);

	    if (alpha_tls_size == 64)
	      {
		dest = gen_reg_rtx (Pmode);
		emit_insn (gen_rtx_SET (dest, eqv));
		emit_insn (gen_adddi3 (dest, dest, scratch));
		return dest;
	      }
	    if (alpha_tls_size == 32)
	      {
		rtx temp = gen_rtx_HIGH (Pmode, eqv);
		temp = gen_rtx_PLUS (Pmode, scratch, temp);
		scratch = gen_reg_rtx (Pmode);
		emit_insn (gen_rtx_SET (scratch, temp));
	      }
	    return gen_rtx_LO_SUM (Pmode, scratch, eqv);
	  }

	case TLS_MODEL_INITIAL_EXEC:
	  eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
	  eqv = gen_rtx_CONST (Pmode, eqv);
	  tp = gen_reg_rtx (Pmode);
	  scratch = gen_reg_rtx (Pmode);
	  dest = gen_reg_rtx (Pmode);

	  emit_insn (gen_get_thread_pointerdi (tp));
	  emit_insn (gen_rtx_SET (scratch, eqv));
	  emit_insn (gen_adddi3 (dest, tp, scratch));
	  return dest;

	case TLS_MODEL_LOCAL_EXEC:
	  eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
	  eqv = gen_rtx_CONST (Pmode, eqv);
	  tp = gen_reg_rtx (Pmode);

	  emit_insn (gen_get_thread_pointerdi (tp));
	  if (alpha_tls_size == 32)
	    {
	      rtx temp = gen_rtx_HIGH (Pmode, eqv);
	      temp = gen_rtx_PLUS (Pmode, tp, temp);
	      tp = gen_reg_rtx (Pmode);
	      emit_insn (gen_rtx_SET (tp, temp));
	    }
	  return gen_rtx_LO_SUM (Pmode, tp, eqv);

	default:
	  gcc_unreachable ();
	}

      if (local_symbolic_operand (x, Pmode))
	{
	  if (small_symbolic_operand (x, Pmode))
	    return x;
	  else
	    {
	      if (can_create_pseudo_p ())
	        scratch = gen_reg_rtx (Pmode);
	      emit_insn (gen_rtx_SET (scratch, gen_rtx_HIGH (Pmode, x)));
	      return gen_rtx_LO_SUM (Pmode, scratch, x);
	    }
	}
    }

  return NULL;

 split_addend:
  {
    HOST_WIDE_INT low, high;

    low = ((addend & 0xffff) ^ 0x8000) - 0x8000;
    addend -= low;
    high = ((addend & 0xffffffff) ^ 0x80000000) - 0x80000000;
    addend -= high;

    if (addend)
      x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (addend),
			       (!can_create_pseudo_p () ? scratch : NULL_RTX),
			       1, OPTAB_LIB_WIDEN);
    if (high)
      x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (high),
			       (!can_create_pseudo_p () ? scratch : NULL_RTX),
			       1, OPTAB_LIB_WIDEN);

    return plus_constant (Pmode, x, low);
  }
}


/* Try machine-dependent ways of modifying an illegitimate address
   to be legitimate.  Return X or the new, valid address.  */

static rtx
alpha_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
			  machine_mode mode)
{
  rtx new_x = alpha_legitimize_address_1 (x, NULL_RTX, mode);
  return new_x ? new_x : x;
}

/* Return true if ADDR has an effect that depends on the machine mode it
   is used for.  On the Alpha this is true only for the unaligned modes.
   We can simplify the test since we know that the address must be valid.  */

static bool
alpha_mode_dependent_address_p (const_rtx addr,
				addr_space_t as ATTRIBUTE_UNUSED)
{
  return GET_CODE (addr) == AND;
}

/* Primarily this is required for TLS symbols, but given that our move
   patterns *ought* to be able to handle any symbol at any time, we
   should never be spilling symbolic operands to the constant pool, ever.  */

static bool
alpha_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
  enum rtx_code code = GET_CODE (x);
  return code == SYMBOL_REF || code == LABEL_REF || code == CONST;
}

/* We do not allow indirect calls to be optimized into sibling calls, nor
   can we allow a call to a function with a different GP to be optimized
   into a sibcall.  */

static bool
alpha_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
{
  /* Can't do indirect tail calls, since we don't know if the target
     uses the same GP.  */
  if (!decl)
    return false;

  /* Otherwise, we can make a tail call if the target function shares
     the same GP.  */
  return decl_has_samegp (decl);
}

bool
some_small_symbolic_operand_int (rtx x)
{
  subrtx_var_iterator::array_type array;
  FOR_EACH_SUBRTX_VAR (iter, array, x, ALL)
    {
      rtx x = *iter;
      /* Don't re-split.  */
      if (GET_CODE (x) == LO_SUM)
	iter.skip_subrtxes ();
      else if (small_symbolic_operand (x, Pmode))
	return true;
    }
  return false;
}

rtx
split_small_symbolic_operand (rtx x)
{
  x = copy_insn (x);
  subrtx_ptr_iterator::array_type array;
  FOR_EACH_SUBRTX_PTR (iter, array, &x, ALL)
    {
      rtx *ptr = *iter;
      rtx x = *ptr;
      /* Don't re-split.  */
      if (GET_CODE (x) == LO_SUM)
	iter.skip_subrtxes ();
      else if (small_symbolic_operand (x, Pmode))
	{
	  *ptr = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x);
	  iter.skip_subrtxes ();
	}
    }
  return x;
}

/* Indicate that INSN cannot be duplicated.  This is true for any insn
   that we've marked with gpdisp relocs, since those have to stay in
   1-1 correspondence with one another.

   Technically we could copy them if we could set up a mapping from one
   sequence number to another, across the set of insns to be duplicated.
   This seems overly complicated and error-prone since interblock motion
   from sched-ebb could move one of the pair of insns to a different block.

   Also cannot allow jsr insns to be duplicated.  If they throw exceptions,
   then they'll be in a different block from their ldgp.  Which could lead
   the bb reorder code to think that it would be ok to copy just the block
   containing the call and branch to the block containing the ldgp.  */

static bool
alpha_cannot_copy_insn_p (rtx_insn *insn)
{
  if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
    return false;
  if (recog_memoized (insn) >= 0)
    return get_attr_cannot_copy (insn);
  else
    return false;
}


/* Try a machine-dependent way of reloading an illegitimate address
   operand.  If we find one, push the reload and return the new rtx.  */

rtx
alpha_legitimize_reload_address (rtx x,
				 machine_mode mode ATTRIBUTE_UNUSED,
				 int opnum, int type,
				 int ind_levels ATTRIBUTE_UNUSED)
{
  /* We must recognize output that we have already generated ourselves.  */
  if (GET_CODE (x) == PLUS
      && GET_CODE (XEXP (x, 0)) == PLUS
      && REG_P (XEXP (XEXP (x, 0), 0))
      && CONST_INT_P (XEXP (XEXP (x, 0), 1))
      && CONST_INT_P (XEXP (x, 1)))
    {
      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
		   BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
		   opnum, (enum reload_type) type);
      return x;
    }

  /* We wish to handle large displacements off a base register by
     splitting the addend across an ldah and the mem insn.  This
     cuts number of extra insns needed from 3 to 1.  */
  if (GET_CODE (x) == PLUS
      && REG_P (XEXP (x, 0))
      && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
      && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0)))
      && CONST_INT_P (XEXP (x, 1)))
    {
      HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
      HOST_WIDE_INT high
	= (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;

      /* Check for 32-bit overflow.  */
      if (high + low != val)
	return NULL_RTX;

      /* Reload the high part into a base reg; leave the low part
	 in the mem directly.  */
      x = gen_rtx_PLUS (GET_MODE (x),
			gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
				      GEN_INT (high)),
			GEN_INT (low));

      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
		   BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
		   opnum, (enum reload_type) type);
      return x;
    }

  return NULL_RTX;
}

/* Return the cost of moving between registers of various classes.  Moving
   between FLOAT_REGS and anything else except float regs is expensive.
   In fact, we make it quite expensive because we really don't want to
   do these moves unless it is clearly worth it.  Optimizations may
   reduce the impact of not being able to allocate a pseudo to a
   hard register.  */

static int
alpha_register_move_cost (machine_mode /*mode*/,
			  reg_class_t from, reg_class_t to)
{
  if ((from == FLOAT_REGS) == (to == FLOAT_REGS))
    return 2;

  if (TARGET_FIX)
    return (from == FLOAT_REGS) ? 6 : 8;

  return 4 + 2 * alpha_memory_latency;
}

/* Return the cost of moving data of MODE from a register to
   or from memory.  On the Alpha, bump this up a bit.  */

static int
alpha_memory_move_cost (machine_mode /*mode*/, reg_class_t /*regclass*/,
			bool /*in*/)
{
  return 2 * alpha_memory_latency;
}

/* Compute a (partial) cost for rtx X.  Return true if the complete
   cost has been computed, and false if subexpressions should be
   scanned.  In either case, *TOTAL contains the cost result.  */

static bool
alpha_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total,
		 bool speed)
{
  int code = GET_CODE (x);
  bool float_mode_p = FLOAT_MODE_P (mode);
  const struct alpha_rtx_cost_data *cost_data;

  if (!speed)
    cost_data = &alpha_rtx_cost_size;
  else
    cost_data = &alpha_rtx_cost_data[alpha_tune];

  switch (code)
    {
    case CONST_INT:
      /* If this is an 8-bit constant, return zero since it can be used
	 nearly anywhere with no cost.  If it is a valid operand for an
	 ADD or AND, likewise return 0 if we know it will be used in that
	 context.  Otherwise, return 2 since it might be used there later.
	 All other constants take at least two insns.  */
      if (INTVAL (x) >= 0 && INTVAL (x) < 256)
	{
	  *total = 0;
	  return true;
	}
      /* FALLTHRU */

    case CONST_DOUBLE:
    case CONST_WIDE_INT:
      if (x == CONST0_RTX (mode))
	*total = 0;
      else if ((outer_code == PLUS && add_operand (x, VOIDmode))
	       || (outer_code == AND && and_operand (x, VOIDmode)))
	*total = 0;
      else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode))
	*total = 2;
      else
	*total = COSTS_N_INSNS (2);
      return true;

    case CONST:
    case SYMBOL_REF:
    case LABEL_REF:
      if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode))
	*total = COSTS_N_INSNS (outer_code != MEM);
      else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode))
	*total = COSTS_N_INSNS (1 + (outer_code != MEM));
      else if (tls_symbolic_operand_type (x))
	/* Estimate of cost for call_pal rduniq.  */
	/* ??? How many insns do we emit here?  More than one...  */
	*total = COSTS_N_INSNS (15);
      else
	/* Otherwise we do a load from the GOT.  */
	*total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency);
      return true;

    case HIGH:
      /* This is effectively an add_operand.  */
      *total = 2;
      return true;

    case PLUS:
    case MINUS:
      if (float_mode_p)
	*total = cost_data->fp_add;
      else if (GET_CODE (XEXP (x, 0)) == ASHIFT
	       && const23_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
	{
	  *total = (rtx_cost (XEXP (XEXP (x, 0), 0), mode,
			      (enum rtx_code) outer_code, opno, speed)
		    + rtx_cost (XEXP (x, 1), mode,
				(enum rtx_code) outer_code, opno, speed)
		    + COSTS_N_INSNS (1));
	  return true;
	}
      return false;

    case MULT:
      if (float_mode_p)
	*total = cost_data->fp_mult;
      else if (mode == DImode)
	*total = cost_data->int_mult_di;
      else
	*total = cost_data->int_mult_si;
      return false;

    case ASHIFT:
      if (CONST_INT_P (XEXP (x, 1))
	  && INTVAL (XEXP (x, 1)) <= 3)
	{
	  *total = COSTS_N_INSNS (1);
	  return false;
	}
      /* FALLTHRU */

    case ASHIFTRT:
    case LSHIFTRT:
      *total = cost_data->int_shift;
      return false;

    case IF_THEN_ELSE:
      if (float_mode_p)
        *total = cost_data->fp_add;
      else
        *total = cost_data->int_cmov;
      return false;

    case DIV:
    case UDIV:
    case MOD:
    case UMOD:
      if (!float_mode_p)
	*total = cost_data->int_div;
      else if (mode == SFmode)
        *total = cost_data->fp_div_sf;
      else
        *total = cost_data->fp_div_df;
      return false;

    case MEM:
      *total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency);
      return true;

    case NEG:
      if (! float_mode_p)
	{
	  *total = COSTS_N_INSNS (1);
	  return false;
	}
      /* FALLTHRU */

    case ABS:
      if (! float_mode_p)
	{
	  *total = COSTS_N_INSNS (1) + cost_data->int_cmov;
	  return false;
	}
      /* FALLTHRU */

    case FLOAT:
    case UNSIGNED_FLOAT:
    case FIX:
    case UNSIGNED_FIX:
    case FLOAT_TRUNCATE:
      *total = cost_data->fp_add;
      return false;

    case FLOAT_EXTEND:
      if (MEM_P (XEXP (x, 0)))
	*total = 0;
      else
	*total = cost_data->fp_add;
      return false;

    default:
      return false;
    }
}

/* REF is an alignable memory location.  Place an aligned SImode
   reference into *PALIGNED_MEM and the number of bits to shift into
   *PBITNUM.  SCRATCH is a free register for use in reloading out
   of range stack slots.  */

void
get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum)
{
  rtx base;
  HOST_WIDE_INT disp, offset;

  gcc_assert (MEM_P (ref));

  if (reload_in_progress)
    {
      base = find_replacement (&XEXP (ref, 0));
      gcc_assert (memory_address_p (GET_MODE (ref), base));
    }
  else
    base = XEXP (ref, 0);

  if (GET_CODE (base) == PLUS)
    disp = INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
  else
    disp = 0;

  /* Find the byte offset within an aligned word.  If the memory itself is
     claimed to be aligned, believe it.  Otherwise, aligned_memory_operand
     will have examined the base register and determined it is aligned, and
     thus displacements from it are naturally alignable.  */
  if (MEM_ALIGN (ref) >= 32)
    offset = 0;
  else
    offset = disp & 3;

  /* The location should not cross aligned word boundary.  */
  gcc_assert (offset + GET_MODE_SIZE (GET_MODE (ref))
	      <= GET_MODE_SIZE (SImode));

  /* Access the entire aligned word.  */
  *paligned_mem = widen_memory_access (ref, SImode, -offset);

  /* Convert the byte offset within the word to a bit offset.  */
  offset *= BITS_PER_UNIT;
  *pbitnum = GEN_INT (offset);
}

/* Similar, but just get the address.  Handle the two reload cases.
   Add EXTRA_OFFSET to the address we return.  */

rtx
get_unaligned_address (rtx ref)
{
  rtx base;
  HOST_WIDE_INT offset = 0;

  gcc_assert (MEM_P (ref));

  if (reload_in_progress)
    {
      base = find_replacement (&XEXP (ref, 0));
      gcc_assert (memory_address_p (GET_MODE (ref), base));
    }
  else
    base = XEXP (ref, 0);

  if (GET_CODE (base) == PLUS)
    offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);

  return plus_constant (Pmode, base, offset);
}

/* Compute a value X, such that X & 7 == (ADDR + OFS) & 7.
   X is always returned in a register.  */

rtx
get_unaligned_offset (rtx addr, HOST_WIDE_INT ofs)
{
  if (GET_CODE (addr) == PLUS)
    {
      ofs += INTVAL (XEXP (addr, 1));
      addr = XEXP (addr, 0);
    }

  return expand_simple_binop (Pmode, PLUS, addr, GEN_INT (ofs & 7),
			      NULL_RTX, 1, OPTAB_LIB_WIDEN);
}

/* On the Alpha, all (non-symbolic) constants except zero go into
   a floating-point register via memory.  Note that we cannot
   return anything that is not a subset of RCLASS, and that some
   symbolic constants cannot be dropped to memory.  */

enum reg_class
alpha_preferred_reload_class(rtx x, enum reg_class rclass)
{
  /* Zero is present in any register class.  */
  if (x == CONST0_RTX (GET_MODE (x)))
    return rclass;

  /* These sorts of constants we can easily drop to memory.  */
  if (CONST_SCALAR_INT_P (x)
      || CONST_DOUBLE_P (x)
      || GET_CODE (x) == CONST_VECTOR)
    {
      if (rclass == FLOAT_REGS)
	return NO_REGS;
      if (rclass == ALL_REGS)
	return GENERAL_REGS;
      return rclass;
    }

  /* All other kinds of constants should not (and in the case of HIGH
     cannot) be dropped to memory -- instead we use a GENERAL_REGS
     secondary reload.  */
  if (CONSTANT_P (x))
    return (rclass == ALL_REGS ? GENERAL_REGS : rclass);

  return rclass;
}

/* Inform reload about cases where moving X with a mode MODE to a register in
   RCLASS requires an extra scratch or immediate register.  Return the class
   needed for the immediate register.  */

static reg_class_t
alpha_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
			machine_mode mode, secondary_reload_info *sri)
{
  enum reg_class rclass = (enum reg_class) rclass_i;

  /* Loading and storing HImode or QImode values to and from memory
     usually requires a scratch register.  */
  if (!TARGET_BWX && (mode == QImode || mode == HImode || mode == CQImode))
    {
      if (any_memory_operand (x, mode))
	{
	  if (in_p)
	    {
	      if (!aligned_memory_operand (x, mode))
		sri->icode = direct_optab_handler (reload_in_optab, mode);
	    }
	  else
	    sri->icode = direct_optab_handler (reload_out_optab, mode);
	  return NO_REGS;
	}
    }

  /* We also cannot do integral arithmetic into FP regs, as might result
     from register elimination into a DImode fp register.  */
  if (rclass == FLOAT_REGS)
    {
      if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND)
	return GENERAL_REGS;
      if (in_p && INTEGRAL_MODE_P (mode)
	  && !MEM_P (x) && !REG_P (x) && !CONST_INT_P (x))
	return GENERAL_REGS;
    }

  return NO_REGS;
}

/* Implement TARGET_SECONDARY_MEMORY_NEEDED.

   If we are copying between general and FP registers, we need a memory
   location unless the FIX extension is available.  */

static bool
alpha_secondary_memory_needed (machine_mode, reg_class_t class1,
			       reg_class_t class2)
{
  return (!TARGET_FIX
	  && ((class1 == FLOAT_REGS && class2 != FLOAT_REGS)
	      || (class2 == FLOAT_REGS && class1 != FLOAT_REGS)));
}

/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.  If MODE is
   floating-point, use it.  Otherwise, widen to a word like the default.
   This is needed because we always store integers in FP registers in
   quadword format.  This whole area is very tricky!  */

static machine_mode
alpha_secondary_memory_needed_mode (machine_mode mode)
{
  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
    return mode;
  if (GET_MODE_SIZE (mode) >= 4)
    return mode;
  return mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0).require ();
}

/* Given SEQ, which is an INSN list, look for any MEMs in either
   a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
   volatile flags from REF into each of the MEMs found.  If REF is not
   a MEM, don't do anything.  */

void
alpha_set_memflags (rtx seq, rtx ref)
{
  rtx_insn *insn;

  if (!MEM_P (ref))
    return;

  /* This is only called from alpha.md, after having had something
     generated from one of the insn patterns.  So if everything is
     zero, the pattern is already up-to-date.  */
  if (!MEM_VOLATILE_P (ref)
      && !MEM_NOTRAP_P (ref)
      && !MEM_READONLY_P (ref))
    return;

  subrtx_var_iterator::array_type array;
  for (insn = as_a <rtx_insn *> (seq); insn; insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST)
	{
	  rtx x = *iter;
	  if (MEM_P (x))
	    {
	      MEM_VOLATILE_P (x) = MEM_VOLATILE_P (ref);
	      MEM_NOTRAP_P (x) = MEM_NOTRAP_P (ref);
	      MEM_READONLY_P (x) = MEM_READONLY_P (ref);
	      /* Sadly, we cannot use alias sets because the extra
		 aliasing produced by the AND interferes.  Given that
		 two-byte quantities are the only thing we would be
		 able to differentiate anyway, there does not seem to
		 be any point in convoluting the early out of the
		 alias check.  */
	      iter.skip_subrtxes ();
	    }
	}
    else
      gcc_unreachable ();
}

static rtx alpha_emit_set_const (rtx, machine_mode, HOST_WIDE_INT,
				 int, bool);

/* Internal routine for alpha_emit_set_const to check for N or below insns.
   If NO_OUTPUT is true, then we only check to see if N insns are possible,
   and return pc_rtx if successful.  */

static rtx
alpha_emit_set_const_1 (rtx target, machine_mode mode,
			HOST_WIDE_INT c, int n, bool no_output)
{
  HOST_WIDE_INT new_const;
  int i, bits;
  /* Use a pseudo if highly optimizing and still generating RTL.  */
  rtx subtarget
    = (flag_expensive_optimizations && can_create_pseudo_p () ? 0 : target);
  rtx temp, insn;

  /* If this is a sign-extended 32-bit constant, we can do this in at most
     three insns, so do it if we have enough insns left.  */

  if (c >> 31 == -1 || c >> 31 == 0)
    {
      HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
      HOST_WIDE_INT tmp1 = c - low;
      HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
      HOST_WIDE_INT extra = 0;

      /* If HIGH will be interpreted as negative but the constant is
	 positive, we must adjust it to do two ldha insns.  */

      if ((high & 0x8000) != 0 && c >= 0)
	{
	  extra = 0x4000;
	  tmp1 -= 0x40000000;
	  high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
	}

      if (c == low || (low == 0 && extra == 0))
	{
	  /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
	     but that meant that we can't handle INT_MIN on 32-bit machines
	     (like NT/Alpha), because we recurse indefinitely through
	     emit_move_insn to gen_movdi.  So instead, since we know exactly
	     what we want, create it explicitly.  */

	  if (no_output)
	    return pc_rtx;
	  if (target == NULL)
	    target = gen_reg_rtx (mode);
	  emit_insn (gen_rtx_SET (target, GEN_INT (c)));
	  return target;
	}
      else if (n >= 2 + (extra != 0))
	{
	  if (no_output)
	    return pc_rtx;
	  if (!can_create_pseudo_p ())
	    {
	      emit_insn (gen_rtx_SET (target, GEN_INT (high << 16)));
	      temp = target;
	    }
	  else
	    temp = copy_to_suggested_reg (GEN_INT (high << 16),
					  subtarget, mode);

	  /* As of 2002-02-23, addsi3 is only available when not optimizing.
	     This means that if we go through expand_binop, we'll try to
	     generate extensions, etc, which will require new pseudos, which
	     will fail during some split phases.  The SImode add patterns
	     still exist, but are not named.  So build the insns by hand.  */

	  if (extra != 0)
	    {
	      if (! subtarget)
		subtarget = gen_reg_rtx (mode);
	      insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16));
	      insn = gen_rtx_SET (subtarget, insn);
	      emit_insn (insn);
	      temp = subtarget;
	    }

	  if (target == NULL)
	    target = gen_reg_rtx (mode);
	  insn = gen_rtx_PLUS (mode, temp, GEN_INT (low));
	  insn = gen_rtx_SET (target, insn);
	  emit_insn (insn);
	  return target;
	}
    }

  /* If we couldn't do it that way, try some other methods.  But if we have
     no instructions left, don't bother.  Likewise, if this is SImode and
     we can't make pseudos, we can't do anything since the expand_binop
     and expand_unop calls will widen and try to make pseudos.  */

  if (n == 1 || (mode == SImode && !can_create_pseudo_p ()))
    return 0;

  /* Next, see if we can load a related constant and then shift and possibly
     negate it to get the constant we want.  Try this once each increasing
     numbers of insns.  */

  for (i = 1; i < n; i++)
    {
      /* First, see if minus some low bits, we've an easy load of
	 high bits.  */

      new_const = ((c & 0xffff) ^ 0x8000) - 0x8000;
      if (new_const != 0)
	{
          temp = alpha_emit_set_const (subtarget, mode, c - new_const, i, no_output);
	  if (temp)
	    {
	      if (no_output)
		return temp;
	      return expand_binop (mode, add_optab, temp, GEN_INT (new_const),
				   target, 0, OPTAB_WIDEN);
	    }
	}

      /* Next try complementing.  */
      temp = alpha_emit_set_const (subtarget, mode, ~c, i, no_output);
      if (temp)
	{
	  if (no_output)
	    return temp;
	  return expand_unop (mode, one_cmpl_optab, temp, target, 0);
	}

      /* Next try to form a constant and do a left shift.  We can do this
	 if some low-order bits are zero; the exact_log2 call below tells
	 us that information.  The bits we are shifting out could be any
	 value, but here we'll just try the 0- and sign-extended forms of
	 the constant.  To try to increase the chance of having the same
	 constant in more than one insn, start at the highest number of
	 bits to shift, but try all possibilities in case a ZAPNOT will
	 be useful.  */

      bits = exact_log2 (c & -c);
      if (bits > 0)
	for (; bits > 0; bits--)
	  {
	    new_const = c >> bits;
	    temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
	    if (!temp && c < 0)
	      {
		new_const = (unsigned HOST_WIDE_INT)c >> bits;
		temp = alpha_emit_set_const (subtarget, mode, new_const,
					     i, no_output);
	      }
	    if (temp)
	      {
		if (no_output)
		  return temp;
	        return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
				     target, 0, OPTAB_WIDEN);
	      }
	  }

      /* Now try high-order zero bits.  Here we try the shifted-in bits as
	 all zero and all ones.  Be careful to avoid shifting outside the
	 mode and to avoid shifting outside the host wide int size.  */

      bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
	      - floor_log2 (c) - 1);
      if (bits > 0)
	for (; bits > 0; bits--)
	  {
	    new_const = c << bits;
	    temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
	    if (!temp)
	      {
		new_const = (c << bits) | ((HOST_WIDE_INT_1U << bits) - 1);
	        temp = alpha_emit_set_const (subtarget, mode, new_const,
					     i, no_output);
	      }
	    if (temp)
	      {
		if (no_output)
		  return temp;
		return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
				     target, 1, OPTAB_WIDEN);
	      }
	  }

      /* Now try high-order 1 bits.  We get that with a sign-extension.
	 But one bit isn't enough here.  Be careful to avoid shifting outside
	 the mode and to avoid shifting outside the host wide int size.  */

      bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
	      - floor_log2 (~ c) - 2);
      if (bits > 0)
	for (; bits > 0; bits--)
	  {
	    new_const = c << bits;
	    temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
	    if (!temp)
	      {
		new_const = (c << bits) | ((HOST_WIDE_INT_1U << bits) - 1);
	        temp = alpha_emit_set_const (subtarget, mode, new_const,
					     i, no_output);
	      }
	    if (temp)
	      {
		if (no_output)
		  return temp;
		return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
				     target, 0, OPTAB_WIDEN);
	      }
	  }
    }

  /* Finally, see if can load a value into the target that is the same as the
     constant except that all bytes that are 0 are changed to be 0xff.  If we
     can, then we can do a ZAPNOT to obtain the desired constant.  */

  new_const = c;
  for (i = 0; i < 64; i += 8)
    if ((new_const & ((HOST_WIDE_INT) 0xff << i)) == 0)
      new_const |= (HOST_WIDE_INT) 0xff << i;

  /* We are only called for SImode and DImode.  If this is SImode, ensure that
     we are sign extended to a full word.  */

  if (mode == SImode)
    new_const = ((new_const & 0xffffffff) ^ 0x80000000) - 0x80000000;

  if (new_const != c)
    {
      temp = alpha_emit_set_const (subtarget, mode, new_const, n - 1, no_output);
      if (temp)
	{
	  if (no_output)
	    return temp;
	  return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new_const),
			       target, 0, OPTAB_WIDEN);
	}
    }

  return 0;
}

/* Try to output insns to set TARGET equal to the constant C if it can be
   done in less than N insns.  Do all computations in MODE.  Returns the place
   where the output has been placed if it can be done and the insns have been
   emitted.  If it would take more than N insns, zero is returned and no
   insns and emitted.  */

static rtx
alpha_emit_set_const (rtx target, machine_mode mode,
		      HOST_WIDE_INT c, int n, bool no_output)
{
  machine_mode orig_mode = mode;
  rtx orig_target = target;
  rtx result = 0;
  int i;

  /* If we can't make any pseudos, TARGET is an SImode hard register, we
     can't load this constant in one insn, do this in DImode.  */
  if (!can_create_pseudo_p () && mode == SImode
      && REG_P (target) && REGNO (target) < FIRST_PSEUDO_REGISTER)
    {
      result = alpha_emit_set_const_1 (target, mode, c, 1, no_output);
      if (result)
	return result;

      target = no_output ? NULL : gen_lowpart (DImode, target);
      mode = DImode;
    }
  else if (mode == V8QImode || mode == V4HImode || mode == V2SImode)
    {
      target = no_output ? NULL : gen_lowpart (DImode, target);
      mode = DImode;
    }

  /* Try 1 insn, then 2, then up to N.  */
  for (i = 1; i <= n; i++)
    {
      result = alpha_emit_set_const_1 (target, mode, c, i, no_output);
      if (result)
	{
	  rtx_insn *insn;
	  rtx set;

	  if (no_output)
	    return result;

	  insn = get_last_insn ();
	  set = single_set (insn);
	  if (! CONSTANT_P (SET_SRC (set)))
	    set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
	  break;
	}
    }

  /* Allow for the case where we changed the mode of TARGET.  */
  if (result)
    {
      if (result == target)
	result = orig_target;
      else if (mode != orig_mode)
	result = gen_lowpart (orig_mode, result);
    }

  return result;
}

/* Having failed to find a 3 insn sequence in alpha_emit_set_const,
   fall back to a straight forward decomposition.  We do this to avoid
   exponential run times encountered when looking for longer sequences
   with alpha_emit_set_const.  */

static rtx
alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1)
{
  HOST_WIDE_INT d1, d2, d3, d4;

  /* Decompose the entire word */

  d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
  c1 -= d1;
  d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
  c1 = (c1 - d2) >> 32;
  d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
  c1 -= d3;
  d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
  gcc_assert (c1 == d4);

  /* Construct the high word */
  if (d4)
    {
      emit_move_insn (target, GEN_INT (d4));
      if (d3)
	emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
    }
  else
    emit_move_insn (target, GEN_INT (d3));

  /* Shift it into place */
  emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));

  /* Add in the low bits.  */
  if (d2)
    emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
  if (d1)
    emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));

  return target;
}

/* Given an integral CONST_INT or CONST_VECTOR, return the low 64 bits.  */

static HOST_WIDE_INT
alpha_extract_integer (rtx x)
{
  if (GET_CODE (x) == CONST_VECTOR)
    x = simplify_subreg (DImode, x, GET_MODE (x), 0);

  gcc_assert (CONST_INT_P (x));

  return INTVAL (x);
}

/* Implement TARGET_LEGITIMATE_CONSTANT_P.  This is all constants for which
   we are willing to load the value into a register via a move pattern.
   Normally this is all symbolic constants, integral constants that
   take three or fewer instructions, and floating-point zero.  */

bool
alpha_legitimate_constant_p (machine_mode mode, rtx x)
{
  HOST_WIDE_INT i0;

  switch (GET_CODE (x))
    {
    case LABEL_REF:
    case HIGH:
      return true;

    case CONST:
      if (GET_CODE (XEXP (x, 0)) == PLUS
	  && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
	x = XEXP (XEXP (x, 0), 0);
      else
	return true;

      if (GET_CODE (x) != SYMBOL_REF)
	return true;
      /* FALLTHRU */

    case SYMBOL_REF:
      /* TLS symbols are never valid.  */
      return SYMBOL_REF_TLS_MODEL (x) == 0;

    case CONST_WIDE_INT:
      if (TARGET_BUILD_CONSTANTS)
	return true;
      if (x == CONST0_RTX (mode))
	return true;
      mode = DImode;
      gcc_assert (CONST_WIDE_INT_NUNITS (x) == 2);
      i0 = CONST_WIDE_INT_ELT (x, 1);
      if (alpha_emit_set_const_1 (NULL_RTX, mode, i0, 3, true) == NULL)
	return false;
      i0 = CONST_WIDE_INT_ELT (x, 0);
      goto do_integer;

    case CONST_DOUBLE:
      if (x == CONST0_RTX (mode))
	return true;
      return false;

    case CONST_VECTOR:
      if (x == CONST0_RTX (mode))
	return true;
      if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
	return false;
      if (GET_MODE_SIZE (mode) != 8)
	return false;
      /* FALLTHRU */

    case CONST_INT:
      if (TARGET_BUILD_CONSTANTS)
	return true;
      i0 = alpha_extract_integer (x);
    do_integer:
      return alpha_emit_set_const_1 (NULL_RTX, mode, i0, 3, true) != NULL;

    default:
      return false;
    }
}

/* Operand 1 is known to be a constant, and should require more than one
   instruction to load.  Emit that multi-part load.  */

bool
alpha_split_const_mov (machine_mode mode, rtx *operands)
{
  HOST_WIDE_INT i0;
  rtx temp = NULL_RTX;

  i0 = alpha_extract_integer (operands[1]);

  temp = alpha_emit_set_const (operands[0], mode, i0, 3, false);

  if (!temp && TARGET_BUILD_CONSTANTS)
    temp = alpha_emit_set_long_const (operands[0], i0);

  if (temp)
    {
      if (!rtx_equal_p (operands[0], temp))
	emit_move_insn (operands[0], temp);
      return true;
    }

  return false;
}

/* Expand a move instruction; return true if all work is done.
   We don't handle non-bwx subword loads here.  */

bool
alpha_expand_mov (machine_mode mode, rtx *operands)
{
  rtx tmp;

  /* If the output is not a register, the input must be.  */
  if (MEM_P (operands[0])
      && ! reg_or_0_operand (operands[1], mode))
    operands[1] = force_reg (mode, operands[1]);

  /* Allow legitimize_address to perform some simplifications.  */
  if (mode == Pmode && symbolic_operand (operands[1], mode))
    {
      tmp = alpha_legitimize_address_1 (operands[1], operands[0], mode);
      if (tmp)
	{
	  if (tmp == operands[0])
	    return true;
	  operands[1] = tmp;
	  return false;
	}
    }

  /* Early out for non-constants and valid constants.  */
  if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode))
    return false;

  /* Split large integers.  */
  if (CONST_INT_P (operands[1])
      || GET_CODE (operands[1]) == CONST_VECTOR)
    {
      if (alpha_split_const_mov (mode, operands))
	return true;
    }

  /* Otherwise we've nothing left but to drop the thing to memory.  */
  tmp = force_const_mem (mode, operands[1]);

  if (tmp == NULL_RTX)
    return false;

  if (reload_in_progress)
    {
      emit_move_insn (operands[0], XEXP (tmp, 0));
      operands[1] = replace_equiv_address (tmp, operands[0]);
    }
  else
    operands[1] = validize_mem (tmp);
  return false;
}

/* Expand a non-bwx QImode or HImode move instruction;
   return true if all work is done.  */

bool
alpha_expand_mov_nobwx (machine_mode mode, rtx *operands)
{
  rtx seq;

  /* If the output is not a register, the input must be.  */
  if (MEM_P (operands[0]))
    operands[1] = force_reg (mode, operands[1]);

  /* Handle four memory cases, unaligned and aligned for either the input
     or the output.  The only case where we can be called during reload is
     for aligned loads; all other cases require temporaries.  */

  if (any_memory_operand (operands[1], mode))
    {
      if (aligned_memory_operand (operands[1], mode))
	{
	  if (reload_in_progress)
	    {
	      seq = gen_reload_in_aligned (mode, operands[0], operands[1]);
	      emit_insn (seq);
	    }
	  else
	    {
	      rtx aligned_mem, bitnum;
	      rtx scratch = gen_reg_rtx (SImode);
	      rtx subtarget;
	      bool copyout;

	      get_aligned_mem (operands[1], &aligned_mem, &bitnum);

	      subtarget = operands[0];
	      if (REG_P (subtarget))
		subtarget = gen_lowpart (DImode, subtarget), copyout = false;
	      else
		subtarget = gen_reg_rtx (DImode), copyout = true;

	      if (mode == QImode)
		seq = gen_aligned_loadqi (subtarget, aligned_mem,
					  bitnum, scratch);
	      else
		seq = gen_aligned_loadhi (subtarget, aligned_mem,
					  bitnum, scratch);
	      emit_insn (seq);

	      if (copyout)
		emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
	    }
	}
      else
	{
	  /* Don't pass these as parameters since that makes the generated
	     code depend on parameter evaluation order which will cause
	     bootstrap failures.  */

	  rtx temp1, temp2, subtarget, ua;
	  bool copyout;

	  temp1 = gen_reg_rtx (DImode);
	  temp2 = gen_reg_rtx (DImode);

	  subtarget = operands[0];
	  if (REG_P (subtarget))
	    subtarget = gen_lowpart (DImode, subtarget), copyout = false;
	  else
	    subtarget = gen_reg_rtx (DImode), copyout = true;

	  ua = get_unaligned_address (operands[1]);
	  if (mode == QImode)
	    seq = gen_unaligned_loadqi (subtarget, ua, temp1, temp2);
	  else
	    seq = gen_unaligned_loadhi (subtarget, ua, temp1, temp2);

	  alpha_set_memflags (seq, operands[1]);
	  emit_insn (seq);

	  if (copyout)
	    emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
	}
      return true;
    }

  if (any_memory_operand (operands[0], mode))
    {
      if (aligned_memory_operand (operands[0], mode))
	{
	  rtx aligned_mem, bitnum;
	  rtx temp1 = gen_reg_rtx (SImode);
	  rtx temp2 = gen_reg_rtx (SImode);

	  get_aligned_mem (operands[0], &aligned_mem, &bitnum);

	  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
					temp1, temp2));
	}
      else
	{
	  rtx temp1 = gen_reg_rtx (DImode);
	  rtx temp2 = gen_reg_rtx (DImode);
	  rtx temp3 = gen_reg_rtx (DImode);
	  rtx ua = get_unaligned_address (operands[0]);

	  seq = gen_unaligned_store
	    (mode, ua, operands[1], temp1, temp2, temp3);

	  alpha_set_memflags (seq, operands[0]);
	  emit_insn (seq);
	}
      return true;
    }

  return false;
}

/* Implement the movmisalign patterns.  One of the operands is a memory
   that is not naturally aligned.  Emit instructions to load it.  */

void
alpha_expand_movmisalign (machine_mode mode, rtx *operands)
{
  /* Honor misaligned loads, for those we promised to do so.  */
  if (MEM_P (operands[1]))
    {
      rtx tmp;

      if (register_operand (operands[0], mode))
	tmp = operands[0];
      else
	tmp = gen_reg_rtx (mode);

      alpha_expand_unaligned_load (tmp, operands[1], 8, 0, 0);
      if (tmp != operands[0])
	emit_move_insn (operands[0], tmp);
    }
  else if (MEM_P (operands[0]))
    {
      if (!reg_or_0_operand (operands[1], mode))
	operands[1] = force_reg (mode, operands[1]);
      alpha_expand_unaligned_store (operands[0], operands[1], 8, 0);
    }
  else
    gcc_unreachable ();
}

/* Generate an unsigned DImode to FP conversion.  This is the same code
   optabs would emit if we didn't have TFmode patterns.

   For SFmode, this is the only construction I've found that can pass
   gcc.c-torture/execute/ieee/rbug.c.  No scenario that uses DFmode
   intermediates will work, because you'll get intermediate rounding
   that ruins the end result.  Some of this could be fixed by turning
   on round-to-positive-infinity, but that requires diddling the fpsr,
   which kills performance.  I tried turning this around and converting
   to a negative number, so that I could turn on /m, but either I did
   it wrong or there's something else cause I wound up with the exact
   same single-bit error.  There is a branch-less form of this same code:

	srl     $16,1,$1
	and     $16,1,$2
	cmplt   $16,0,$3
	or      $1,$2,$2
	cmovge  $16,$16,$2
	itoft	$3,$f10
	itoft	$2,$f11
	cvtqs   $f11,$f11
	adds    $f11,$f11,$f0
	fcmoveq $f10,$f11,$f0

   I'm not using it because it's the same number of instructions as
   this branch-full form, and it has more serialized long latency
   instructions on the critical path.

   For DFmode, we can avoid rounding errors by breaking up the word
   into two pieces, converting them separately, and adding them back:

   LC0: .long 0,0x5f800000

	itoft	$16,$f11
	lda	$2,LC0
	cmplt	$16,0,$1
	cpyse	$f11,$f31,$f10
	cpyse	$f31,$f11,$f11
	s4addq	$1,$2,$1
	lds	$f12,0($1)
	cvtqt	$f10,$f10
	cvtqt	$f11,$f11
	addt	$f12,$f10,$f0
	addt	$f0,$f11,$f0

   This doesn't seem to be a clear-cut win over the optabs form.
   It probably all depends on the distribution of numbers being
   converted -- in the optabs form, all but high-bit-set has a
   much lower minimum execution time.  */

void
alpha_emit_floatuns (rtx operands[2])
{
  rtx neglab, donelab, i0, i1, f0, in, out;
  machine_mode mode;

  out = operands[0];
  in = force_reg (DImode, operands[1]);
  mode = GET_MODE (out);
  neglab = gen_label_rtx ();
  donelab = gen_label_rtx ();
  i0 = gen_reg_rtx (DImode);
  i1 = gen_reg_rtx (DImode);
  f0 = gen_reg_rtx (mode);

  emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab);

  emit_insn (gen_rtx_SET (out, gen_rtx_FLOAT (mode, in)));
  emit_jump_insn (gen_jump (donelab));
  emit_barrier ();

  emit_label (neglab);

  emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
  emit_insn (gen_anddi3 (i1, in, const1_rtx));
  emit_insn (gen_iordi3 (i0, i0, i1));
  emit_insn (gen_rtx_SET (f0, gen_rtx_FLOAT (mode, i0)));
  emit_insn (gen_rtx_SET (out, gen_rtx_PLUS (mode, f0, f0)));

  emit_label (donelab);
}

/* Generate the comparison for a conditional branch.  */

void
alpha_emit_conditional_branch (rtx operands[], machine_mode cmp_mode)
{
  enum rtx_code cmp_code, branch_code;
  machine_mode branch_mode = VOIDmode;
  enum rtx_code code = GET_CODE (operands[0]);
  rtx op0 = operands[1], op1 = operands[2];
  rtx tem;

  if (cmp_mode == TFmode)
    {
      op0 = alpha_emit_xfloating_compare (&code, op0, op1);
      op1 = const0_rtx;
      cmp_mode = DImode;
    }

  /* The general case: fold the comparison code to the types of compares
     that we have, choosing the branch as necessary.  */
  switch (code)
    {
    case EQ:  case LE:  case LT:  case LEU:  case LTU:
    case UNORDERED:
      /* We have these compares.  */
      cmp_code = code, branch_code = NE;
      break;

    case NE:
    case ORDERED:
      /* These must be reversed.  */
      cmp_code = reverse_condition (code), branch_code = EQ;
      break;

    case GE:  case GT: case GEU:  case GTU:
      /* For FP, we swap them, for INT, we reverse them.  */
      if (cmp_mode == DFmode)
	{
	  cmp_code = swap_condition (code);
	  branch_code = NE;
	  std::swap (op0, op1);
	}
      else
	{
	  cmp_code = reverse_condition (code);
	  branch_code = EQ;
	}
      break;

    default:
      gcc_unreachable ();
    }

  if (cmp_mode == DFmode)
    {
      if (flag_unsafe_math_optimizations && cmp_code != UNORDERED)
	{
	  /* When we are not as concerned about non-finite values, and we
	     are comparing against zero, we can branch directly.  */
	  if (op1 == CONST0_RTX (DFmode))
	    cmp_code = UNKNOWN, branch_code = code;
	  else if (op0 == CONST0_RTX (DFmode))
	    {
	      /* Undo the swap we probably did just above.  */
	      std::swap (op0, op1);
	      branch_code = swap_condition (cmp_code);
	      cmp_code = UNKNOWN;
	    }
	}
      else
	{
	  /* ??? We mark the branch mode to be CCmode to prevent the
	     compare and branch from being combined, since the compare
	     insn follows IEEE rules that the branch does not.  */
	  branch_mode = CCmode;
	}
    }
  else
    {
      /* The following optimizations are only for signed compares.  */
      if (code != LEU && code != LTU && code != GEU && code != GTU)
	{
	  /* Whee.  Compare and branch against 0 directly.  */
	  if (op1 == const0_rtx)
	    cmp_code = UNKNOWN, branch_code = code;

	  /* If the constants doesn't fit into an immediate, but can
 	     be generated by lda/ldah, we adjust the argument and
 	     compare against zero, so we can use beq/bne directly.  */
	  /* ??? Don't do this when comparing against symbols, otherwise
	     we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
	     be declared false out of hand (at least for non-weak).  */
	  else if (CONST_INT_P (op1)
		   && (code == EQ || code == NE)
		   && !(symbolic_operand (op0, VOIDmode)
			|| (REG_P (op0) && REG_POINTER (op0))))
	    {
	      rtx n_op1 = GEN_INT (-INTVAL (op1));

	      if (! satisfies_constraint_I (op1)
		  && (satisfies_constraint_K (n_op1)
		      || satisfies_constraint_L (n_op1)))
		cmp_code = PLUS, branch_code = code, op1 = n_op1;
	    }
	}

      if (!reg_or_0_operand (op0, DImode))
	op0 = force_reg (DImode, op0);
      if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
	op1 = force_reg (DImode, op1);
    }

  /* Emit an initial compare instruction, if necessary.  */
  tem = op0;
  if (cmp_code != UNKNOWN)
    {
      tem = gen_reg_rtx (cmp_mode);
      emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
    }

  /* Emit the branch instruction.  */
  tem = gen_rtx_SET (pc_rtx,
		     gen_rtx_IF_THEN_ELSE (VOIDmode,
					   gen_rtx_fmt_ee (branch_code,
							   branch_mode, tem,
							   CONST0_RTX (cmp_mode)),
					   gen_rtx_LABEL_REF (VOIDmode,
							      operands[3]),
					   pc_rtx));
  emit_jump_insn (tem);
}

/* Certain simplifications can be done to make invalid setcc operations
   valid.  Return the final comparison, or NULL if we can't work.  */

bool
alpha_emit_setcc (rtx operands[], machine_mode cmp_mode)
{
  enum rtx_code cmp_code;
  enum rtx_code code = GET_CODE (operands[1]);
  rtx op0 = operands[2], op1 = operands[3];
  rtx tmp;

  if (cmp_mode == TFmode)
    {
      op0 = alpha_emit_xfloating_compare (&code, op0, op1);
      op1 = const0_rtx;
      cmp_mode = DImode;
    }

  if (cmp_mode == DFmode && !TARGET_FIX)
    return 0;

  /* The general case: fold the comparison code to the types of compares
     that we have, choosing the branch as necessary.  */

  cmp_code = UNKNOWN;
  switch (code)
    {
    case EQ:  case LE:  case LT:  case LEU:  case LTU:
    case UNORDERED:
      /* We have these compares.  */
      if (cmp_mode == DFmode)
	cmp_code = code, code = NE;
      break;

    case NE:
      if (cmp_mode == DImode && op1 == const0_rtx)
	break;
      /* FALLTHRU */

    case ORDERED:
      cmp_code = reverse_condition (code);
      code = EQ;
      break;

    case GE:  case GT: case GEU:  case GTU:
      /* These normally need swapping, but for integer zero we have
	 special patterns that recognize swapped operands.  */
      if (cmp_mode == DImode && op1 == const0_rtx)
	break;
      code = swap_condition (code);
      if (cmp_mode == DFmode)
	cmp_code = code, code = NE;
      std::swap (op0, op1);
      break;

    default:
      gcc_unreachable ();
    }

  if (cmp_mode == DImode)
    {
      if (!register_operand (op0, DImode))
	op0 = force_reg (DImode, op0);
      if (!reg_or_8bit_operand (op1, DImode))
	op1 = force_reg (DImode, op1);
    }

  /* Emit an initial compare instruction, if necessary.  */
  if (cmp_code != UNKNOWN)
    {
      tmp = gen_reg_rtx (cmp_mode);
      emit_insn (gen_rtx_SET (tmp, gen_rtx_fmt_ee (cmp_code, cmp_mode,
						   op0, op1)));

      op0 = cmp_mode != DImode ? gen_lowpart (DImode, tmp) : tmp;
      op1 = const0_rtx;
    }

  /* Emit the setcc instruction.  */
  emit_insn (gen_rtx_SET (operands[0], gen_rtx_fmt_ee (code, DImode,
						       op0, op1)));
  return true;
}


/* Rewrite a comparison against zero CMP of the form
   (CODE (cc0) (const_int 0)) so it can be written validly in
   a conditional move (if_then_else CMP ...).
   If both of the operands that set cc0 are nonzero we must emit
   an insn to perform the compare (it can't be done within
   the conditional move).  */

rtx
alpha_emit_conditional_move (rtx cmp, machine_mode mode)
{
  enum rtx_code code = GET_CODE (cmp);
  enum rtx_code cmov_code = NE;
  rtx op0 = XEXP (cmp, 0);
  rtx op1 = XEXP (cmp, 1);
  machine_mode cmp_mode
    = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
  machine_mode cmov_mode = VOIDmode;
  int local_fast_math = flag_unsafe_math_optimizations;
  rtx tem;

  if (cmp_mode == TFmode)
    {
      op0 = alpha_emit_xfloating_compare (&code, op0, op1);
      op1 = const0_rtx;
      cmp_mode = DImode;
    }

  gcc_assert (cmp_mode == DFmode || cmp_mode == DImode);

  if (FLOAT_MODE_P (cmp_mode) != FLOAT_MODE_P (mode))
    {
      enum rtx_code cmp_code;

      if (! TARGET_FIX)
	return 0;

      /* If we have fp<->int register move instructions, do a cmov by
	 performing the comparison in fp registers, and move the
	 zero/nonzero value to integer registers, where we can then
	 use a normal cmov, or vice-versa.  */

      switch (code)
	{
	case EQ: case LE: case LT: case LEU: case LTU:
	case UNORDERED:
	  /* We have these compares.  */
	  cmp_code = code, code = NE;
	  break;

	case NE:
	case ORDERED:
	  /* These must be reversed.  */
	  cmp_code = reverse_condition (code), code = EQ;
	  break;

	case GE: case GT: case GEU: case GTU:
	  /* These normally need swapping, but for integer zero we have
	     special patterns that recognize swapped operands.  */
	  if (cmp_mode == DImode && op1 == const0_rtx)
	    cmp_code = code, code = NE;
	  else
	    {
	      cmp_code = swap_condition (code);
	      code = NE;
	      std::swap (op0, op1);
	    }
	  break;

	default:
	  gcc_unreachable ();
	}

      if (cmp_mode == DImode)
	{
	  if (!reg_or_0_operand (op0, DImode))
	    op0 = force_reg (DImode, op0);
	  if (!reg_or_8bit_operand (op1, DImode))
	    op1 = force_reg (DImode, op1);
	}

      tem = gen_reg_rtx (cmp_mode);
      emit_insn (gen_rtx_SET (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode,
						   op0, op1)));

      cmp_mode = cmp_mode == DImode ? E_DFmode : E_DImode;
      op0 = gen_lowpart (cmp_mode, tem);
      op1 = CONST0_RTX (cmp_mode);
      cmp = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
      local_fast_math = 1;
    }

  if (cmp_mode == DImode)
    {
      if (!reg_or_0_operand (op0, DImode))
	op0 = force_reg (DImode, op0);
      if (!reg_or_8bit_operand (op1, DImode))
	op1 = force_reg (DImode, op1);
    }

  /* We may be able to use a conditional move directly.
     This avoids emitting spurious compares.  */
  if (signed_comparison_operator (cmp, VOIDmode)
      && (cmp_mode == DImode || local_fast_math)
      && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
    return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);

  /* We can't put the comparison inside the conditional move;
     emit a compare instruction and put that inside the
     conditional move.  Make sure we emit only comparisons we have;
     swap or reverse as necessary.  */

  if (!can_create_pseudo_p ())
    return NULL_RTX;

  switch (code)
    {
    case EQ:  case LE:  case LT:  case LEU:  case LTU:
    case UNORDERED:
      /* We have these compares: */
      break;

    case NE:
    case ORDERED:
      /* These must be reversed.  */
      code = reverse_condition (code);
      cmov_code = EQ;
      break;

    case GE:  case GT:  case GEU:  case GTU:
      /* These normally need swapping, but for integer zero we have
	 special patterns that recognize swapped operands.  */
      if (cmp_mode == DImode && op1 == const0_rtx)
	break;
      code = swap_condition (code);
      std::swap (op0, op1);
      break;

    default:
      gcc_unreachable ();
    }

  if (cmp_mode == DImode)
    {
      if (!reg_or_0_operand (op0, DImode))
	op0 = force_reg (DImode, op0);
      if (!reg_or_8bit_operand (op1, DImode))
	op1 = force_reg (DImode, op1);
    }

  /* ??? We mark the branch mode to be CCmode to prevent the compare
     and cmov from being combined, since the compare insn follows IEEE
     rules that the cmov does not.  */
  if (cmp_mode == DFmode && !local_fast_math)
    cmov_mode = CCmode;

  tem = gen_reg_rtx (cmp_mode);
  emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_mode, op0, op1));
  return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_mode));
}

/* Simplify a conditional move of two constants into a setcc with
   arithmetic.  This is done with a splitter since combine would
   just undo the work if done during code generation.  It also catches
   cases we wouldn't have before cse.  */

int
alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond,
			      rtx t_rtx, rtx f_rtx)
{
  HOST_WIDE_INT t, f, diff;
  machine_mode mode;
  rtx target, subtarget, tmp;

  mode = GET_MODE (dest);
  t = INTVAL (t_rtx);
  f = INTVAL (f_rtx);
  diff = t - f;

  if (((code == NE || code == EQ) && diff < 0)
      || (code == GE || code == GT))
    {
      code = reverse_condition (code);
      std::swap (t, f);
      diff = -diff;
    }

  subtarget = target = dest;
  if (mode != DImode)
    {
      target = gen_lowpart (DImode, dest);
      if (can_create_pseudo_p ())
        subtarget = gen_reg_rtx (DImode);
      else
	subtarget = target;
    }
  /* Below, we must be careful to use copy_rtx on target and subtarget
     in intermediate insns, as they may be a subreg rtx, which may not
     be shared.  */

  if (f == 0 && exact_log2 (diff) > 0
      /* On EV6, we've got enough shifters to make non-arithmetic shifts
	 viable over a longer latency cmove.  On EV5, the E0 slot is a
	 scarce resource, and on EV4 shift has the same latency as a cmove.  */
      && (diff <= 8 || alpha_tune == PROCESSOR_EV6))
    {
      tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
      emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp));

      tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
			    GEN_INT (exact_log2 (t)));
      emit_insn (gen_rtx_SET (target, tmp));
    }
  else if (f == 0 && t == -1)
    {
      tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
      emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp));

      emit_insn (gen_negdi2 (target, copy_rtx (subtarget)));
    }
  else if (diff == 1 || diff == 4 || diff == 8)
    {
      rtx add_op;

      tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
      emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp));

      if (diff == 1)
	emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f)));
      else
	{
	  add_op = GEN_INT (f);
	  if (sext_add_operand (add_op, mode))
	    {
	      tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
				    GEN_INT (exact_log2 (diff)));
	      tmp = gen_rtx_PLUS (DImode, tmp, add_op);
	      emit_insn (gen_rtx_SET (target, tmp));
	    }
	  else
	    return 0;
	}
    }
  else
    return 0;

  return 1;
}

/* Look up the function X_floating library function name for the
   given operation.  */

struct GTY(()) xfloating_op
{
  const enum rtx_code code;
  const char *const GTY((skip)) osf_func;
  const char *const GTY((skip)) vms_func;
  rtx libcall;
};

static GTY(()) struct xfloating_op xfloating_ops[] =
{
  { PLUS,		"_OtsAddX", "OTS$ADD_X", 0 },
  { MINUS,		"_OtsSubX", "OTS$SUB_X", 0 },
  { MULT,		"_OtsMulX", "OTS$MUL_X", 0 },
  { DIV,		"_OtsDivX", "OTS$DIV_X", 0 },
  { EQ,			"_OtsEqlX", "OTS$EQL_X", 0 },
  { NE,			"_OtsNeqX", "OTS$NEQ_X", 0 },
  { LT,			"_OtsLssX", "OTS$LSS_X", 0 },
  { LE,			"_OtsLeqX", "OTS$LEQ_X", 0 },
  { GT,			"_OtsGtrX", "OTS$GTR_X", 0 },
  { GE,			"_OtsGeqX", "OTS$GEQ_X", 0 },
  { FIX,		"_OtsCvtXQ", "OTS$CVTXQ", 0 },
  { FLOAT,		"_OtsCvtQX", "OTS$CVTQX", 0 },
  { UNSIGNED_FLOAT,	"_OtsCvtQUX", "OTS$CVTQUX", 0 },
  { FLOAT_EXTEND,	"_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 },
  { FLOAT_TRUNCATE,	"_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 }
};

static GTY(()) struct xfloating_op vax_cvt_ops[] =
{
  { FLOAT_EXTEND,	"_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 },
  { FLOAT_TRUNCATE,	"_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 }
};

static rtx
alpha_lookup_xfloating_lib_func (enum rtx_code code)
{
  struct xfloating_op *ops = xfloating_ops;
  long n = ARRAY_SIZE (xfloating_ops);
  long i;

  gcc_assert (TARGET_HAS_XFLOATING_LIBS);

  /* How irritating.  Nothing to key off for the main table.  */
  if (TARGET_FLOAT_VAX && (code == FLOAT_EXTEND || code == FLOAT_TRUNCATE))
    {
      ops = vax_cvt_ops;
      n = ARRAY_SIZE (vax_cvt_ops);
    }

  for (i = 0; i < n; ++i, ++ops)
    if (ops->code == code)
      {
	rtx func = ops->libcall;
	if (!func)
	  {
	    func = init_one_libfunc (TARGET_ABI_OPEN_VMS
				     ? ops->vms_func : ops->osf_func);
	    ops->libcall = func;
	  }
        return func;
      }

  gcc_unreachable ();
}

/* Most X_floating operations take the rounding mode as an argument.
   Compute that here.  */

static int
alpha_compute_xfloating_mode_arg (enum rtx_code code,
				  enum alpha_fp_rounding_mode round)
{
  int mode;

  switch (round)
    {
    case ALPHA_FPRM_NORM:
      mode = 2;
      break;
    case ALPHA_FPRM_MINF:
      mode = 1;
      break;
    case ALPHA_FPRM_CHOP:
      mode = 0;
      break;
    case ALPHA_FPRM_DYN:
      mode = 4;
      break;
    default:
      gcc_unreachable ();

    /* XXX For reference, round to +inf is mode = 3.  */
    }

  if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
    mode |= 0x10000;

  return mode;
}

/* Emit an X_floating library function call.

   Note that these functions do not follow normal calling conventions:
   TFmode arguments are passed in two integer registers (as opposed to
   indirect); TFmode return values appear in R16+R17.

   FUNC is the function to call.
   TARGET is where the output belongs.
   OPERANDS are the inputs.
   NOPERANDS is the count of inputs.
   EQUIV is the expression equivalent for the function.
*/

static void
alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
			      int noperands, rtx equiv)
{
  rtx usage = NULL_RTX, reg;
  int regno = 16, i;

  start_sequence ();

  for (i = 0; i < noperands; ++i)
    {
      switch (GET_MODE (operands[i]))
	{
	case E_TFmode:
	  reg = gen_rtx_REG (TFmode, regno);
	  regno += 2;
	  break;

	case E_DFmode:
	  reg = gen_rtx_REG (DFmode, regno + 32);
	  regno += 1;
	  break;

	case E_VOIDmode:
	  gcc_assert (CONST_INT_P (operands[i]));
	  /* FALLTHRU */
	case E_DImode:
	  reg = gen_rtx_REG (DImode, regno);
	  regno += 1;
	  break;

	default:
	  gcc_unreachable ();
	}

      emit_move_insn (reg, operands[i]);
      use_reg (&usage, reg);
    }

  switch (GET_MODE (target))
    {
    case E_TFmode:
      reg = gen_rtx_REG (TFmode, 16);
      break;
    case E_DFmode:
      reg = gen_rtx_REG (DFmode, 32);
      break;
    case E_DImode:
      reg = gen_rtx_REG (DImode, 0);
      break;
    default:
      gcc_unreachable ();
    }

  rtx mem = gen_rtx_MEM (QImode, func);
  rtx_insn *tmp = emit_call_insn (gen_call_value (reg, mem, const0_rtx,
						  const0_rtx, const0_rtx));
  CALL_INSN_FUNCTION_USAGE (tmp) = usage;
  RTL_CONST_CALL_P (tmp) = 1;

  tmp = get_insns ();
  end_sequence ();

  emit_libcall_block (tmp, target, reg, equiv);
}

/* Emit an X_floating library function call for arithmetic (+,-,*,/).  */

void
alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[])
{
  rtx func;
  int mode;
  rtx out_operands[3];

  func = alpha_lookup_xfloating_lib_func (code);
  mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);

  out_operands[0] = operands[1];
  out_operands[1] = operands[2];
  out_operands[2] = GEN_INT (mode);
  alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
				gen_rtx_fmt_ee (code, TFmode, operands[1],
						operands[2]));
}

/* Emit an X_floating library function call for a comparison.  */

static rtx
alpha_emit_xfloating_compare (enum rtx_code *pcode, rtx op0, rtx op1)
{
  enum rtx_code cmp_code, res_code;
  rtx func, out, operands[2], note;

  /* X_floating library comparison functions return
	   -1  unordered
	    0  false
	    1  true
     Convert the compare against the raw return value.  */

  cmp_code = *pcode;
  switch (cmp_code)
    {
    case UNORDERED:
      cmp_code = EQ;
      res_code = LT;
      break;
    case ORDERED:
      cmp_code = EQ;
      res_code = GE;
      break;
    case NE:
      res_code = NE;
      break;
    case EQ:
    case LT:
    case GT:
    case LE:
    case GE:
      res_code = GT;
      break;
    default:
      gcc_unreachable ();
    }
  *pcode = res_code;

  func = alpha_lookup_xfloating_lib_func (cmp_code);

  operands[0] = op0;
  operands[1] = op1;
  out = gen_reg_rtx (DImode);

  /* What's actually returned is -1,0,1, not a proper boolean value.  */
  note = gen_rtx_fmt_ee (cmp_code, VOIDmode, op0, op1);
  note = gen_rtx_UNSPEC (DImode, gen_rtvec (1, note), UNSPEC_XFLT_COMPARE);
  alpha_emit_xfloating_libcall (func, out, operands, 2, note);

  return out;
}

/* Emit an X_floating library function call for a conversion.  */

void
alpha_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[])
{
  int noperands = 1, mode;
  rtx out_operands[2];
  rtx func;
  enum rtx_code code = orig_code;

  if (code == UNSIGNED_FIX)
    code = FIX;

  func = alpha_lookup_xfloating_lib_func (code);

  out_operands[0] = operands[1];

  switch (code)
    {
    case FIX:
      mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
      out_operands[1] = GEN_INT (mode);
      noperands = 2;
      break;
    case FLOAT_TRUNCATE:
      mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
      out_operands[1] = GEN_INT (mode);
      noperands = 2;
      break;
    default:
      break;
    }

  alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
				gen_rtx_fmt_e (orig_code,
					       GET_MODE (operands[0]),
					       operands[1]));
}

/* Split a TImode or TFmode move from OP[1] to OP[0] into a pair of
   DImode moves from OP[2,3] to OP[0,1].  If FIXUP_OVERLAP is true,
   guarantee that the sequence
     set (OP[0] OP[2])
     set (OP[1] OP[3])
   is valid.  Naturally, output operand ordering is little-endian.
   This is used by *movtf_internal and *movti_internal.  */
  
void
alpha_split_tmode_pair (rtx operands[4], machine_mode mode,
			bool fixup_overlap)
{
  switch (GET_CODE (operands[1]))
    {
    case REG:
      operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
      operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
      break;

    case MEM:
      operands[3] = adjust_address (operands[1], DImode, 8);
      operands[2] = adjust_address (operands[1], DImode, 0);
      break;

    CASE_CONST_SCALAR_INT:
    case CONST_DOUBLE:
      gcc_assert (operands[1] == CONST0_RTX (mode));
      operands[2] = operands[3] = const0_rtx;
      break;

    default:
      gcc_unreachable ();
    }

  switch (GET_CODE (operands[0]))
    {
    case REG:
      operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
      operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
      break;

    case MEM:
      operands[1] = adjust_address (operands[0], DImode, 8);
      operands[0] = adjust_address (operands[0], DImode, 0);
      break;

    default:
      gcc_unreachable ();
    }

  if (fixup_overlap && reg_overlap_mentioned_p (operands[0], operands[3]))
    {
      std::swap (operands[0], operands[1]);
      std::swap (operands[2], operands[3]);
    }
}

/* Implement negtf2 or abstf2.  Op0 is destination, op1 is source,
   op2 is a register containing the sign bit, operation is the
   logical operation to be performed.  */

void
alpha_split_tfmode_frobsign (rtx operands[3], rtx (*operation) (rtx, rtx, rtx))
{
  rtx high_bit = operands[2];
  rtx scratch;
  int move;

  alpha_split_tmode_pair (operands, TFmode, false);

  /* Detect three flavors of operand overlap.  */
  move = 1;
  if (rtx_equal_p (operands[0], operands[2]))
    move = 0;
  else if (rtx_equal_p (operands[1], operands[2]))
    {
      if (rtx_equal_p (operands[0], high_bit))
	move = 2;
      else
	move = -1;
    }

  if (move < 0)
    emit_move_insn (operands[0], operands[2]);

  /* ??? If the destination overlaps both source tf and high_bit, then
     assume source tf is dead in its entirety and use the other half
     for a scratch register.  Otherwise "scratch" is just the proper
     destination register.  */
  scratch = operands[move < 2 ? 1 : 3];

  emit_insn ((*operation) (scratch, high_bit, operands[3]));

  if (move > 0)
    {
      emit_move_insn (operands[0], operands[2]);
      if (move > 1)
	emit_move_insn (operands[1], scratch);
    }
}

/* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
   unaligned data:

           unsigned:                       signed:
   word:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
           ldq_u  r2,X+1(r11)              ldq_u  r2,X+1(r11)
           lda    r3,X(r11)                lda    r3,X+2(r11)
           extwl  r1,r3,r1                 extql  r1,r3,r1
           extwh  r2,r3,r2                 extqh  r2,r3,r2
           or     r1.r2.r1                 or     r1,r2,r1
                                           sra    r1,48,r1

   long:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
           ldq_u  r2,X+3(r11)              ldq_u  r2,X+3(r11)
           lda    r3,X(r11)                lda    r3,X(r11)
           extll  r1,r3,r1                 extll  r1,r3,r1
           extlh  r2,r3,r2                 extlh  r2,r3,r2
           or     r1.r2.r1                 addl   r1,r2,r1

   quad:   ldq_u  r1,X(r11)
           ldq_u  r2,X+7(r11)
           lda    r3,X(r11)
           extql  r1,r3,r1
           extqh  r2,r3,r2
           or     r1.r2.r1
*/

void
alpha_expand_unaligned_load (rtx tgt, rtx mem, HOST_WIDE_INT size,
			     HOST_WIDE_INT ofs, int sign)
{
  rtx meml, memh, addr, extl, exth, tmp, mema;
  machine_mode mode;

  if (TARGET_BWX && size == 2)
    {
      meml = adjust_address (mem, QImode, ofs);
      memh = adjust_address (mem, QImode, ofs+1);
      extl = gen_reg_rtx (DImode);
      exth = gen_reg_rtx (DImode);
      emit_insn (gen_zero_extendqidi2 (extl, meml));
      emit_insn (gen_zero_extendqidi2 (exth, memh));
      exth = expand_simple_binop (DImode, ASHIFT, exth, GEN_INT (8),
				  NULL, 1, OPTAB_LIB_WIDEN);
      addr = expand_simple_binop (DImode, IOR, extl, exth,
				  NULL, 1, OPTAB_LIB_WIDEN);

      if (sign && GET_MODE (tgt) != HImode)
	{
	  addr = gen_lowpart (HImode, addr);
	  emit_insn (gen_extend_insn (tgt, addr, GET_MODE (tgt), HImode, 0));
	}
      else
	{
	  if (GET_MODE (tgt) != DImode)
	    addr = gen_lowpart (GET_MODE (tgt), addr);
	  emit_move_insn (tgt, addr);
	}
      return;
    }

  meml = gen_reg_rtx (DImode);
  memh = gen_reg_rtx (DImode);
  addr = gen_reg_rtx (DImode);
  extl = gen_reg_rtx (DImode);
  exth = gen_reg_rtx (DImode);

  mema = XEXP (mem, 0);
  if (GET_CODE (mema) == LO_SUM)
    mema = force_reg (Pmode, mema);

  /* AND addresses cannot be in any alias set, since they may implicitly
     alias surrounding code.  Ideally we'd have some alias set that
     covered all types except those with alignment 8 or higher.  */

  tmp = change_address (mem, DImode,
			gen_rtx_AND (DImode,
				     plus_constant (DImode, mema, ofs),
				     GEN_INT (-8)));
  set_mem_alias_set (tmp, 0);
  emit_move_insn (meml, tmp);

  tmp = change_address (mem, DImode,
			gen_rtx_AND (DImode,
				     plus_constant (DImode, mema,
						    ofs + size - 1),
				     GEN_INT (-8)));
  set_mem_alias_set (tmp, 0);
  emit_move_insn (memh, tmp);

  if (sign && size == 2)
    {
      emit_move_insn (addr, plus_constant (Pmode, mema, ofs+2));

      emit_insn (gen_extql (extl, meml, addr));
      emit_insn (gen_extqh (exth, memh, addr));

      /* We must use tgt here for the target.  Alpha-vms port fails if we use
	 addr for the target, because addr is marked as a pointer and combine
	 knows that pointers are always sign-extended 32-bit values.  */
      addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
      addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
			   addr, 1, OPTAB_WIDEN);
    }
  else
    {
      emit_move_insn (addr, plus_constant (Pmode, mema, ofs));
      emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
      switch ((int) size)
	{
	case 2:
	  emit_insn (gen_extwh (exth, memh, addr));
	  mode = HImode;
	  break;
	case 4:
	  emit_insn (gen_extlh (exth, memh, addr));
	  mode = SImode;
	  break;
	case 8:
	  emit_insn (gen_extqh (exth, memh, addr));
	  mode = DImode;
	  break;
	default:
	  gcc_unreachable ();
	}

      addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
			   gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
			   sign, OPTAB_WIDEN);
    }

  if (addr != tgt)
    emit_move_insn (tgt, gen_lowpart (GET_MODE (tgt), addr));
}

/* Similarly, use ins and msk instructions to perform unaligned stores.  */

void
alpha_expand_unaligned_store (rtx dst, rtx src,
			      HOST_WIDE_INT size, HOST_WIDE_INT ofs)
{
  rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;

  if (TARGET_BWX && size == 2)
    {
      if (src != const0_rtx)
	{
	  dstl = gen_lowpart (QImode, src);
	  dsth = expand_simple_binop (DImode, LSHIFTRT, src, GEN_INT (8),
				      NULL, 1, OPTAB_LIB_WIDEN);
	  dsth = gen_lowpart (QImode, dsth);
	}
      else
	dstl = dsth = const0_rtx;

      meml = adjust_address (dst, QImode, ofs);
      memh = adjust_address (dst, QImode, ofs+1);

      emit_move_insn (meml, dstl);
      emit_move_insn (memh, dsth);
      return;
    }

  dstl = gen_reg_rtx (DImode);
  dsth = gen_reg_rtx (DImode);
  insl = gen_reg_rtx (DImode);
  insh = gen_reg_rtx (DImode);

  dsta = XEXP (dst, 0);
  if (GET_CODE (dsta) == LO_SUM)
    dsta = force_reg (Pmode, dsta);

  /* AND addresses cannot be in any alias set, since they may implicitly
     alias surrounding code.  Ideally we'd have some alias set that
     covered all types except those with alignment 8 or higher.  */

  meml = change_address (dst, DImode,
			 gen_rtx_AND (DImode,
				      plus_constant (DImode, dsta, ofs),
				      GEN_INT (-8)));
  set_mem_alias_set (meml, 0);

  memh = change_address (dst, DImode,
			 gen_rtx_AND (DImode,
				      plus_constant (DImode, dsta,
						     ofs + size - 1),
				      GEN_INT (-8)));
  set_mem_alias_set (memh, 0);

  emit_move_insn (dsth, memh);
  emit_move_insn (dstl, meml);

  addr = copy_addr_to_reg (plus_constant (Pmode, dsta, ofs));

  if (src != CONST0_RTX (GET_MODE (src)))
    {
      emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
			    GEN_INT (size*8), addr));

      switch ((int) size)
	{
	case 2:
	  emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
	  break;
	case 4:
	  emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
	  break;
	case 8:
	  emit_insn (gen_insql (insl, gen_lowpart (DImode, src), addr));
	  break;
	default:
	  gcc_unreachable ();
	}
    }

  emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));

  switch ((int) size)
    {
    case 2:
      emit_insn (gen_mskwl (dstl, dstl, addr));
      break;
    case 4:
      emit_insn (gen_mskll (dstl, dstl, addr));
      break;
    case 8:
      emit_insn (gen_mskql (dstl, dstl, addr));
      break;
    default:
      gcc_unreachable ();
    }

  if (src != CONST0_RTX (GET_MODE (src)))
    {
      dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
      dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
    }

  /* Must store high before low for degenerate case of aligned.  */
  emit_move_insn (memh, dsth);
  emit_move_insn (meml, dstl);
}

/* The block move code tries to maximize speed by separating loads and
   stores at the expense of register pressure: we load all of the data
   before we store it back out.  There are two secondary effects worth
   mentioning, that this speeds copying to/from aligned and unaligned
   buffers, and that it makes the code significantly easier to write.  */

#define MAX_MOVE_WORDS	8

/* Load an integral number of consecutive unaligned quadwords.  */

static void
alpha_expand_unaligned_load_words (rtx *out_regs, rtx smem,
				   HOST_WIDE_INT words, HOST_WIDE_INT ofs)
{
  rtx const im8 = GEN_INT (-8);
  rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
  rtx sreg, areg, tmp, smema;
  HOST_WIDE_INT i;

  smema = XEXP (smem, 0);
  if (GET_CODE (smema) == LO_SUM)
    smema = force_reg (Pmode, smema);

  /* Generate all the tmp registers we need.  */
  for (i = 0; i < words; ++i)
    {
      data_regs[i] = out_regs[i];
      ext_tmps[i] = gen_reg_rtx (DImode);
    }
  data_regs[words] = gen_reg_rtx (DImode);

  if (ofs != 0)
    smem = adjust_address (smem, GET_MODE (smem), ofs);

  /* Load up all of the source data.  */
  for (i = 0; i < words; ++i)
    {
      tmp = change_address (smem, DImode,
			    gen_rtx_AND (DImode,
					 plus_constant (DImode, smema, 8*i),
					 im8));
      set_mem_alias_set (tmp, 0);
      emit_move_insn (data_regs[i], tmp);
    }

  tmp = change_address (smem, DImode,
			gen_rtx_AND (DImode,
				     plus_constant (DImode, smema,
						    8*words - 1),
				     im8));
  set_mem_alias_set (tmp, 0);
  emit_move_insn (data_regs[words], tmp);

  /* Extract the half-word fragments.  Unfortunately DEC decided to make
     extxh with offset zero a noop instead of zeroing the register, so
     we must take care of that edge condition ourselves with cmov.  */

  sreg = copy_addr_to_reg (smema);
  areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
		       1, OPTAB_WIDEN);
  for (i = 0; i < words; ++i)
    {
      emit_insn (gen_extql (data_regs[i], data_regs[i], sreg));
      emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
      emit_insn (gen_rtx_SET (ext_tmps[i],
			      gen_rtx_IF_THEN_ELSE (DImode,
						    gen_rtx_EQ (DImode, areg,
								const0_rtx),
						    const0_rtx, ext_tmps[i])));
    }

  /* Merge the half-words into whole words.  */
  for (i = 0; i < words; ++i)
    {
      out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
				  ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
    }
}

/* Store an integral number of consecutive unaligned quadwords.  DATA_REGS
   may be NULL to store zeros.  */

static void
alpha_expand_unaligned_store_words (rtx *data_regs, rtx dmem,
				    HOST_WIDE_INT words, HOST_WIDE_INT ofs)
{
  rtx const im8 = GEN_INT (-8);
  rtx ins_tmps[MAX_MOVE_WORDS];
  rtx st_tmp_1, st_tmp_2, dreg;
  rtx st_addr_1, st_addr_2, dmema;
  HOST_WIDE_INT i;

  dmema = XEXP (dmem, 0);
  if (GET_CODE (dmema) == LO_SUM)
    dmema = force_reg (Pmode, dmema);

  /* Generate all the tmp registers we need.  */
  if (data_regs != NULL)
    for (i = 0; i < words; ++i)
      ins_tmps[i] = gen_reg_rtx(DImode);
  st_tmp_1 = gen_reg_rtx(DImode);
  st_tmp_2 = gen_reg_rtx(DImode);

  if (ofs != 0)
    dmem = adjust_address (dmem, GET_MODE (dmem), ofs);

  st_addr_2 = change_address (dmem, DImode,
			      gen_rtx_AND (DImode,
					   plus_constant (DImode, dmema,
							  words*8 - 1),
					   im8));
  set_mem_alias_set (st_addr_2, 0);

  st_addr_1 = change_address (dmem, DImode,
			      gen_rtx_AND (DImode, dmema, im8));
  set_mem_alias_set (st_addr_1, 0);

  /* Load up the destination end bits.  */
  emit_move_insn (st_tmp_2, st_addr_2);
  emit_move_insn (st_tmp_1, st_addr_1);

  /* Shift the input data into place.  */
  dreg = copy_addr_to_reg (dmema);
  if (data_regs != NULL)
    {
      for (i = words-1; i >= 0; --i)
	{
	  emit_insn (gen_insqh (ins_tmps[i], data_regs[i], dreg));
	  emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
	}
      for (i = words-1; i > 0; --i)
	{
	  ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
					ins_tmps[i-1], ins_tmps[i-1], 1,
					OPTAB_WIDEN);
	}
    }

  /* Split and merge the ends with the destination data.  */
  emit_insn (gen_mskqh (st_tmp_2, st_tmp_2, dreg));
  emit_insn (gen_mskql (st_tmp_1, st_tmp_1, dreg));

  if (data_regs != NULL)
    {
      st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
			       st_tmp_2, 1, OPTAB_WIDEN);
      st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
			       st_tmp_1, 1, OPTAB_WIDEN);
    }

  /* Store it all.  */
  emit_move_insn (st_addr_2, st_tmp_2);
  for (i = words-1; i > 0; --i)
    {
      rtx tmp = change_address (dmem, DImode,
				gen_rtx_AND (DImode,
					     plus_constant (DImode,
							    dmema, i*8),
					     im8));
      set_mem_alias_set (tmp, 0);
      emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
    }
  emit_move_insn (st_addr_1, st_tmp_1);
}


/* Expand string/block move operations.

   operands[0] is the pointer to the destination.
   operands[1] is the pointer to the source.
   operands[2] is the number of bytes to move.
   operands[3] is the alignment.  */

int
alpha_expand_block_move (rtx operands[])
{
  rtx bytes_rtx	= operands[2];
  rtx align_rtx = operands[3];
  HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
  HOST_WIDE_INT bytes = orig_bytes;
  HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
  HOST_WIDE_INT dst_align = src_align;
  rtx orig_src = operands[1];
  rtx orig_dst = operands[0];
  rtx data_regs[2 * MAX_MOVE_WORDS + 16];
  rtx tmp;
  unsigned int i, words, ofs, nregs = 0;

  if (orig_bytes <= 0)
    return 1;
  else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
    return 0;

  /* Look for additional alignment information from recorded register info.  */

  tmp = XEXP (orig_src, 0);
  if (REG_P (tmp))
    src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
  else if (GET_CODE (tmp) == PLUS
	   && REG_P (XEXP (tmp, 0))
	   && CONST_INT_P (XEXP (tmp, 1)))
    {
      unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
      unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));

      if (a > src_align)
	{
          if (a >= 64 && c % 8 == 0)
	    src_align = 64;
          else if (a >= 32 && c % 4 == 0)
	    src_align = 32;
          else if (a >= 16 && c % 2 == 0)
	    src_align = 16;
	}
    }

  tmp = XEXP (orig_dst, 0);
  if (REG_P (tmp))
    dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
  else if (GET_CODE (tmp) == PLUS
	   && REG_P (XEXP (tmp, 0))
	   && CONST_INT_P (XEXP (tmp, 1)))
    {
      unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
      unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));

      if (a > dst_align)
	{
          if (a >= 64 && c % 8 == 0)
	    dst_align = 64;
          else if (a >= 32 && c % 4 == 0)
	    dst_align = 32;
          else if (a >= 16 && c % 2 == 0)
	    dst_align = 16;
	}
    }

  ofs = 0;
  if (src_align >= 64 && bytes >= 8)
    {
      words = bytes / 8;

      for (i = 0; i < words; ++i)
	data_regs[nregs + i] = gen_reg_rtx (DImode);

      for (i = 0; i < words; ++i)
	emit_move_insn (data_regs[nregs + i],
			adjust_address (orig_src, DImode, ofs + i * 8));

      nregs += words;
      bytes -= words * 8;
      ofs += words * 8;
    }

  if (src_align >= 32 && bytes >= 4)
    {
      words = bytes / 4;

      for (i = 0; i < words; ++i)
	data_regs[nregs + i] = gen_reg_rtx (SImode);

      for (i = 0; i < words; ++i)
	emit_move_insn (data_regs[nregs + i],
			adjust_address (orig_src, SImode, ofs + i * 4));

      nregs += words;
      bytes -= words * 4;
      ofs += words * 4;
    }

  if (bytes >= 8)
    {
      words = bytes / 8;

      for (i = 0; i < words+1; ++i)
	data_regs[nregs + i] = gen_reg_rtx (DImode);

      alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
					 words, ofs);

      nregs += words;
      bytes -= words * 8;
      ofs += words * 8;
    }

  if (! TARGET_BWX && bytes >= 4)
    {
      data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
      alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
      bytes -= 4;
      ofs += 4;
    }

  if (bytes >= 2)
    {
      if (src_align >= 16)
	{
	  do {
	    data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
	    emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs));
	    bytes -= 2;
	    ofs += 2;
	  } while (bytes >= 2);
	}
      else if (! TARGET_BWX)
	{
	  data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
	  alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
	  bytes -= 2;
	  ofs += 2;
	}
    }

  while (bytes > 0)
    {
      data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
      emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs));
      bytes -= 1;
      ofs += 1;
    }

  gcc_assert (nregs <= ARRAY_SIZE (data_regs));

  /* Now save it back out again.  */

  i = 0, ofs = 0;

  /* Write out the data in whatever chunks reading the source allowed.  */
  if (dst_align >= 64)
    {
      while (i < nregs && GET_MODE (data_regs[i]) == DImode)
	{
	  emit_move_insn (adjust_address (orig_dst, DImode, ofs),
			  data_regs[i]);
	  ofs += 8;
	  i++;
	}
    }

  if (dst_align >= 32)
    {
      /* If the source has remaining DImode regs, write them out in
	 two pieces.  */
      while (i < nregs && GET_MODE (data_regs[i]) == DImode)
	{
	  tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
			      NULL_RTX, 1, OPTAB_WIDEN);

	  emit_move_insn (adjust_address (orig_dst, SImode, ofs),
			  gen_lowpart (SImode, data_regs[i]));
	  emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4),
			  gen_lowpart (SImode, tmp));
	  ofs += 8;
	  i++;
	}

      while (i < nregs && GET_MODE (data_regs[i]) == SImode)
	{
	  emit_move_insn (adjust_address (orig_dst, SImode, ofs),
			  data_regs[i]);
	  ofs += 4;
	  i++;
	}
    }

  if (i < nregs && GET_MODE (data_regs[i]) == DImode)
    {
      /* Write out a remaining block of words using unaligned methods.  */

      for (words = 1; i + words < nregs; words++)
	if (GET_MODE (data_regs[i + words]) != DImode)
	  break;

      if (words == 1)
	alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
      else
        alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
					    words, ofs);

      i += words;
      ofs += words * 8;
    }

  /* Due to the above, this won't be aligned.  */
  /* ??? If we have more than one of these, consider constructing full
     words in registers and using alpha_expand_unaligned_store_words.  */
  while (i < nregs && GET_MODE (data_regs[i]) == SImode)
    {
      alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
      ofs += 4;
      i++;
    }

  if (dst_align >= 16)
    while (i < nregs && GET_MODE (data_regs[i]) == HImode)
      {
	emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]);
	i++;
	ofs += 2;
      }
  else
    while (i < nregs && GET_MODE (data_regs[i]) == HImode)
      {
	alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
	i++;
	ofs += 2;
      }

  /* The remainder must be byte copies.  */
  while (i < nregs)
    {
      gcc_assert (GET_MODE (data_regs[i]) == QImode);
      emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]);
      i++;
      ofs += 1;
    }

  return 1;
}

int
alpha_expand_block_clear (rtx operands[])
{
  rtx bytes_rtx	= operands[1];
  rtx align_rtx = operands[3];
  HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
  HOST_WIDE_INT bytes = orig_bytes;
  HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;
  HOST_WIDE_INT alignofs = 0;
  rtx orig_dst = operands[0];
  rtx tmp;
  int i, words, ofs = 0;

  if (orig_bytes <= 0)
    return 1;
  if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
    return 0;

  /* Look for stricter alignment.  */
  tmp = XEXP (orig_dst, 0);
  if (REG_P (tmp))
    align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
  else if (GET_CODE (tmp) == PLUS
	   && REG_P (XEXP (tmp, 0))
	   && CONST_INT_P (XEXP (tmp, 1)))
    {
      HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
      int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));

      if (a > align)
	{
          if (a >= 64)
	    align = a, alignofs = 8 - c % 8;
          else if (a >= 32)
	    align = a, alignofs = 4 - c % 4;
          else if (a >= 16)
	    align = a, alignofs = 2 - c % 2;
	}
    }

  /* Handle an unaligned prefix first.  */

  if (alignofs > 0)
    {
      /* Given that alignofs is bounded by align, the only time BWX could
	 generate three stores is for a 7 byte fill.  Prefer two individual
	 stores over a load/mask/store sequence.  */
      if ((!TARGET_BWX || alignofs == 7)
	       && align >= 32
	       && !(alignofs == 4 && bytes >= 4))
	{
	  machine_mode mode = (align >= 64 ? DImode : SImode);
	  int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
	  rtx mem, tmp;
	  HOST_WIDE_INT mask;

	  mem = adjust_address (orig_dst, mode, ofs - inv_alignofs);
	  set_mem_alias_set (mem, 0);

	  mask = ~(HOST_WIDE_INT_M1U << (inv_alignofs * 8));
	  if (bytes < alignofs)
	    {
	      mask |= HOST_WIDE_INT_M1U << ((inv_alignofs + bytes) * 8);
	      ofs += bytes;
	      bytes = 0;
	    }
	  else
	    {
	      bytes -= alignofs;
	      ofs += alignofs;
	    }
	  alignofs = 0;

	  tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask),
			      NULL_RTX, 1, OPTAB_WIDEN);

	  emit_move_insn (mem, tmp);
	}

      if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
	{
	  emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
	  bytes -= 1;
	  ofs += 1;
	  alignofs -= 1;
	}
      if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2)
	{
	  emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx);
	  bytes -= 2;
	  ofs += 2;
	  alignofs -= 2;
	}
      if (alignofs == 4 && bytes >= 4)
	{
	  emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
	  bytes -= 4;
	  ofs += 4;
	  alignofs = 0;
	}

      /* If we've not used the extra lead alignment information by now,
	 we won't be able to.  Downgrade align to match what's left over.  */
      if (alignofs > 0)
	{
	  alignofs = alignofs & -alignofs;
	  align = MIN (align, alignofs * BITS_PER_UNIT);
	}
    }

  /* Handle a block of contiguous long-words.  */

  if (align >= 64 && bytes >= 8)
    {
      words = bytes / 8;

      for (i = 0; i < words; ++i)
	emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8),
			const0_rtx);

      bytes -= words * 8;
      ofs += words * 8;
    }

  /* If the block is large and appropriately aligned, emit a single
     store followed by a sequence of stq_u insns.  */

  if (align >= 32 && bytes > 16)
    {
      rtx orig_dsta;

      emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
      bytes -= 4;
      ofs += 4;

      orig_dsta = XEXP (orig_dst, 0);
      if (GET_CODE (orig_dsta) == LO_SUM)
	orig_dsta = force_reg (Pmode, orig_dsta);

      words = bytes / 8;
      for (i = 0; i < words; ++i)
	{
	  rtx mem
	    = change_address (orig_dst, DImode,
			      gen_rtx_AND (DImode,
					   plus_constant (DImode, orig_dsta,
							  ofs + i*8),
					   GEN_INT (-8)));
	  set_mem_alias_set (mem, 0);
	  emit_move_insn (mem, const0_rtx);
	}

      /* Depending on the alignment, the first stq_u may have overlapped
	 with the initial stl, which means that the last stq_u didn't
	 write as much as it would appear.  Leave those questionable bytes
	 unaccounted for.  */
      bytes -= words * 8 - 4;
      ofs += words * 8 - 4;
    }

  /* Handle a smaller block of aligned words.  */

  if ((align >= 64 && bytes == 4)
      || (align == 32 && bytes >= 4))
    {
      words = bytes / 4;

      for (i = 0; i < words; ++i)
	emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4),
			const0_rtx);

      bytes -= words * 4;
      ofs += words * 4;
    }

  /* An unaligned block uses stq_u stores for as many as possible.  */

  if (bytes >= 8)
    {
      words = bytes / 8;

      alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);

      bytes -= words * 8;
      ofs += words * 8;
    }

  /* Next clean up any trailing pieces.  */

  /* Count the number of bits in BYTES for which aligned stores could
     be emitted.  */
  words = 0;
  for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1)
    if (bytes & i)
      words += 1;

  /* If we have appropriate alignment (and it wouldn't take too many
     instructions otherwise), mask out the bytes we need.  */
  if (TARGET_BWX ? words > 2 : bytes > 0)
    {
      if (align >= 64)
	{
	  rtx mem, tmp;
	  HOST_WIDE_INT mask;

	  mem = adjust_address (orig_dst, DImode, ofs);
	  set_mem_alias_set (mem, 0);

	  mask = HOST_WIDE_INT_M1U << (bytes * 8);

	  tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
			      NULL_RTX, 1, OPTAB_WIDEN);

	  emit_move_insn (mem, tmp);
	  return 1;
	}
      else if (align >= 32 && bytes < 4)
	{
	  rtx mem, tmp;
	  HOST_WIDE_INT mask;

	  mem = adjust_address (orig_dst, SImode, ofs);
	  set_mem_alias_set (mem, 0);

	  mask = HOST_WIDE_INT_M1U << (bytes * 8);

	  tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
			      NULL_RTX, 1, OPTAB_WIDEN);

	  emit_move_insn (mem, tmp);
	  return 1;
	}
    }

  if (!TARGET_BWX && bytes >= 4)
    {
      alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
      bytes -= 4;
      ofs += 4;
    }

  if (bytes >= 2)
    {
      if (align >= 16)
	{
	  do {
	    emit_move_insn (adjust_address (orig_dst, HImode, ofs),
			    const0_rtx);
	    bytes -= 2;
	    ofs += 2;
	  } while (bytes >= 2);
	}
      else if (! TARGET_BWX)
	{
	  alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
	  bytes -= 2;
	  ofs += 2;
	}
    }

  while (bytes > 0)
    {
      emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
      bytes -= 1;
      ofs += 1;
    }

  return 1;
}

/* Returns a mask so that zap(x, value) == x & mask.  */

rtx
alpha_expand_zap_mask (HOST_WIDE_INT value)
{
  rtx result;
  int i;
  HOST_WIDE_INT mask = 0;

  for (i = 7; i >= 0; --i)
    {
      mask <<= 8;
      if (!((value >> i) & 1))
	mask |= 0xff;
    }

  result = gen_int_mode (mask, DImode);
  return result;
}

void
alpha_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx),
				   machine_mode mode,
				   rtx op0, rtx op1, rtx op2)
{
  op0 = gen_lowpart (mode, op0);

  if (op1 == const0_rtx)
    op1 = CONST0_RTX (mode);
  else
    op1 = gen_lowpart (mode, op1);

  if (op2 == const0_rtx)
    op2 = CONST0_RTX (mode);
  else
    op2 = gen_lowpart (mode, op2);

  emit_insn ((*gen) (op0, op1, op2));
}

/* A subroutine of the atomic operation splitters.  Jump to LABEL if
   COND is true.  Mark the jump as unlikely to be taken.  */

static void
emit_unlikely_jump (rtx cond, rtx label)
{
  rtx x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
  rtx_insn *insn = emit_jump_insn (gen_rtx_SET (pc_rtx, x));
  add_reg_br_prob_note (insn, profile_probability::very_unlikely ());
}

/* Subroutines of the atomic operation splitters.  Emit barriers
   as needed for the memory MODEL.  */

static void
alpha_pre_atomic_barrier (enum memmodel model)
{
  if (need_atomic_barrier_p (model, true))
    emit_insn (gen_memory_barrier ());
}

static void
alpha_post_atomic_barrier (enum memmodel model)
{
  if (need_atomic_barrier_p (model, false))
    emit_insn (gen_memory_barrier ());
}

/* A subroutine of the atomic operation splitters.  Emit an insxl
   instruction in MODE.  */

static rtx
emit_insxl (machine_mode mode, rtx op1, rtx op2)
{
  rtx ret = gen_reg_rtx (DImode);
  rtx (*fn) (rtx, rtx, rtx);

  switch (mode)
    {
    case E_QImode:
      fn = gen_insbl;
      break;
    case E_HImode:
      fn = gen_inswl;
      break;
    case E_SImode:
      fn = gen_insll;
      break;
    case E_DImode:
      fn = gen_insql;
      break;
    default:
      gcc_unreachable ();
    }

  op1 = force_reg (mode, op1);
  emit_insn (fn (ret, op1, op2));

  return ret;
}

/* Expand an atomic fetch-and-operate pattern.  CODE is the binary operation
   to perform.  MEM is the memory on which to operate.  VAL is the second 
   operand of the binary operator.  BEFORE and AFTER are optional locations to
   return the value of MEM either before of after the operation.  SCRATCH is
   a scratch register.  */

void
alpha_split_atomic_op (enum rtx_code code, rtx mem, rtx val, rtx before,
		       rtx after, rtx scratch, enum memmodel model)
{
  machine_mode mode = GET_MODE (mem);
  rtx label, x, cond = gen_rtx_REG (DImode, REGNO (scratch));

  alpha_pre_atomic_barrier (model);

  label = gen_label_rtx ();
  emit_label (label);
  label = gen_rtx_LABEL_REF (DImode, label);

  if (before == NULL)
    before = scratch;
  emit_insn (gen_load_locked (mode, before, mem));

  if (code == NOT)
    {
      x = gen_rtx_AND (mode, before, val);
      emit_insn (gen_rtx_SET (val, x));

      x = gen_rtx_NOT (mode, val);
    }
  else
    x = gen_rtx_fmt_ee (code, mode, before, val);
  if (after)
    emit_insn (gen_rtx_SET (after, copy_rtx (x)));
  emit_insn (gen_rtx_SET (scratch, x));

  emit_insn (gen_store_conditional (mode, cond, mem, scratch));

  x = gen_rtx_EQ (DImode, cond, const0_rtx);
  emit_unlikely_jump (x, label);

  alpha_post_atomic_barrier (model);
}

/* Expand a compare and swap operation.  */

void
alpha_split_compare_and_swap (rtx operands[])
{
  rtx cond, retval, mem, oldval, newval;
  bool is_weak;
  enum memmodel mod_s, mod_f;
  machine_mode mode;
  rtx label1, label2, x;

  cond = operands[0];
  retval = operands[1];
  mem = operands[2];
  oldval = operands[3];
  newval = operands[4];
  is_weak = (operands[5] != const0_rtx);
  mod_s = memmodel_from_int (INTVAL (operands[6]));
  mod_f = memmodel_from_int (INTVAL (operands[7]));
  mode = GET_MODE (mem);

  alpha_pre_atomic_barrier (mod_s);

  label1 = NULL_RTX;
  if (!is_weak)
    {
      label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
      emit_label (XEXP (label1, 0));
    }
  label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());

  emit_insn (gen_load_locked (mode, retval, mem));

  x = gen_lowpart (DImode, retval);
  if (oldval == const0_rtx)
    {
      emit_move_insn (cond, const0_rtx);
      x = gen_rtx_NE (DImode, x, const0_rtx);
    }
  else
    {
      x = gen_rtx_EQ (DImode, x, oldval);
      emit_insn (gen_rtx_SET (cond, x));
      x = gen_rtx_EQ (DImode, cond, const0_rtx);
    }
  emit_unlikely_jump (x, label2);

  emit_move_insn (cond, newval);
  emit_insn (gen_store_conditional
	     (mode, cond, mem, gen_lowpart (mode, cond)));

  if (!is_weak)
    {
      x = gen_rtx_EQ (DImode, cond, const0_rtx);
      emit_unlikely_jump (x, label1);
    }

  if (!is_mm_relaxed (mod_f))
    emit_label (XEXP (label2, 0));

  alpha_post_atomic_barrier (mod_s);

  if (is_mm_relaxed (mod_f))
    emit_label (XEXP (label2, 0));
}

void
alpha_expand_compare_and_swap_12 (rtx operands[])
{
  rtx cond, dst, mem, oldval, newval, is_weak, mod_s, mod_f;
  machine_mode mode;
  rtx addr, align, wdst;

  cond = operands[0];
  dst = operands[1];
  mem = operands[2];
  oldval = operands[3];
  newval = operands[4];
  is_weak = operands[5];
  mod_s = operands[6];
  mod_f = operands[7];
  mode = GET_MODE (mem);

  /* We forced the address into a register via mem_noofs_operand.  */
  addr = XEXP (mem, 0);
  gcc_assert (register_operand (addr, DImode));

  align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8),
			       NULL_RTX, 1, OPTAB_DIRECT);

  oldval = convert_modes (DImode, mode, oldval, 1);

  if (newval != const0_rtx)
    newval = emit_insxl (mode, newval, addr);

  wdst = gen_reg_rtx (DImode);
  emit_insn (gen_atomic_compare_and_swap_1
	     (mode, cond, wdst, mem, oldval, newval, align,
	      is_weak, mod_s, mod_f));

  emit_move_insn (dst, gen_lowpart (mode, wdst));
}

void
alpha_split_compare_and_swap_12 (rtx operands[])
{
  rtx cond, dest, orig_mem, oldval, newval, align, scratch;
  machine_mode mode;
  bool is_weak;
  enum memmodel mod_s, mod_f;
  rtx label1, label2, mem, addr, width, mask, x;

  cond = operands[0];
  dest = operands[1];
  orig_mem = operands[2];
  oldval = operands[3];
  newval = operands[4];
  align = operands[5];
  is_weak = (operands[6] != const0_rtx);
  mod_s = memmodel_from_int (INTVAL (operands[7]));
  mod_f = memmodel_from_int (INTVAL (operands[8]));
  scratch = operands[9];
  mode = GET_MODE (orig_mem);
  addr = XEXP (orig_mem, 0);

  mem = gen_rtx_MEM (DImode, align);
  MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem);
  if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER)
    set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);

  alpha_pre_atomic_barrier (mod_s);

  label1 = NULL_RTX;
  if (!is_weak)
    {
      label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
      emit_label (XEXP (label1, 0));
    }
  label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());

  emit_insn (gen_load_locked (DImode, scratch, mem));
  
  width = GEN_INT (GET_MODE_BITSIZE (mode));
  mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
  emit_insn (gen_extxl (dest, scratch, width, addr));

  if (oldval == const0_rtx)
    {
      emit_move_insn (cond, const0_rtx);
      x = gen_rtx_NE (DImode, dest, const0_rtx);
    }
  else
    {
      x = gen_rtx_EQ (DImode, dest, oldval);
      emit_insn (gen_rtx_SET (cond, x));
      x = gen_rtx_EQ (DImode, cond, const0_rtx);
    }
  emit_unlikely_jump (x, label2);

  emit_insn (gen_mskxl (cond, scratch, mask, addr));

  if (newval != const0_rtx)
    emit_insn (gen_iordi3 (cond, cond, newval));

  emit_insn (gen_store_conditional (DImode, cond, mem, cond));

  if (!is_weak)
    {
      x = gen_rtx_EQ (DImode, cond, const0_rtx);
      emit_unlikely_jump (x, label1);
    }

  if (!is_mm_relaxed (mod_f))
    emit_label (XEXP (label2, 0));

  alpha_post_atomic_barrier (mod_s);

  if (is_mm_relaxed (mod_f))
    emit_label (XEXP (label2, 0));
}

/* Expand an atomic exchange operation.  */

void
alpha_split_atomic_exchange (rtx operands[])
{
  rtx retval, mem, val, scratch;
  enum memmodel model;
  machine_mode mode;
  rtx label, x, cond;

  retval = operands[0];
  mem = operands[1];
  val = operands[2];
  model = (enum memmodel) INTVAL (operands[3]);
  scratch = operands[4];
  mode = GET_MODE (mem);
  cond = gen_lowpart (DImode, scratch);

  alpha_pre_atomic_barrier (model);

  label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
  emit_label (XEXP (label, 0));

  emit_insn (gen_load_locked (mode, retval, mem));
  emit_move_insn (scratch, val);
  emit_insn (gen_store_conditional (mode, cond, mem, scratch));

  x = gen_rtx_EQ (DImode, cond, const0_rtx);
  emit_unlikely_jump (x, label);

  alpha_post_atomic_barrier (model);
}

void
alpha_expand_atomic_exchange_12 (rtx operands[])
{
  rtx dst, mem, val, model;
  machine_mode mode;
  rtx addr, align, wdst;

  dst = operands[0];
  mem = operands[1];
  val = operands[2];
  model = operands[3];
  mode = GET_MODE (mem);

  /* We forced the address into a register via mem_noofs_operand.  */
  addr = XEXP (mem, 0);
  gcc_assert (register_operand (addr, DImode));

  align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8),
			       NULL_RTX, 1, OPTAB_DIRECT);

  /* Insert val into the correct byte location within the word.  */
  if (val != const0_rtx)
    val = emit_insxl (mode, val, addr);

  wdst = gen_reg_rtx (DImode);
  emit_insn (gen_atomic_exchange_1 (mode, wdst, mem, val, align, model));

  emit_move_insn (dst, gen_lowpart (mode, wdst));
}

void
alpha_split_atomic_exchange_12 (rtx operands[])
{
  rtx dest, orig_mem, addr, val, align, scratch;
  rtx label, mem, width, mask, x;
  machine_mode mode;
  enum memmodel model;

  dest = operands[0];
  orig_mem = operands[1];
  val = operands[2];
  align = operands[3];
  model = (enum memmodel) INTVAL (operands[4]);
  scratch = operands[5];
  mode = GET_MODE (orig_mem);
  addr = XEXP (orig_mem, 0);

  mem = gen_rtx_MEM (DImode, align);
  MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem);
  if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER)
    set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);

  alpha_pre_atomic_barrier (model);

  label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
  emit_label (XEXP (label, 0));

  emit_insn (gen_load_locked (DImode, scratch, mem));
  
  width = GEN_INT (GET_MODE_BITSIZE (mode));
  mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
  emit_insn (gen_extxl (dest, scratch, width, addr));
  emit_insn (gen_mskxl (scratch, scratch, mask, addr));
  if (val != const0_rtx)
    emit_insn (gen_iordi3 (scratch, scratch, val));

  emit_insn (gen_store_conditional (DImode, scratch, mem, scratch));

  x = gen_rtx_EQ (DImode, scratch, const0_rtx);
  emit_unlikely_jump (x, label);

  alpha_post_atomic_barrier (model);
}

/* Adjust the cost of a scheduling dependency.  Return the new cost of
   a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */

static int
alpha_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
		   unsigned int)
{
  enum attr_type dep_insn_type;

  /* If the dependence is an anti-dependence, there is no cost.  For an
     output dependence, there is sometimes a cost, but it doesn't seem
     worth handling those few cases.  */
  if (dep_type != 0)
    return cost;

  /* If we can't recognize the insns, we can't really do anything.  */
  if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
    return cost;

  dep_insn_type = get_attr_type (dep_insn);

  /* Bring in the user-defined memory latency.  */
  if (dep_insn_type == TYPE_ILD
      || dep_insn_type == TYPE_FLD
      || dep_insn_type == TYPE_LDSYM)
    cost += alpha_memory_latency-1;

  /* Everything else handled in DFA bypasses now.  */

  return cost;
}

/* The number of instructions that can be issued per cycle.  */

static int
alpha_issue_rate (void)
{
  return (alpha_tune == PROCESSOR_EV4 ? 2 : 4);
}

/* How many alternative schedules to try.  This should be as wide as the
   scheduling freedom in the DFA, but no wider.  Making this value too
   large results extra work for the scheduler.

   For EV4, loads can be issued to either IB0 or IB1, thus we have 2
   alternative schedules.  For EV5, we can choose between E0/E1 and
   FA/FM.  For EV6, an arithmetic insn can be issued to U0/U1/L0/L1.  */

static int
alpha_multipass_dfa_lookahead (void)
{
  return (alpha_tune == PROCESSOR_EV6 ? 4 : 2);
}

/* Machine-specific function data.  */

struct GTY(()) alpha_links;

struct GTY(()) machine_function
{
  unsigned HOST_WIDE_INT sa_mask;
  HOST_WIDE_INT sa_size;
  HOST_WIDE_INT frame_size;

  /* For flag_reorder_blocks_and_partition.  */
  rtx gp_save_rtx;

  /* For VMS condition handlers.  */
  bool uses_condition_handler;

  /* Linkage entries.  */
  hash_map<nofree_string_hash, alpha_links *> *links;
};

/* How to allocate a 'struct machine_function'.  */

static struct machine_function *
alpha_init_machine_status (void)
{
  return ggc_cleared_alloc<machine_function> ();
}

/* Support for frame based VMS condition handlers.  */

/* A VMS condition handler may be established for a function with a call to
   __builtin_establish_vms_condition_handler, and cancelled with a call to
   __builtin_revert_vms_condition_handler.

   The VMS Condition Handling Facility knows about the existence of a handler
   from the procedure descriptor .handler field.  As the VMS native compilers,
   we store the user specified handler's address at a fixed location in the
   stack frame and point the procedure descriptor at a common wrapper which
   fetches the real handler's address and issues an indirect call.

   The indirection wrapper is "__gcc_shell_handler", provided by libgcc.

   We force the procedure kind to PT_STACK, and the fixed frame location is
   fp+8, just before the register save area. We use the handler_data field in
   the procedure descriptor to state the fp offset at which the installed
   handler address can be found.  */

#define VMS_COND_HANDLER_FP_OFFSET 8

/* Expand code to store the currently installed user VMS condition handler
   into TARGET and install HANDLER as the new condition handler.  */

void
alpha_expand_builtin_establish_vms_condition_handler (rtx target, rtx handler)
{
  rtx handler_slot_address = plus_constant (Pmode, hard_frame_pointer_rtx,
					    VMS_COND_HANDLER_FP_OFFSET);

  rtx handler_slot
    = gen_rtx_MEM (DImode, handler_slot_address);

  emit_move_insn (target, handler_slot);
  emit_move_insn (handler_slot, handler);

  /* Notify the start/prologue/epilogue emitters that the condition handler
     slot is needed.  In addition to reserving the slot space, this will force
     the procedure kind to PT_STACK so ensure that the hard_frame_pointer_rtx
     use above is correct.  */
  cfun->machine->uses_condition_handler = true;
}

/* Expand code to store the current VMS condition handler into TARGET and
   nullify it.  */

void
alpha_expand_builtin_revert_vms_condition_handler (rtx target)
{
  /* We implement this by establishing a null condition handler, with the tiny
     side effect of setting uses_condition_handler.  This is a little bit
     pessimistic if no actual builtin_establish call is ever issued, which is
     not a real problem and expected never to happen anyway.  */

  alpha_expand_builtin_establish_vms_condition_handler (target, const0_rtx);
}

/* Functions to save and restore alpha_return_addr_rtx.  */

/* Start the ball rolling with RETURN_ADDR_RTX.  */

rtx
alpha_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
{
  if (count != 0)
    return const0_rtx;

  return get_hard_reg_initial_val (Pmode, REG_RA);
}

/* Return or create a memory slot containing the gp value for the current
   function.  Needed only if TARGET_LD_BUGGY_LDGP.  */

rtx
alpha_gp_save_rtx (void)
{
  rtx_insn *seq;
  rtx m = cfun->machine->gp_save_rtx;

  if (m == NULL)
    {
      start_sequence ();

      m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD);
      m = validize_mem (m);
      emit_move_insn (m, pic_offset_table_rtx);

      seq = get_insns ();
      end_sequence ();

      /* We used to simply emit the sequence after entry_of_function.
	 However this breaks the CFG if the first instruction in the
	 first block is not the NOTE_INSN_BASIC_BLOCK, for example a
	 label.  Emit the sequence properly on the edge.  We are only
	 invoked from dw2_build_landing_pads and finish_eh_generation
	 will call commit_edge_insertions thanks to a kludge.  */
      insert_insn_on_edge (seq,
			   single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));

      cfun->machine->gp_save_rtx = m;
    }

  return m;
}

static void
alpha_instantiate_decls (void)
{
  if (cfun->machine->gp_save_rtx != NULL_RTX)
    instantiate_decl_rtl (cfun->machine->gp_save_rtx);
}

static int
alpha_ra_ever_killed (void)
{
  rtx_insn *top;

  if (!has_hard_reg_initial_val (Pmode, REG_RA))
    return (int)df_regs_ever_live_p (REG_RA);

  push_topmost_sequence ();
  top = get_insns ();
  pop_topmost_sequence ();

  return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL);
}


/* Return the trap mode suffix applicable to the current
   instruction, or NULL.  */

static const char *
get_trap_mode_suffix (void)
{
  enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);

  switch (s)
    {
    case TRAP_SUFFIX_NONE:
      return NULL;

    case TRAP_SUFFIX_SU:
      if (alpha_fptm >= ALPHA_FPTM_SU)
	return "su";
      return NULL;

    case TRAP_SUFFIX_SUI:
      if (alpha_fptm >= ALPHA_FPTM_SUI)
	return "sui";
      return NULL;

    case TRAP_SUFFIX_V_SV:
      switch (alpha_fptm)
	{
	case ALPHA_FPTM_N:
	  return NULL;
	case ALPHA_FPTM_U:
	  return "v";
	case ALPHA_FPTM_SU:
	case ALPHA_FPTM_SUI:
	  return "sv";
	default:
	  gcc_unreachable ();
	}

    case TRAP_SUFFIX_V_SV_SVI:
      switch (alpha_fptm)
	{
	case ALPHA_FPTM_N:
	  return NULL;
	case ALPHA_FPTM_U:
	  return "v";
	case ALPHA_FPTM_SU:
	  return "sv";
	case ALPHA_FPTM_SUI:
	  return "svi";
	default:
	  gcc_unreachable ();
	}
      break;

    case TRAP_SUFFIX_U_SU_SUI:
      switch (alpha_fptm)
	{
	case ALPHA_FPTM_N:
	  return NULL;
	case ALPHA_FPTM_U:
	  return "u";
	case ALPHA_FPTM_SU:
	  return "su";
	case ALPHA_FPTM_SUI:
	  return "sui";
	default:
	  gcc_unreachable ();
	}
      break;
      
    default:
      gcc_unreachable ();
    }
  gcc_unreachable ();
}

/* Return the rounding mode suffix applicable to the current
   instruction, or NULL.  */

static const char *
get_round_mode_suffix (void)
{
  enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);

  switch (s)
    {
    case ROUND_SUFFIX_NONE:
      return NULL;
    case ROUND_SUFFIX_NORMAL:
      switch (alpha_fprm)
	{
	case ALPHA_FPRM_NORM:
	  return NULL;
	case ALPHA_FPRM_MINF:
	  return "m";
	case ALPHA_FPRM_CHOP:
	  return "c";
	case ALPHA_FPRM_DYN:
	  return "d";
	default:
	  gcc_unreachable ();
	}
      break;

    case ROUND_SUFFIX_C:
      return "c";
      
    default:
      gcc_unreachable ();
    }
  gcc_unreachable ();
}

/* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P.  */

static bool
alpha_print_operand_punct_valid_p (unsigned char code)
{
  return (code == '/' || code == ',' || code == '-' || code == '~'
	  || code == '#' || code == '*' || code == '&');
}

/* Implement TARGET_PRINT_OPERAND.  The alpha-specific
   operand codes are documented below.  */

static void
alpha_print_operand (FILE *file, rtx x, int code)
{
  int i;

  switch (code)
    {
    case '~':
      /* Print the assembler name of the current function.  */
      assemble_name (file, alpha_fnname);
      break;

    case '&':
      if (const char *name = get_some_local_dynamic_name ())
	assemble_name (file, name);
      else
	output_operand_lossage ("'%%&' used without any "
				"local dynamic TLS references");
      break;

    case '/':
      /* Generates the instruction suffix.  The TRAP_SUFFIX and ROUND_SUFFIX
	 attributes are examined to determine what is appropriate.  */
      {
	const char *trap = get_trap_mode_suffix ();
	const char *round = get_round_mode_suffix ();

	if (trap || round)
	  fprintf (file, "/%s%s", (trap ? trap : ""), (round ? round : ""));
	break;
      }

    case ',':
      /* Generates single precision suffix for floating point
	 instructions (s for IEEE, f for VAX).  */
      fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file);
      break;

    case '-':
      /* Generates double precision suffix for floating point
	 instructions (t for IEEE, g for VAX).  */
      fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
      break;

    case '#':
      if (alpha_this_literal_sequence_number == 0)
	alpha_this_literal_sequence_number = alpha_next_sequence_number++;
      fprintf (file, "%d", alpha_this_literal_sequence_number);
      break;

    case '*':
      if (alpha_this_gpdisp_sequence_number == 0)
	alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
      fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
      break;

    case 'J':
      {
	const char *lituse;

        if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL)
	  {
	    x = XVECEXP (x, 0, 0);
	    lituse = "lituse_tlsgd";
	  }
	else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL)
	  {
	    x = XVECEXP (x, 0, 0);
	    lituse = "lituse_tlsldm";
	  }
	else if (CONST_INT_P (x))
	  lituse = "lituse_jsr";
	else
	  {
	    output_operand_lossage ("invalid %%J value");
	    break;
	  }

	if (x != const0_rtx)
	  fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
      }
      break;

    case 'j':
      {
	const char *lituse;

#ifdef HAVE_AS_JSRDIRECT_RELOCS
	lituse = "lituse_jsrdirect";
#else
	lituse = "lituse_jsr";
#endif

	gcc_assert (INTVAL (x) != 0);
	fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
      }
      break;
    case 'r':
      /* If this operand is the constant zero, write it as "$31".  */
      if (REG_P (x))
	fprintf (file, "%s", reg_names[REGNO (x)]);
      else if (x == CONST0_RTX (GET_MODE (x)))
	fprintf (file, "$31");
      else
	output_operand_lossage ("invalid %%r value");
      break;

    case 'R':
      /* Similar, but for floating-point.  */
      if (REG_P (x))
	fprintf (file, "%s", reg_names[REGNO (x)]);
      else if (x == CONST0_RTX (GET_MODE (x)))
	fprintf (file, "$f31");
      else
	output_operand_lossage ("invalid %%R value");
      break;

    case 'N':
      /* Write the 1's complement of a constant.  */
      if (!CONST_INT_P (x))
	output_operand_lossage ("invalid %%N value");

      fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
      break;

    case 'P':
      /* Write 1 << C, for a constant C.  */
      if (!CONST_INT_P (x))
	output_operand_lossage ("invalid %%P value");

      fprintf (file, HOST_WIDE_INT_PRINT_DEC, HOST_WIDE_INT_1 << INTVAL (x));
      break;

    case 'h':
      /* Write the high-order 16 bits of a constant, sign-extended.  */
      if (!CONST_INT_P (x))
	output_operand_lossage ("invalid %%h value");

      fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
      break;

    case 'L':
      /* Write the low-order 16 bits of a constant, sign-extended.  */
      if (!CONST_INT_P (x))
	output_operand_lossage ("invalid %%L value");

      fprintf (file, HOST_WIDE_INT_PRINT_DEC,
	       (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
      break;

    case 'm':
      /* Write mask for ZAP insn.  */
      if (CONST_INT_P (x))
	{
	  HOST_WIDE_INT mask = 0, value = INTVAL (x);

	  for (i = 0; i < 8; i++, value >>= 8)
	    if (value & 0xff)
	      mask |= (1 << i);

	  fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
	}
      else
	output_operand_lossage ("invalid %%m value");
      break;

    case 'M':
      /* 'b', 'w', 'l', or 'q' as the value of the constant.  */
      if (!mode_width_operand (x, VOIDmode))
	output_operand_lossage ("invalid %%M value");

      fprintf (file, "%s",
	       (INTVAL (x) == 8 ? "b"
		: INTVAL (x) == 16 ? "w"
		: INTVAL (x) == 32 ? "l"
		: "q"));
      break;

    case 'U':
      /* Similar, except do it from the mask.  */
      if (CONST_INT_P (x))
	{
	  HOST_WIDE_INT value = INTVAL (x);

	  if (value == 0xff)
	    {
	      fputc ('b', file);
	      break;
	    }
	  if (value == 0xffff)
	    {
	      fputc ('w', file);
	      break;
	    }
	  if (value == 0xffffffff)
	    {
	      fputc ('l', file);
	      break;
	    }
	  if (value == -1)
	    {
	      fputc ('q', file);
	      break;
	    }
	}

      output_operand_lossage ("invalid %%U value");
      break;

    case 's':
      /* Write the constant value divided by 8.  */
      if (!CONST_INT_P (x)
	  || (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
	  || (INTVAL (x) & 7) != 0)
	output_operand_lossage ("invalid %%s value");

      fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
      break;

    case 'C': case 'D': case 'c': case 'd':
      /* Write out comparison name.  */
      {
	enum rtx_code c = GET_CODE (x);

        if (!COMPARISON_P (x))
	  output_operand_lossage ("invalid %%C value");

	else if (code == 'D')
	  c = reverse_condition (c);
	else if (code == 'c')
	  c = swap_condition (c);
	else if (code == 'd')
	  c = swap_condition (reverse_condition (c));

        if (c == LEU)
	  fprintf (file, "ule");
        else if (c == LTU)
	  fprintf (file, "ult");
	else if (c == UNORDERED)
	  fprintf (file, "un");
        else
	  fprintf (file, "%s", GET_RTX_NAME (c));
      }
      break;

    case 'E':
      /* Write the divide or modulus operator.  */
      switch (GET_CODE (x))
	{
	case DIV:
	  fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
	  break;
	case UDIV:
	  fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
	  break;
	case MOD:
	  fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
	  break;
	case UMOD:
	  fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
	  break;
	default:
	  output_operand_lossage ("invalid %%E value");
	  break;
	}
      break;

    case 'A':
      /* Write "_u" for unaligned access.  */
      if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND)
	fprintf (file, "_u");
      break;

    case 0:
      if (REG_P (x))
	fprintf (file, "%s", reg_names[REGNO (x)]);
      else if (MEM_P (x))
	output_address (GET_MODE (x), XEXP (x, 0));
      else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
	{
	  switch (XINT (XEXP (x, 0), 1))
	    {
	    case UNSPEC_DTPREL:
	    case UNSPEC_TPREL:
	      output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0));
	      break;
	    default:
	      output_operand_lossage ("unknown relocation unspec");
	      break;
	    }
	}
      else
	output_addr_const (file, x);
      break;

    default:
      output_operand_lossage ("invalid %%xn code");
    }
}

/* Implement TARGET_PRINT_OPERAND_ADDRESS.  */

static void
alpha_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
{
  int basereg = 31;
  HOST_WIDE_INT offset = 0;

  if (GET_CODE (addr) == AND)
    addr = XEXP (addr, 0);

  if (GET_CODE (addr) == PLUS
      && CONST_INT_P (XEXP (addr, 1)))
    {
      offset = INTVAL (XEXP (addr, 1));
      addr = XEXP (addr, 0);
    }

  if (GET_CODE (addr) == LO_SUM)
    {
      const char *reloc16, *reloclo;
      rtx op1 = XEXP (addr, 1);

      if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC)
	{
	  op1 = XEXP (op1, 0);
	  switch (XINT (op1, 1))
	    {
	    case UNSPEC_DTPREL:
	      reloc16 = NULL;
	      reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello");
	      break;
	    case UNSPEC_TPREL:
	      reloc16 = NULL;
	      reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello");
	      break;
	    default:
	      output_operand_lossage ("unknown relocation unspec");
	      return;
	    }

	  output_addr_const (file, XVECEXP (op1, 0, 0));
	}
      else
	{
	  reloc16 = "gprel";
	  reloclo = "gprellow";
	  output_addr_const (file, op1);
	}

      if (offset)
	fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);

      addr = XEXP (addr, 0);
      switch (GET_CODE (addr))
	{
	case REG:
	  basereg = REGNO (addr);
	  break;

	case SUBREG:
	  basereg = subreg_regno (addr);
	  break;

	default:
	  gcc_unreachable ();
	}

      fprintf (file, "($%d)\t\t!%s", basereg,
	       (basereg == 29 ? reloc16 : reloclo));
      return;
    }

  switch (GET_CODE (addr))
    {
    case REG:
      basereg = REGNO (addr);
      break;

    case SUBREG:
      basereg = subreg_regno (addr);
      break;

    case CONST_INT:
      offset = INTVAL (addr);
      break;

    case SYMBOL_REF:
      gcc_assert(TARGET_ABI_OPEN_VMS || this_is_asm_operands);
      fprintf (file, "%s", XSTR (addr, 0));
      return;

    case CONST:
      gcc_assert(TARGET_ABI_OPEN_VMS || this_is_asm_operands);
      gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS
		  && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF);
      fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC,
	       XSTR (XEXP (XEXP (addr, 0), 0), 0),
	       INTVAL (XEXP (XEXP (addr, 0), 1)));
      return;

    default:
      output_operand_lossage ("invalid operand address");
      return;
    }

  fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
}

/* Emit RTL insns to initialize the variable parts of a trampoline at
   M_TRAMP.  FNDECL is target function's decl.  CHAIN_VALUE is an rtx
   for the static chain value for the function.  */

static void
alpha_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
{
  rtx fnaddr, mem, word1, word2;

  fnaddr = XEXP (DECL_RTL (fndecl), 0);

#ifdef POINTERS_EXTEND_UNSIGNED
  fnaddr = convert_memory_address (Pmode, fnaddr);
  chain_value = convert_memory_address (Pmode, chain_value);
#endif

  if (TARGET_ABI_OPEN_VMS)
    {
      const char *fnname;
      char *trname;

      /* Construct the name of the trampoline entry point.  */
      fnname = XSTR (fnaddr, 0);
      trname = (char *) alloca (strlen (fnname) + 5);
      strcpy (trname, fnname);
      strcat (trname, "..tr");
      fnname = ggc_alloc_string (trname, strlen (trname) + 1);
      word2 = gen_rtx_SYMBOL_REF (Pmode, fnname);

      /* Trampoline (or "bounded") procedure descriptor is constructed from
	 the function's procedure descriptor with certain fields zeroed IAW
	 the VMS calling standard. This is stored in the first quadword.  */
      word1 = force_reg (DImode, gen_const_mem (DImode, fnaddr));
      word1 = expand_and (DImode, word1,
			  GEN_INT (HOST_WIDE_INT_C (0xffff0fff0000fff0)),
			  NULL);
    }
  else
    {
      /* These 4 instructions are:
	    ldq $1,24($27)
	    ldq $27,16($27)
	    jmp $31,($27),0
	    nop
	 We don't bother setting the HINT field of the jump; the nop
	 is merely there for padding.  */
      word1 = GEN_INT (HOST_WIDE_INT_C (0xa77b0010a43b0018));
      word2 = GEN_INT (HOST_WIDE_INT_C (0x47ff041f6bfb0000));
    }

  /* Store the first two words, as computed above.  */
  mem = adjust_address (m_tramp, DImode, 0);
  emit_move_insn (mem, word1);
  mem = adjust_address (m_tramp, DImode, 8);
  emit_move_insn (mem, word2);

  /* Store function address and static chain value.  */
  mem = adjust_address (m_tramp, Pmode, 16);
  emit_move_insn (mem, fnaddr);
  mem = adjust_address (m_tramp, Pmode, 24);
  emit_move_insn (mem, chain_value);

  if (TARGET_ABI_OSF)
    {
      emit_insn (gen_imb ());
#ifdef HAVE_ENABLE_EXECUTE_STACK
      emit_library_call (init_one_libfunc ("__enable_execute_stack"),
			 LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
#endif
    }
}

/* Determine where to put an argument to a function.
   Value is zero to push the argument on the stack,
   or a hard register in which to store the argument.

   CUM is a variable of type CUMULATIVE_ARGS which gives info about
    the preceding args and about the function being called.
   ARG is a description of the argument.

   On Alpha the first 6 words of args are normally in registers
   and the rest are pushed.  */

static rtx
alpha_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  int basereg;
  int num_args;

  /* Don't get confused and pass small structures in FP registers.  */
  if (arg.aggregate_type_p ())
    basereg = 16;
  else
    {
      /* With alpha_split_complex_arg, we shouldn't see any raw complex
	 values here.  */
      gcc_checking_assert (!COMPLEX_MODE_P (arg.mode));

      /* Set up defaults for FP operands passed in FP registers, and
	 integral operands passed in integer registers.  */
      if (TARGET_FPREGS && GET_MODE_CLASS (arg.mode) == MODE_FLOAT)
	basereg = 32 + 16;
      else
	basereg = 16;
    }

  /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
     the two platforms, so we can't avoid conditional compilation.  */
#if TARGET_ABI_OPEN_VMS
    {
      if (arg.end_marker_p ())
	return alpha_arg_info_reg_val (*cum);

      num_args = cum->num_args;
      if (num_args >= 6
	  || targetm.calls.must_pass_in_stack (arg))
	return NULL_RTX;
    }
#elif TARGET_ABI_OSF
    {
      if (*cum >= 6)
	return NULL_RTX;
      num_args = *cum;

      if (arg.end_marker_p ())
	basereg = 16;
      else if (targetm.calls.must_pass_in_stack (arg))
	return NULL_RTX;
    }
#else
#error Unhandled ABI
#endif

  return gen_rtx_REG (arg.mode, num_args + basereg);
}

/* Update the data in CUM to advance over argument ARG.  */

static void
alpha_function_arg_advance (cumulative_args_t cum_v,
			    const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  bool onstack = targetm.calls.must_pass_in_stack (arg);
  int increment = onstack ? 6 : ALPHA_ARG_SIZE (arg.mode, arg.type);

#if TARGET_ABI_OSF
  *cum += increment;
#else
  if (!onstack && cum->num_args < 6)
    cum->atypes[cum->num_args] = alpha_arg_type (arg.mode);
  cum->num_args += increment;
#endif
}

static int
alpha_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
  int words = 0;
  CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED = get_cumulative_args (cum_v);

#if TARGET_ABI_OPEN_VMS
  if (cum->num_args < 6
      && 6 < cum->num_args + ALPHA_ARG_SIZE (arg.mode, arg.type))
    words = 6 - cum->num_args;
#elif TARGET_ABI_OSF
  if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (arg.mode, arg.type))
    words = 6 - *cum;
#else
#error Unhandled ABI
#endif

  return words * UNITS_PER_WORD;
}


/* Return true if TYPE must be returned in memory, instead of in registers.  */

static bool
alpha_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
{
  machine_mode mode = VOIDmode;
  int size;

  if (type)
    {
      mode = TYPE_MODE (type);

      /* All aggregates are returned in memory, except on OpenVMS where
	 records that fit 64 bits should be returned by immediate value
	 as required by section 3.8.7.1 of the OpenVMS Calling Standard.  */
      if (TARGET_ABI_OPEN_VMS
	  && TREE_CODE (type) != ARRAY_TYPE
	  && (unsigned HOST_WIDE_INT) int_size_in_bytes(type) <= 8)
	return false;

      if (AGGREGATE_TYPE_P (type))
	return true;
    }

  size = GET_MODE_SIZE (mode);
  switch (GET_MODE_CLASS (mode))
    {
    case MODE_VECTOR_FLOAT:
      /* Pass all float vectors in memory, like an aggregate.  */
      return true;

    case MODE_COMPLEX_FLOAT:
      /* We judge complex floats on the size of their element,
	 not the size of the whole type.  */
      size = GET_MODE_UNIT_SIZE (mode);
      break;

    case MODE_INT:
    case MODE_FLOAT:
    case MODE_COMPLEX_INT:
    case MODE_VECTOR_INT:
      break;

    default:
      /* ??? We get called on all sorts of random stuff from
	 aggregate_value_p.  We must return something, but it's not
	 clear what's safe to return.  Pretend it's a struct I
	 guess.  */
      return true;
    }

  /* Otherwise types must fit in one register.  */
  return size > UNITS_PER_WORD;
}

/* Return true if ARG should be passed by invisible reference.  */

static bool
alpha_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
{
  /* Pass float and _Complex float variable arguments by reference.
     This avoids 64-bit store from a FP register to a pretend args save area
     and subsequent 32-bit load from the saved location to a FP register.

     Note that 32-bit loads and stores to/from a FP register on alpha reorder
     bits to form a canonical 64-bit value in the FP register.  This fact
     invalidates compiler assumption that 32-bit FP value lives in the lower
     32-bits of the passed 64-bit FP value, so loading the 32-bit value from
     the stored 64-bit location using 32-bit FP load is invalid on alpha.

     This introduces sort of ABI incompatibility, but until _Float32 was
     introduced, C-family languages promoted 32-bit float variable arg to
     a 64-bit double, and it was not allowed to pass float as a varible
     argument.  Passing _Complex float as a variable argument never
     worked on alpha.  Thus, we have no backward compatibility issues
     to worry about, and passing unpromoted _Float32 and _Complex float
     as a variable argument will actually work in the future.  */

  if (arg.mode == SFmode || arg.mode == SCmode)
    return !arg.named;

  return arg.mode == TFmode || arg.mode == TCmode;
}

/* Define how to find the value returned by a function.  VALTYPE is the
   data type of the value (as a tree).  If the precise function being
   called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
   MODE is set instead of VALTYPE for libcalls.

   On Alpha the value is found in $0 for integer functions and
   $f0 for floating-point functions.  */

static rtx
alpha_function_value_1 (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
			machine_mode mode)
{
  unsigned int regnum, dummy ATTRIBUTE_UNUSED;
  enum mode_class mclass;

  gcc_assert (!valtype || !alpha_return_in_memory (valtype, func));

  if (valtype)
    mode = TYPE_MODE (valtype);

  mclass = GET_MODE_CLASS (mode);
  switch (mclass)
    {
    case MODE_INT:
      /* Do the same thing as PROMOTE_MODE except for libcalls on VMS,
	 where we have them returning both SImode and DImode.  */
      if (!(TARGET_ABI_OPEN_VMS && valtype && AGGREGATE_TYPE_P (valtype)))
        PROMOTE_MODE (mode, dummy, valtype);
      /* FALLTHRU */

    case MODE_COMPLEX_INT:
    case MODE_VECTOR_INT:
      regnum = 0;
      break;

    case MODE_FLOAT:
      regnum = 32;
      break;

    case MODE_COMPLEX_FLOAT:
      {
	machine_mode cmode = GET_MODE_INNER (mode);

	return gen_rtx_PARALLEL
	  (VOIDmode,
	   gen_rtvec (2,
		      gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32),
				         const0_rtx),
		      gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33),
				         GEN_INT (GET_MODE_SIZE (cmode)))));
      }

    case MODE_RANDOM:
      /* We should only reach here for BLKmode on VMS.  */
      gcc_assert (TARGET_ABI_OPEN_VMS && mode == BLKmode);
      regnum = 0;
      break;

    default:
      gcc_unreachable ();
    }

  return gen_rtx_REG (mode, regnum);
}

/* Implement TARGET_FUNCTION_VALUE.  */

static rtx
alpha_function_value (const_tree valtype, const_tree fn_decl_or_type,
		      bool /*outgoing*/)
{
  return alpha_function_value_1 (valtype, fn_decl_or_type, VOIDmode);
}

/* Implement TARGET_LIBCALL_VALUE.  */

static rtx
alpha_libcall_value (machine_mode mode, const_rtx /*fun*/)
{
  return alpha_function_value_1 (NULL_TREE, NULL_TREE, mode);
}

/* Implement TARGET_FUNCTION_VALUE_REGNO_P.

   On the Alpha, $0 $1 and $f0 $f1 are the only register thus used.  */

static bool
alpha_function_value_regno_p (const unsigned int regno)
{
  return (regno == 0 || regno == 1 || regno == 32 || regno == 33);
}

/* TCmode complex values are passed by invisible reference.  We
   should not split these values.  */

static bool
alpha_split_complex_arg (const_tree type)
{
  return TYPE_MODE (type) != TCmode;
}

static tree
alpha_build_builtin_va_list (void)
{
  tree base, ofs, space, record, type_decl;

  if (TARGET_ABI_OPEN_VMS)
    return ptr_type_node;

  record = (*lang_hooks.types.make_type) (RECORD_TYPE);
  type_decl = build_decl (BUILTINS_LOCATION,
			  TYPE_DECL, get_identifier ("__va_list_tag"), record);
  TYPE_STUB_DECL (record) = type_decl;
  TYPE_NAME (record) = type_decl;

  /* C++? SET_IS_AGGR_TYPE (record, 1); */

  /* Dummy field to prevent alignment warnings.  */
  space = build_decl (BUILTINS_LOCATION,
		      FIELD_DECL, NULL_TREE, integer_type_node);
  DECL_FIELD_CONTEXT (space) = record;
  DECL_ARTIFICIAL (space) = 1;
  DECL_IGNORED_P (space) = 1;

  ofs = build_decl (BUILTINS_LOCATION,
		    FIELD_DECL, get_identifier ("__offset"),
		    integer_type_node);
  DECL_FIELD_CONTEXT (ofs) = record;
  DECL_CHAIN (ofs) = space;

  base = build_decl (BUILTINS_LOCATION,
		     FIELD_DECL, get_identifier ("__base"),
		     ptr_type_node);
  DECL_FIELD_CONTEXT (base) = record;
  DECL_CHAIN (base) = ofs;

  TYPE_FIELDS (record) = base;
  layout_type (record);

  va_list_gpr_counter_field = ofs;
  return record;
}

#if TARGET_ABI_OSF
/* Helper function for alpha_stdarg_optimize_hook.  Skip over casts
   and constant additions.  */

static gimple *
va_list_skip_additions (tree lhs)
{
  gimple  *stmt;

  for (;;)
    {
      enum tree_code code;

      stmt = SSA_NAME_DEF_STMT (lhs);

      if (gimple_code (stmt) == GIMPLE_PHI)
	return stmt;

      if (!is_gimple_assign (stmt)
	  || gimple_assign_lhs (stmt) != lhs)
	return NULL;

      if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
	return stmt;
      code = gimple_assign_rhs_code (stmt);
      if (!CONVERT_EXPR_CODE_P (code)
	  && ((code != PLUS_EXPR && code != POINTER_PLUS_EXPR)
	      || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST
	      || !tree_fits_uhwi_p (gimple_assign_rhs2 (stmt))))
	return stmt;

      lhs = gimple_assign_rhs1 (stmt);
    }
}

/* Check if LHS = RHS statement is
   LHS = *(ap.__base + ap.__offset + cst)
   or
   LHS = *(ap.__base
	   + ((ap.__offset + cst <= 47)
	      ? ap.__offset + cst - 48 : ap.__offset + cst) + cst2).
   If the former, indicate that GPR registers are needed,
   if the latter, indicate that FPR registers are needed.

   Also look for LHS = (*ptr).field, where ptr is one of the forms
   listed above.

   On alpha, cfun->va_list_gpr_size is used as size of the needed
   regs and cfun->va_list_fpr_size is a bitmask, bit 0 set if GPR
   registers are needed and bit 1 set if FPR registers are needed.
   Return true if va_list references should not be scanned for the
   current statement.  */

static bool
alpha_stdarg_optimize_hook (struct stdarg_info *si, const gimple *stmt)
{
  tree base, offset, rhs;
  int offset_arg = 1;
  gimple *base_stmt;

  if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
      != GIMPLE_SINGLE_RHS)
    return false;

  rhs = gimple_assign_rhs1 (stmt);
  while (handled_component_p (rhs))
    rhs = TREE_OPERAND (rhs, 0);
  if (TREE_CODE (rhs) != MEM_REF
      || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
    return false;

  stmt = va_list_skip_additions (TREE_OPERAND (rhs, 0));
  if (stmt == NULL
      || !is_gimple_assign (stmt)
      || gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR)
    return false;

  base = gimple_assign_rhs1 (stmt);
  if (TREE_CODE (base) == SSA_NAME)
    {
      base_stmt = va_list_skip_additions (base);
      if (base_stmt
	  && is_gimple_assign (base_stmt)
	  && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
	base = gimple_assign_rhs1 (base_stmt);
    }

  if (TREE_CODE (base) != COMPONENT_REF
      || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
    {
      base = gimple_assign_rhs2 (stmt);
      if (TREE_CODE (base) == SSA_NAME)
	{
	  base_stmt = va_list_skip_additions (base);
	  if (base_stmt
	      && is_gimple_assign (base_stmt)
	      && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
	    base = gimple_assign_rhs1 (base_stmt);
	}

      if (TREE_CODE (base) != COMPONENT_REF
	  || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
	return false;

      offset_arg = 0;
    }

  base = get_base_address (base);
  if (TREE_CODE (base) != VAR_DECL
      || !bitmap_bit_p (si->va_list_vars, DECL_UID (base) + num_ssa_names))
    return false;

  offset = gimple_op (stmt, 1 + offset_arg);
  if (TREE_CODE (offset) == SSA_NAME)
    {
      gimple *offset_stmt = va_list_skip_additions (offset);

      if (offset_stmt
	  && gimple_code (offset_stmt) == GIMPLE_PHI)
	{
	  HOST_WIDE_INT sub;
	  gimple *arg1_stmt, *arg2_stmt;
	  tree arg1, arg2;
	  enum tree_code code1, code2;

	  if (gimple_phi_num_args (offset_stmt) != 2)
	    goto escapes;

	  arg1_stmt
	    = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 0));
	  arg2_stmt
	    = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 1));
	  if (arg1_stmt == NULL
	      || !is_gimple_assign (arg1_stmt)
	      || arg2_stmt == NULL
	      || !is_gimple_assign (arg2_stmt))
	    goto escapes;

	  code1 = gimple_assign_rhs_code (arg1_stmt);
	  code2 = gimple_assign_rhs_code (arg2_stmt);
	  if (code1 == COMPONENT_REF
	      && (code2 == MINUS_EXPR || code2 == PLUS_EXPR))
	    /* Do nothing.  */;
	  else if (code2 == COMPONENT_REF
		   && (code1 == MINUS_EXPR || code1 == PLUS_EXPR))
	    {
	      std::swap (arg1_stmt, arg2_stmt);
	      code2 = code1;
	    }
	  else
	    goto escapes;

	  if (!tree_fits_shwi_p (gimple_assign_rhs2 (arg2_stmt)))
	    goto escapes;

	  sub = tree_to_shwi (gimple_assign_rhs2 (arg2_stmt));
	  if (code2 == MINUS_EXPR)
	    sub = -sub;
	  if (sub < -48 || sub > -32)
	    goto escapes;

	  arg1 = gimple_assign_rhs1 (arg1_stmt);
	  arg2 = gimple_assign_rhs1 (arg2_stmt);
	  if (TREE_CODE (arg2) == SSA_NAME)
	    {
	      arg2_stmt = va_list_skip_additions (arg2);
	      if (arg2_stmt == NULL
		  || !is_gimple_assign (arg2_stmt)
		  || gimple_assign_rhs_code (arg2_stmt) != COMPONENT_REF)
		goto escapes;
	      arg2 = gimple_assign_rhs1 (arg2_stmt);
	    }
	  if (arg1 != arg2)
	    goto escapes;

	  if (TREE_CODE (arg1) != COMPONENT_REF
	      || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
	      || get_base_address (arg1) != base)
	    goto escapes;

	  /* Need floating point regs.  */
	  cfun->va_list_fpr_size |= 2;
	  return false;
	}
      if (offset_stmt
	  && is_gimple_assign (offset_stmt)
	  && gimple_assign_rhs_code (offset_stmt) == COMPONENT_REF)
	offset = gimple_assign_rhs1 (offset_stmt);
    }
  if (TREE_CODE (offset) != COMPONENT_REF
      || TREE_OPERAND (offset, 1) != va_list_gpr_counter_field
      || get_base_address (offset) != base)
    goto escapes;
  else
    /* Need general regs.  */
    cfun->va_list_fpr_size |= 1;
  return false;

escapes:
  si->va_list_escapes = true;
  return false;
}
#endif

/* Perform any needed actions needed for a function that is receiving a
   variable number of arguments.  */

static void
alpha_setup_incoming_varargs (cumulative_args_t pcum,
			      const function_arg_info &arg,
			      int *pretend_size, int no_rtl)
{
  CUMULATIVE_ARGS cum = *get_cumulative_args (pcum);

  /* Skip the current argument.  */
  targetm.calls.function_arg_advance (pack_cumulative_args (&cum), arg);

#if TARGET_ABI_OPEN_VMS
  /* For VMS, we allocate space for all 6 arg registers plus a count.

     However, if NO registers need to be saved, don't allocate any space.
     This is not only because we won't need the space, but because AP
     includes the current_pretend_args_size and we don't want to mess up
     any ap-relative addresses already made.  */
  if (cum.num_args < 6)
    {
      if (!no_rtl)
	{
	  emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx);
	  emit_insn (gen_arg_home ());
	}
      *pretend_size = 7 * UNITS_PER_WORD;
    }
#else
  /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
     only push those that are remaining.  However, if NO registers need to
     be saved, don't allocate any space.  This is not only because we won't
     need the space, but because AP includes the current_pretend_args_size
     and we don't want to mess up any ap-relative addresses already made.

     If we are not to use the floating-point registers, save the integer
     registers where we would put the floating-point registers.  This is
     not the most efficient way to implement varargs with just one register
     class, but it isn't worth doing anything more efficient in this rare
     case.  */
  if (cum >= 6)
    return;

  if (!no_rtl)
    {
      int count;
      alias_set_type set = get_varargs_alias_set ();
      rtx tmp;

      count = cfun->va_list_gpr_size / UNITS_PER_WORD;
      if (count > 6 - cum)
	count = 6 - cum;

      /* Detect whether integer registers or floating-point registers
	 are needed by the detected va_arg statements.  See above for
	 how these values are computed.  Note that the "escape" value
	 is VA_LIST_MAX_FPR_SIZE, which is 255, which has both of 
	 these bits set.  */
      gcc_assert ((VA_LIST_MAX_FPR_SIZE & 3) == 3);

      if (cfun->va_list_fpr_size & 1)
	{
	  tmp = gen_rtx_MEM (BLKmode,
			     plus_constant (Pmode, virtual_incoming_args_rtx,
					    (cum + 6) * UNITS_PER_WORD));
	  MEM_NOTRAP_P (tmp) = 1;
	  set_mem_alias_set (tmp, set);
	  move_block_from_reg (16 + cum, tmp, count);
	}

      if (cfun->va_list_fpr_size & 2)
	{
	  tmp = gen_rtx_MEM (BLKmode,
			     plus_constant (Pmode, virtual_incoming_args_rtx,
					    cum * UNITS_PER_WORD));
	  MEM_NOTRAP_P (tmp) = 1;
	  set_mem_alias_set (tmp, set);
	  move_block_from_reg (16 + cum + TARGET_FPREGS*32, tmp, count);
	}
     }
  *pretend_size = 12 * UNITS_PER_WORD;
#endif
}

static void
alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
{
  HOST_WIDE_INT offset;
  tree t, offset_field, base_field;

  if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
    return;

  /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
     up by 48, storing fp arg registers in the first 48 bytes, and the
     integer arg registers in the next 48 bytes.  This is only done,
     however, if any integer registers need to be stored.

     If no integer registers need be stored, then we must subtract 48
     in order to account for the integer arg registers which are counted
     in argsize above, but which are not actually stored on the stack.
     Must further be careful here about structures straddling the last
     integer argument register; that futzes with pretend_args_size,
     which changes the meaning of AP.  */

  if (NUM_ARGS < 6)
    offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
  else
    offset = -6 * UNITS_PER_WORD + crtl->args.pretend_args_size;

  if (TARGET_ABI_OPEN_VMS)
    {
      t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
      t = fold_build_pointer_plus_hwi (t, offset + NUM_ARGS * UNITS_PER_WORD);
      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
      TREE_SIDE_EFFECTS (t) = 1;
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    }
  else
    {
      base_field = TYPE_FIELDS (TREE_TYPE (valist));
      offset_field = DECL_CHAIN (base_field);

      base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
			   valist, base_field, NULL_TREE);
      offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
			     valist, offset_field, NULL_TREE);

      t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
      t = fold_build_pointer_plus_hwi (t, offset);
      t = build2 (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
      TREE_SIDE_EFFECTS (t) = 1;
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);

      t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD);
      t = build2 (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
      TREE_SIDE_EFFECTS (t) = 1;
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    }
}

static tree
alpha_gimplify_va_arg_1 (tree type, tree base, tree offset,
			 gimple_seq *pre_p)
{
  tree type_size, ptr_type, addend, t, addr;
  gimple_seq internal_post;

  /* If the type could not be passed in registers, skip the block
     reserved for the registers.  */
  if (must_pass_va_arg_in_stack (type))
    {
      t = build_int_cst (TREE_TYPE (offset), 6*8);
      gimplify_assign (offset,
		       build2 (MAX_EXPR, TREE_TYPE (offset), offset, t),
		       pre_p);
    }

  addend = offset;
  ptr_type = build_pointer_type_for_mode (type, ptr_mode, true);

  if (TREE_CODE (type) == COMPLEX_TYPE)
    {
      tree real_part, imag_part, real_temp;

      real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
					   offset, pre_p);

      /* Copy the value into a new temporary, lest the formal temporary
	 be reused out from under us.  */
      real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);

      imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
					   offset, pre_p);

      return build2 (COMPLEX_EXPR, type, real_temp, imag_part);
    }
  else if (TREE_CODE (type) == REAL_TYPE)
    {
      tree fpaddend, cond, fourtyeight;

      fourtyeight = build_int_cst (TREE_TYPE (addend), 6*8);
      fpaddend = fold_build2 (MINUS_EXPR, TREE_TYPE (addend),
			      addend, fourtyeight);
      cond = fold_build2 (LT_EXPR, boolean_type_node, addend, fourtyeight);
      addend = fold_build3 (COND_EXPR, TREE_TYPE (addend), cond,
			    fpaddend, addend);
    }

  /* Build the final address and force that value into a temporary.  */
  addr = fold_build_pointer_plus (fold_convert (ptr_type, base), addend);
  internal_post = NULL;
  gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
  gimple_seq_add_seq (pre_p, internal_post);

  /* Update the offset field.  */
  type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
  if (type_size == NULL || TREE_OVERFLOW (type_size))
    t = size_zero_node;
  else
    {
      t = size_binop (PLUS_EXPR, type_size, size_int (7));
      t = size_binop (TRUNC_DIV_EXPR, t, size_int (8));
      t = size_binop (MULT_EXPR, t, size_int (8));
    }
  t = fold_convert (TREE_TYPE (offset), t);
  gimplify_assign (offset, build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t),
      		   pre_p);

  return build_va_arg_indirect_ref (addr);
}

static tree
alpha_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
		       gimple_seq *post_p)
{
  tree offset_field, base_field, offset, base, t, r;
  bool indirect;

  if (TARGET_ABI_OPEN_VMS)
    return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);

  base_field = TYPE_FIELDS (va_list_type_node);
  offset_field = DECL_CHAIN (base_field);
  base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
		       valist, base_field, NULL_TREE);
  offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
			 valist, offset_field, NULL_TREE);

  /* Pull the fields of the structure out into temporaries.  Since we never
     modify the base field, we can use a formal temporary.  Sign-extend the
     offset field so that it's the proper width for pointer arithmetic.  */
  base = get_formal_tmp_var (base_field, pre_p);

  t = fold_convert (build_nonstandard_integer_type (64, 0), offset_field);
  offset = get_initialized_tmp_var (t, pre_p, NULL);

  indirect = pass_va_arg_by_reference (type);

  if (indirect)
    {
      if (TREE_CODE (type) == COMPLEX_TYPE
	  && targetm.calls.split_complex_arg (type))
	{
	  tree real_part, imag_part, real_temp;

	  tree ptr_type = build_pointer_type_for_mode (TREE_TYPE (type),
						       ptr_mode, true);

	  real_part = alpha_gimplify_va_arg_1 (ptr_type, base,
					       offset, pre_p);
	  real_part = build_va_arg_indirect_ref (real_part);

	  /* Copy the value into a new temporary, lest the formal temporary
	     be reused out from under us.  */
	  real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);

	  imag_part = alpha_gimplify_va_arg_1 (ptr_type, base,
					       offset, pre_p);
	  imag_part = build_va_arg_indirect_ref (imag_part);

	  r = build2 (COMPLEX_EXPR, type, real_temp, imag_part);

	  /* Stuff the offset temporary back into its field.  */
	  gimplify_assign (unshare_expr (offset_field),
			   fold_convert (TREE_TYPE (offset_field), offset),
			   pre_p);
	  return r;
	}
      else
	type = build_pointer_type_for_mode (type, ptr_mode, true);
    }

  /* Find the value.  Note that this will be a stable indirection, or
     a composite of stable indirections in the case of complex.  */
  r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);

  /* Stuff the offset temporary back into its field.  */
  gimplify_assign (unshare_expr (offset_field),
		   fold_convert (TREE_TYPE (offset_field), offset), pre_p);

  if (indirect)
    r = build_va_arg_indirect_ref (r);

  return r;
}

/* Builtins.  */

enum alpha_builtin
{
  ALPHA_BUILTIN_CMPBGE,
  ALPHA_BUILTIN_EXTBL,
  ALPHA_BUILTIN_EXTWL,
  ALPHA_BUILTIN_EXTLL,
  ALPHA_BUILTIN_EXTQL,
  ALPHA_BUILTIN_EXTWH,
  ALPHA_BUILTIN_EXTLH,
  ALPHA_BUILTIN_EXTQH,
  ALPHA_BUILTIN_INSBL,
  ALPHA_BUILTIN_INSWL,
  ALPHA_BUILTIN_INSLL,
  ALPHA_BUILTIN_INSQL,
  ALPHA_BUILTIN_INSWH,
  ALPHA_BUILTIN_INSLH,
  ALPHA_BUILTIN_INSQH,
  ALPHA_BUILTIN_MSKBL,
  ALPHA_BUILTIN_MSKWL,
  ALPHA_BUILTIN_MSKLL,
  ALPHA_BUILTIN_MSKQL,
  ALPHA_BUILTIN_MSKWH,
  ALPHA_BUILTIN_MSKLH,
  ALPHA_BUILTIN_MSKQH,
  ALPHA_BUILTIN_UMULH,
  ALPHA_BUILTIN_ZAP,
  ALPHA_BUILTIN_ZAPNOT,
  ALPHA_BUILTIN_AMASK,
  ALPHA_BUILTIN_IMPLVER,
  ALPHA_BUILTIN_RPCC,
  ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
  ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER,

  /* TARGET_MAX */
  ALPHA_BUILTIN_MINUB8,
  ALPHA_BUILTIN_MINSB8,
  ALPHA_BUILTIN_MINUW4,
  ALPHA_BUILTIN_MINSW4,
  ALPHA_BUILTIN_MAXUB8,
  ALPHA_BUILTIN_MAXSB8,
  ALPHA_BUILTIN_MAXUW4,
  ALPHA_BUILTIN_MAXSW4,
  ALPHA_BUILTIN_PERR,
  ALPHA_BUILTIN_PKLB,
  ALPHA_BUILTIN_PKWB,
  ALPHA_BUILTIN_UNPKBL,
  ALPHA_BUILTIN_UNPKBW,

  /* TARGET_CIX */
  ALPHA_BUILTIN_CTTZ,
  ALPHA_BUILTIN_CTLZ,
  ALPHA_BUILTIN_CTPOP,

  ALPHA_BUILTIN_max
};

static enum insn_code const code_for_builtin[ALPHA_BUILTIN_max] = {
  CODE_FOR_builtin_cmpbge,
  CODE_FOR_extbl,
  CODE_FOR_extwl,
  CODE_FOR_extll,
  CODE_FOR_extql,
  CODE_FOR_extwh,
  CODE_FOR_extlh,
  CODE_FOR_extqh,
  CODE_FOR_builtin_insbl,
  CODE_FOR_builtin_inswl,
  CODE_FOR_builtin_insll,
  CODE_FOR_insql,
  CODE_FOR_inswh,
  CODE_FOR_inslh,
  CODE_FOR_insqh,
  CODE_FOR_mskbl,
  CODE_FOR_mskwl,
  CODE_FOR_mskll,
  CODE_FOR_mskql,
  CODE_FOR_mskwh,
  CODE_FOR_msklh,
  CODE_FOR_mskqh,
  CODE_FOR_umuldi3_highpart,
  CODE_FOR_builtin_zap,
  CODE_FOR_builtin_zapnot,
  CODE_FOR_builtin_amask,
  CODE_FOR_builtin_implver,
  CODE_FOR_builtin_rpcc,
  CODE_FOR_builtin_establish_vms_condition_handler,
  CODE_FOR_builtin_revert_vms_condition_handler,

  /* TARGET_MAX */
  CODE_FOR_builtin_minub8,
  CODE_FOR_builtin_minsb8,
  CODE_FOR_builtin_minuw4,
  CODE_FOR_builtin_minsw4,
  CODE_FOR_builtin_maxub8,
  CODE_FOR_builtin_maxsb8,
  CODE_FOR_builtin_maxuw4,
  CODE_FOR_builtin_maxsw4,
  CODE_FOR_builtin_perr,
  CODE_FOR_builtin_pklb,
  CODE_FOR_builtin_pkwb,
  CODE_FOR_builtin_unpkbl,
  CODE_FOR_builtin_unpkbw,

  /* TARGET_CIX */
  CODE_FOR_ctzdi2,
  CODE_FOR_clzdi2,
  CODE_FOR_popcountdi2
};

struct alpha_builtin_def
{
  const char *name;
  enum alpha_builtin code;
  unsigned int target_mask;
  bool is_const;
};

static struct alpha_builtin_def const zero_arg_builtins[] = {
  { "__builtin_alpha_implver",	ALPHA_BUILTIN_IMPLVER,	0, true },
  { "__builtin_alpha_rpcc",	ALPHA_BUILTIN_RPCC,	0, false }
};

static struct alpha_builtin_def const one_arg_builtins[] = {
  { "__builtin_alpha_amask",	ALPHA_BUILTIN_AMASK,	0, true },
  { "__builtin_alpha_pklb",	ALPHA_BUILTIN_PKLB,	MASK_MAX, true },
  { "__builtin_alpha_pkwb",	ALPHA_BUILTIN_PKWB,	MASK_MAX, true },
  { "__builtin_alpha_unpkbl",	ALPHA_BUILTIN_UNPKBL,	MASK_MAX, true },
  { "__builtin_alpha_unpkbw",	ALPHA_BUILTIN_UNPKBW,	MASK_MAX, true },
  { "__builtin_alpha_cttz",	ALPHA_BUILTIN_CTTZ,	MASK_CIX, true },
  { "__builtin_alpha_ctlz",	ALPHA_BUILTIN_CTLZ,	MASK_CIX, true },
  { "__builtin_alpha_ctpop",	ALPHA_BUILTIN_CTPOP,	MASK_CIX, true }
};

static struct alpha_builtin_def const two_arg_builtins[] = {
  { "__builtin_alpha_cmpbge",	ALPHA_BUILTIN_CMPBGE,	0, true },
  { "__builtin_alpha_extbl",	ALPHA_BUILTIN_EXTBL,	0, true },
  { "__builtin_alpha_extwl",	ALPHA_BUILTIN_EXTWL,	0, true },
  { "__builtin_alpha_extll",	ALPHA_BUILTIN_EXTLL,	0, true },
  { "__builtin_alpha_extql",	ALPHA_BUILTIN_EXTQL,	0, true },
  { "__builtin_alpha_extwh",	ALPHA_BUILTIN_EXTWH,	0, true },
  { "__builtin_alpha_extlh",	ALPHA_BUILTIN_EXTLH,	0, true },
  { "__builtin_alpha_extqh",	ALPHA_BUILTIN_EXTQH,	0, true },
  { "__builtin_alpha_insbl",	ALPHA_BUILTIN_INSBL,	0, true },
  { "__builtin_alpha_inswl",	ALPHA_BUILTIN_INSWL,	0, true },
  { "__builtin_alpha_insll",	ALPHA_BUILTIN_INSLL,	0, true },
  { "__builtin_alpha_insql",	ALPHA_BUILTIN_INSQL,	0, true },
  { "__builtin_alpha_inswh",	ALPHA_BUILTIN_INSWH,	0, true },
  { "__builtin_alpha_inslh",	ALPHA_BUILTIN_INSLH,	0, true },
  { "__builtin_alpha_insqh",	ALPHA_BUILTIN_INSQH,	0, true },
  { "__builtin_alpha_mskbl",	ALPHA_BUILTIN_MSKBL,	0, true },
  { "__builtin_alpha_mskwl",	ALPHA_BUILTIN_MSKWL,	0, true },
  { "__builtin_alpha_mskll",	ALPHA_BUILTIN_MSKLL,	0, true },
  { "__builtin_alpha_mskql",	ALPHA_BUILTIN_MSKQL,	0, true },
  { "__builtin_alpha_mskwh",	ALPHA_BUILTIN_MSKWH,	0, true },
  { "__builtin_alpha_msklh",	ALPHA_BUILTIN_MSKLH,	0, true },
  { "__builtin_alpha_mskqh",	ALPHA_BUILTIN_MSKQH,	0, true },
  { "__builtin_alpha_umulh",	ALPHA_BUILTIN_UMULH,	0, true },
  { "__builtin_alpha_zap",	ALPHA_BUILTIN_ZAP,	0, true },
  { "__builtin_alpha_zapnot",	ALPHA_BUILTIN_ZAPNOT,	0, true },
  { "__builtin_alpha_minub8",	ALPHA_BUILTIN_MINUB8,	MASK_MAX, true },
  { "__builtin_alpha_minsb8",	ALPHA_BUILTIN_MINSB8,	MASK_MAX, true },
  { "__builtin_alpha_minuw4",	ALPHA_BUILTIN_MINUW4,	MASK_MAX, true },
  { "__builtin_alpha_minsw4",	ALPHA_BUILTIN_MINSW4,	MASK_MAX, true },
  { "__builtin_alpha_maxub8",	ALPHA_BUILTIN_MAXUB8,	MASK_MAX, true },
  { "__builtin_alpha_maxsb8",	ALPHA_BUILTIN_MAXSB8,	MASK_MAX, true },
  { "__builtin_alpha_maxuw4",	ALPHA_BUILTIN_MAXUW4,	MASK_MAX, true },
  { "__builtin_alpha_maxsw4",	ALPHA_BUILTIN_MAXSW4,	MASK_MAX, true },
  { "__builtin_alpha_perr",	ALPHA_BUILTIN_PERR,	MASK_MAX, true }
};

static GTY(()) tree alpha_dimode_u;
static GTY(()) tree alpha_v8qi_u;
static GTY(()) tree alpha_v8qi_s;
static GTY(()) tree alpha_v4hi_u;
static GTY(()) tree alpha_v4hi_s;

static GTY(()) tree alpha_builtins[(int) ALPHA_BUILTIN_max];

/* Return the alpha builtin for CODE.  */

static tree
alpha_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
{
  if (code >= ALPHA_BUILTIN_max)
    return error_mark_node;
  return alpha_builtins[code];
}

/* Helper function of alpha_init_builtins.  Add the built-in specified
   by NAME, TYPE, CODE, and ECF.  */

static void
alpha_builtin_function (const char *name, tree ftype,
			enum alpha_builtin code, unsigned ecf)
{
  tree decl = add_builtin_function (name, ftype, (int) code,
				    BUILT_IN_MD, NULL, NULL_TREE);

  if (ecf & ECF_CONST)
    TREE_READONLY (decl) = 1;
  if (ecf & ECF_NOTHROW)
    TREE_NOTHROW (decl) = 1;

  alpha_builtins [(int) code] = decl;
}

/* Helper function of alpha_init_builtins.  Add the COUNT built-in
   functions pointed to by P, with function type FTYPE.  */

static void
alpha_add_builtins (const struct alpha_builtin_def *p, size_t count,
		    tree ftype)
{
  size_t i;

  for (i = 0; i < count; ++i, ++p)
    if ((target_flags & p->target_mask) == p->target_mask)
      alpha_builtin_function (p->name, ftype, p->code,
			      (p->is_const ? ECF_CONST : 0) | ECF_NOTHROW);
}

static void
alpha_init_builtins (void)
{
  tree ftype;

  alpha_dimode_u = lang_hooks.types.type_for_mode (DImode, 1);
  alpha_v8qi_u = build_vector_type (unsigned_intQI_type_node, 8);
  alpha_v8qi_s = build_vector_type (intQI_type_node, 8);
  alpha_v4hi_u = build_vector_type (unsigned_intHI_type_node, 4);
  alpha_v4hi_s = build_vector_type (intHI_type_node, 4);

  ftype = build_function_type_list (alpha_dimode_u, NULL_TREE);
  alpha_add_builtins (zero_arg_builtins, ARRAY_SIZE (zero_arg_builtins), ftype);

  ftype = build_function_type_list (alpha_dimode_u, alpha_dimode_u, NULL_TREE);
  alpha_add_builtins (one_arg_builtins, ARRAY_SIZE (one_arg_builtins), ftype);

  ftype = build_function_type_list (alpha_dimode_u, alpha_dimode_u,
				    alpha_dimode_u, NULL_TREE);
  alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins), ftype);

  if (TARGET_ABI_OPEN_VMS)
    {
      ftype = build_function_type_list (ptr_type_node, ptr_type_node,
					NULL_TREE);
      alpha_builtin_function ("__builtin_establish_vms_condition_handler",
			      ftype,
			      ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
			      0);

      ftype = build_function_type_list (ptr_type_node, void_type_node,
					NULL_TREE);
      alpha_builtin_function ("__builtin_revert_vms_condition_handler", ftype,
			      ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER, 0);

      vms_patch_builtins ();
    }
}

/* Expand an expression EXP that calls a built-in function,
   with result going to TARGET if that's convenient
   (and in mode MODE if that's convenient).
   SUBTARGET may be used as the target for computing one of EXP's operands.
   IGNORE is nonzero if the value is to be ignored.  */

static rtx
alpha_expand_builtin (tree exp, rtx target,
		      rtx subtarget ATTRIBUTE_UNUSED,
		      machine_mode mode ATTRIBUTE_UNUSED,
		      int ignore ATTRIBUTE_UNUSED)
{
#define MAX_ARGS 2

  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
  tree arg;
  call_expr_arg_iterator iter;
  enum insn_code icode;
  rtx op[MAX_ARGS], pat;
  int arity;
  bool nonvoid;

  if (fcode >= ALPHA_BUILTIN_max)
    internal_error ("bad builtin fcode");
  icode = code_for_builtin[fcode];
  if (icode == 0)
    internal_error ("bad builtin fcode");

  nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;

  arity = 0;
  FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
    {
      const struct insn_operand_data *insn_op;

      if (arg == error_mark_node)
	return NULL_RTX;
      if (arity > MAX_ARGS)
	return NULL_RTX;

      insn_op = &insn_data[icode].operand[arity + nonvoid];

      op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);

      if (!(*insn_op->predicate) (op[arity], insn_op->mode))
	op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
      arity++;
    }

  if (nonvoid)
    {
      machine_mode tmode = insn_data[icode].operand[0].mode;
      if (!target
	  || GET_MODE (target) != tmode
	  || !(*insn_data[icode].operand[0].predicate) (target, tmode))
	target = gen_reg_rtx (tmode);
    }

  switch (arity)
    {
    case 0:
      pat = GEN_FCN (icode) (target);
      break;
    case 1:
      if (nonvoid)
        pat = GEN_FCN (icode) (target, op[0]);
      else
	pat = GEN_FCN (icode) (op[0]);
      break;
    case 2:
      pat = GEN_FCN (icode) (target, op[0], op[1]);
      break;
    default:
      gcc_unreachable ();
    }
  if (!pat)
    return NULL_RTX;
  emit_insn (pat);

  if (nonvoid)
    return target;
  else
    return const0_rtx;
}

/* Fold the builtin for the CMPBGE instruction.  This is a vector comparison
   with an 8-bit output vector.  OPINT contains the integer operands; bit N
   of OP_CONST is set if OPINT[N] is valid.  */

static tree
alpha_fold_builtin_cmpbge (unsigned HOST_WIDE_INT opint[], long op_const)
{
  if (op_const == 3)
    {
      int i, val;
      for (i = 0, val = 0; i < 8; ++i)
	{
	  unsigned HOST_WIDE_INT c0 = (opint[0] >> (i * 8)) & 0xff;
	  unsigned HOST_WIDE_INT c1 = (opint[1] >> (i * 8)) & 0xff;
	  if (c0 >= c1)
	    val |= 1 << i;
	}
      return build_int_cst (alpha_dimode_u, val);
    }
  else if (op_const == 2 && opint[1] == 0)
    return build_int_cst (alpha_dimode_u, 0xff);
  return NULL;
}

/* Fold the builtin for the ZAPNOT instruction.  This is essentially a 
   specialized form of an AND operation.  Other byte manipulation instructions
   are defined in terms of this instruction, so this is also used as a
   subroutine for other builtins.

   OP contains the tree operands; OPINT contains the extracted integer values.
   Bit N of OP_CONST it set if OPINT[N] is valid.  OP may be null if only
   OPINT may be considered.  */

static tree
alpha_fold_builtin_zapnot (tree *op, unsigned HOST_WIDE_INT opint[],
			   long op_const)
{
  if (op_const & 2)
    {
      unsigned HOST_WIDE_INT mask = 0;
      int i;

      for (i = 0; i < 8; ++i)
	if ((opint[1] >> i) & 1)
	  mask |= (unsigned HOST_WIDE_INT)0xff << (i * 8);

      if (op_const & 1)
	return build_int_cst (alpha_dimode_u, opint[0] & mask);

      if (op)
	return fold_build2 (BIT_AND_EXPR, alpha_dimode_u, op[0],
			    build_int_cst (alpha_dimode_u, mask));
    }
  else if ((op_const & 1) && opint[0] == 0)
    return build_int_cst (alpha_dimode_u, 0);
  return NULL;
}

/* Fold the builtins for the EXT family of instructions.  */

static tree
alpha_fold_builtin_extxx (tree op[], unsigned HOST_WIDE_INT opint[],
			  long op_const, unsigned HOST_WIDE_INT bytemask,
			  bool is_high)
{
  long zap_const = 2;
  tree *zap_op = NULL;

  if (op_const & 2)
    {
      unsigned HOST_WIDE_INT loc;

      loc = opint[1] & 7;
      loc *= BITS_PER_UNIT;

      if (loc != 0)
	{
	  if (op_const & 1)
	    {
	      unsigned HOST_WIDE_INT temp = opint[0];
	      if (is_high)
		temp <<= loc;
	      else
		temp >>= loc;
	      opint[0] = temp;
	      zap_const = 3;
	    }
	}
      else
	zap_op = op;
    }
  
  opint[1] = bytemask;
  return alpha_fold_builtin_zapnot (zap_op, opint, zap_const);
}

/* Fold the builtins for the INS family of instructions.  */

static tree
alpha_fold_builtin_insxx (tree op[], unsigned HOST_WIDE_INT opint[],
			  long op_const, unsigned HOST_WIDE_INT bytemask,
			  bool is_high)
{
  if ((op_const & 1) && opint[0] == 0)
    return build_int_cst (alpha_dimode_u, 0);

  if (op_const & 2)
    {
      unsigned HOST_WIDE_INT temp, loc, byteloc;
      tree *zap_op = NULL;

      loc = opint[1] & 7;
      bytemask <<= loc;

      temp = opint[0];
      if (is_high)
	{
	  byteloc = (64 - (loc * 8)) & 0x3f;
	  if (byteloc == 0)
	    zap_op = op;
	  else
	    temp >>= byteloc;
	  bytemask >>= 8;
	}
      else
	{
	  byteloc = loc * 8;
	  if (byteloc == 0)
	    zap_op = op;
	  else
	    temp <<= byteloc;
	}

      opint[0] = temp;
      opint[1] = bytemask;
      return alpha_fold_builtin_zapnot (zap_op, opint, op_const);
    }

  return NULL;
}

static tree
alpha_fold_builtin_mskxx (tree op[], unsigned HOST_WIDE_INT opint[],
			  long op_const, unsigned HOST_WIDE_INT bytemask,
			  bool is_high)
{
  if (op_const & 2)
    {
      unsigned HOST_WIDE_INT loc;

      loc = opint[1] & 7;
      bytemask <<= loc;

      if (is_high)
	bytemask >>= 8;

      opint[1] = bytemask ^ 0xff;
    }

  return alpha_fold_builtin_zapnot (op, opint, op_const);
}

static tree
alpha_fold_vector_minmax (enum tree_code code, tree op[], tree vtype)
{
  tree op0 = fold_convert (vtype, op[0]);
  tree op1 = fold_convert (vtype, op[1]);
  tree val = fold_build2 (code, vtype, op0, op1);
  return fold_build1 (VIEW_CONVERT_EXPR, alpha_dimode_u, val);
}

static tree
alpha_fold_builtin_perr (unsigned HOST_WIDE_INT opint[], long op_const)
{
  unsigned HOST_WIDE_INT temp = 0;
  int i;

  if (op_const != 3)
    return NULL;

  for (i = 0; i < 8; ++i)
    {
      unsigned HOST_WIDE_INT a = (opint[0] >> (i * 8)) & 0xff;
      unsigned HOST_WIDE_INT b = (opint[1] >> (i * 8)) & 0xff;
      if (a >= b)
	temp += a - b;
      else
	temp += b - a;
    }

  return build_int_cst (alpha_dimode_u, temp);
}

static tree
alpha_fold_builtin_pklb (unsigned HOST_WIDE_INT opint[], long op_const)
{
  unsigned HOST_WIDE_INT temp;

  if (op_const == 0)
    return NULL;

  temp = opint[0] & 0xff;
  temp |= (opint[0] >> 24) & 0xff00;

  return build_int_cst (alpha_dimode_u, temp);
}

static tree
alpha_fold_builtin_pkwb (unsigned HOST_WIDE_INT opint[], long op_const)
{
  unsigned HOST_WIDE_INT temp;

  if (op_const == 0)
    return NULL;

  temp = opint[0] & 0xff;
  temp |= (opint[0] >>  8) & 0xff00;
  temp |= (opint[0] >> 16) & 0xff0000;
  temp |= (opint[0] >> 24) & 0xff000000;

  return build_int_cst (alpha_dimode_u, temp);
}

static tree
alpha_fold_builtin_unpkbl (unsigned HOST_WIDE_INT opint[], long op_const)
{
  unsigned HOST_WIDE_INT temp;

  if (op_const == 0)
    return NULL;

  temp = opint[0] & 0xff;
  temp |= (opint[0] & 0xff00) << 24;

  return build_int_cst (alpha_dimode_u, temp);
}

static tree
alpha_fold_builtin_unpkbw (unsigned HOST_WIDE_INT opint[], long op_const)
{
  unsigned HOST_WIDE_INT temp;

  if (op_const == 0)
    return NULL;

  temp = opint[0] & 0xff;
  temp |= (opint[0] & 0x0000ff00) << 8;
  temp |= (opint[0] & 0x00ff0000) << 16;
  temp |= (opint[0] & 0xff000000) << 24;

  return build_int_cst (alpha_dimode_u, temp);
}

static tree
alpha_fold_builtin_cttz (unsigned HOST_WIDE_INT opint[], long op_const)
{
  unsigned HOST_WIDE_INT temp;

  if (op_const == 0)
    return NULL;

  if (opint[0] == 0)
    temp = 64;
  else
    temp = exact_log2 (opint[0] & -opint[0]);

  return build_int_cst (alpha_dimode_u, temp);
}

static tree
alpha_fold_builtin_ctlz (unsigned HOST_WIDE_INT opint[], long op_const)
{
  unsigned HOST_WIDE_INT temp;

  if (op_const == 0)
    return NULL;

  if (opint[0] == 0)
    temp = 64;
  else
    temp = 64 - floor_log2 (opint[0]) - 1;

  return build_int_cst (alpha_dimode_u, temp);
}

static tree
alpha_fold_builtin_ctpop (unsigned HOST_WIDE_INT opint[], long op_const)
{
  unsigned HOST_WIDE_INT temp, op;

  if (op_const == 0)
    return NULL;

  op = opint[0];
  temp = 0;
  while (op)
    temp++, op &= op - 1;

  return build_int_cst (alpha_dimode_u, temp);
}

/* Fold one of our builtin functions.  */

static tree
alpha_fold_builtin (tree fndecl, int n_args, tree *op,
		    bool ignore ATTRIBUTE_UNUSED)
{
  unsigned HOST_WIDE_INT opint[MAX_ARGS];
  long op_const = 0;
  int i;

  if (n_args > MAX_ARGS)
    return NULL;

  for (i = 0; i < n_args; i++)
    {
      tree arg = op[i];
      if (arg == error_mark_node)
	return NULL;

      opint[i] = 0;
      if (TREE_CODE (arg) == INTEGER_CST)
	{
          op_const |= 1L << i;
	  opint[i] = int_cst_value (arg);
	}
    }

  switch (DECL_MD_FUNCTION_CODE (fndecl))
    {
    case ALPHA_BUILTIN_CMPBGE:
      return alpha_fold_builtin_cmpbge (opint, op_const);

    case ALPHA_BUILTIN_EXTBL:
      return alpha_fold_builtin_extxx (op, opint, op_const, 0x01, false);
    case ALPHA_BUILTIN_EXTWL:
      return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, false);
    case ALPHA_BUILTIN_EXTLL:
      return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, false);
    case ALPHA_BUILTIN_EXTQL:
      return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, false);
    case ALPHA_BUILTIN_EXTWH:
      return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, true);
    case ALPHA_BUILTIN_EXTLH:
      return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, true);
    case ALPHA_BUILTIN_EXTQH:
      return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, true);

    case ALPHA_BUILTIN_INSBL:
      return alpha_fold_builtin_insxx (op, opint, op_const, 0x01, false);
    case ALPHA_BUILTIN_INSWL:
      return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, false);
    case ALPHA_BUILTIN_INSLL:
      return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, false);
    case ALPHA_BUILTIN_INSQL:
      return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, false);
    case ALPHA_BUILTIN_INSWH:
      return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, true);
    case ALPHA_BUILTIN_INSLH:
      return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, true);
    case ALPHA_BUILTIN_INSQH:
      return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, true);

    case ALPHA_BUILTIN_MSKBL:
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0x01, false);
    case ALPHA_BUILTIN_MSKWL:
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, false);
    case ALPHA_BUILTIN_MSKLL:
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, false);
    case ALPHA_BUILTIN_MSKQL:
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, false);
    case ALPHA_BUILTIN_MSKWH:
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, true);
    case ALPHA_BUILTIN_MSKLH:
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, true);
    case ALPHA_BUILTIN_MSKQH:
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, true);

    case ALPHA_BUILTIN_ZAP:
      opint[1] ^= 0xff;
      /* FALLTHRU */
    case ALPHA_BUILTIN_ZAPNOT:
      return alpha_fold_builtin_zapnot (op, opint, op_const);

    case ALPHA_BUILTIN_MINUB8:
      return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_u);
    case ALPHA_BUILTIN_MINSB8:
      return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_s);
    case ALPHA_BUILTIN_MINUW4:
      return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_u);
    case ALPHA_BUILTIN_MINSW4:
      return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_s);
    case ALPHA_BUILTIN_MAXUB8:
      return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_u);
    case ALPHA_BUILTIN_MAXSB8:
      return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_s);
    case ALPHA_BUILTIN_MAXUW4:
      return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_u);
    case ALPHA_BUILTIN_MAXSW4:
      return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_s);

    case ALPHA_BUILTIN_PERR:
      return alpha_fold_builtin_perr (opint, op_const);
    case ALPHA_BUILTIN_PKLB:
      return alpha_fold_builtin_pklb (opint, op_const);
    case ALPHA_BUILTIN_PKWB:
      return alpha_fold_builtin_pkwb (opint, op_const);
    case ALPHA_BUILTIN_UNPKBL:
      return alpha_fold_builtin_unpkbl (opint, op_const);
    case ALPHA_BUILTIN_UNPKBW:
      return alpha_fold_builtin_unpkbw (opint, op_const);

    case ALPHA_BUILTIN_CTTZ:
      return alpha_fold_builtin_cttz (opint, op_const);
    case ALPHA_BUILTIN_CTLZ:
      return alpha_fold_builtin_ctlz (opint, op_const);
    case ALPHA_BUILTIN_CTPOP:
      return alpha_fold_builtin_ctpop (opint, op_const);

    case ALPHA_BUILTIN_AMASK:
    case ALPHA_BUILTIN_IMPLVER:
    case ALPHA_BUILTIN_RPCC:
      /* None of these are foldable at compile-time.  */
    default:
      return NULL;
    }
}

bool
alpha_gimple_fold_builtin (gimple_stmt_iterator *gsi)
{
  bool changed = false;
  gimple *stmt = gsi_stmt (*gsi);
  tree call = gimple_call_fn (stmt);
  gimple *new_stmt = NULL;

  if (call)
    {
      tree fndecl = gimple_call_fndecl (stmt);

      if (fndecl)
	{
	  tree arg0, arg1;

	  switch (DECL_MD_FUNCTION_CODE (fndecl))
	    {
	    case ALPHA_BUILTIN_UMULH:
	      arg0 = gimple_call_arg (stmt, 0);
	      arg1 = gimple_call_arg (stmt, 1);

	      new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
					      MULT_HIGHPART_EXPR, arg0, arg1);
	      break;
	    default:
	      break;
	    }
	}
    }

  if (new_stmt)
    {
      gsi_replace (gsi, new_stmt, true);
      changed = true;
    }

  return changed;
}

/* This page contains routines that are used to determine what the function
   prologue and epilogue code will do and write them out.  */

/* Compute the size of the save area in the stack.  */

/* These variables are used for communication between the following functions.
   They indicate various things about the current function being compiled
   that are used to tell what kind of prologue, epilogue and procedure
   descriptor to generate.  */

/* Nonzero if we need a stack procedure.  */
enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
static enum alpha_procedure_types alpha_procedure_type;

/* Register number (either FP or SP) that is used to unwind the frame.  */
static int vms_unwind_regno;

/* Register number used to save FP.  We need not have one for RA since
   we don't modify it for register procedures.  This is only defined
   for register frame procedures.  */
static int vms_save_fp_regno;

/* Register number used to reference objects off our PV.  */
static int vms_base_regno;

/* Compute register masks for saved registers, register save area size,
   and total frame size.  */
static void
alpha_compute_frame_layout (void)
{
  unsigned HOST_WIDE_INT sa_mask = 0;
  HOST_WIDE_INT frame_size;
  int sa_size;

  /* When outputting a thunk, we don't have valid register life info,
     but assemble_start_function wants to output .frame and .mask
     directives.  */
  if (!cfun->is_thunk)
    {
      if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
	sa_mask |= HOST_WIDE_INT_1U << HARD_FRAME_POINTER_REGNUM;

      /* One for every register we have to save.  */
      for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (! call_used_or_fixed_reg_p (i)
	    && df_regs_ever_live_p (i) && i != REG_RA)
	  sa_mask |= HOST_WIDE_INT_1U << i;

      /* We need to restore these for the handler.  */
      if (crtl->calls_eh_return)
	{
	  for (unsigned i = 0; ; ++i)
	    {
	      unsigned regno = EH_RETURN_DATA_REGNO (i);
	      if (regno == INVALID_REGNUM)
		break;
	      sa_mask |= HOST_WIDE_INT_1U << regno;
	    }
	}

      /* If any register spilled, then spill the return address also.  */
      /* ??? This is required by the Digital stack unwind specification
	 and isn't needed if we're doing Dwarf2 unwinding.  */
      if (sa_mask || alpha_ra_ever_killed ())
	sa_mask |= HOST_WIDE_INT_1U << REG_RA;
    }

  sa_size = popcount_hwi(sa_mask);
  frame_size = get_frame_size ();

  if (TARGET_ABI_OPEN_VMS)
    {
      /* Start with a stack procedure if we make any calls (REG_RA used), or
	 need a frame pointer, with a register procedure if we otherwise need
	 at least a slot, and with a null procedure in other cases.  */
      if ((sa_mask >> REG_RA) & 1 || frame_pointer_needed)
	alpha_procedure_type = PT_STACK;
      else if (frame_size != 0)
	alpha_procedure_type = PT_REGISTER;
      else
	alpha_procedure_type = PT_NULL;

      /* Don't reserve space for saving FP & RA yet.  Do that later after we've
	 made the final decision on stack procedure vs register procedure.  */
      if (alpha_procedure_type == PT_STACK)
	sa_size -= 2;

      /* Decide whether to refer to objects off our PV via FP or PV.
	 If we need FP for something else or if we receive a nonlocal
	 goto (which expects PV to contain the value), we must use PV.
	 Otherwise, start by assuming we can use FP.  */

      vms_base_regno
	= (frame_pointer_needed
	   || cfun->has_nonlocal_label
	   || alpha_procedure_type == PT_STACK
	   || crtl->outgoing_args_size)
	  ? REG_PV : HARD_FRAME_POINTER_REGNUM;

      /* If we want to copy PV into FP, we need to find some register
	 in which to save FP.  */
      vms_save_fp_regno = -1;
      if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
	for (unsigned i = 0; i < 32; i++)
	  if (! fixed_regs[i] && call_used_or_fixed_reg_p (i)
	      && ! df_regs_ever_live_p (i))
	    {
	      vms_save_fp_regno = i;
	      break;
	    }

      /* A VMS condition handler requires a stack procedure in our
	 implementation. (not required by the calling standard).  */
      if ((vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
	  || cfun->machine->uses_condition_handler)
	vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
      else if (alpha_procedure_type == PT_NULL)
	vms_base_regno = REG_PV;

      /* Stack unwinding should be done via FP unless we use it for PV.  */
      vms_unwind_regno = (vms_base_regno == REG_PV
			  ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);

      /* If this is a stack procedure, allow space for saving FP, RA and
	 a condition handler slot if needed.  */
      if (alpha_procedure_type == PT_STACK)
	sa_size += 2 + cfun->machine->uses_condition_handler;
    }
  else
    {
      /* Our size must be even (multiple of 16 bytes).  */
      if (sa_size & 1)
	sa_size++;
    }
  sa_size *= 8;

  if (TARGET_ABI_OPEN_VMS)
    frame_size = ALPHA_ROUND (sa_size
			      + (alpha_procedure_type == PT_STACK ? 8 : 0)
			      + frame_size
			      + crtl->args.pretend_args_size);
  else
    frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
		  + sa_size
		  + ALPHA_ROUND (frame_size + crtl->args.pretend_args_size));

  cfun->machine->sa_mask = sa_mask;
  cfun->machine->sa_size = sa_size;
  cfun->machine->frame_size = frame_size;
}

#undef  TARGET_COMPUTE_FRAME_LAYOUT
#define TARGET_COMPUTE_FRAME_LAYOUT  alpha_compute_frame_layout

/* Return 1 if this function can directly return via $26.  */

bool
direct_return (void)
{
  return (TARGET_ABI_OSF
	  && reload_completed
	  && cfun->machine->frame_size == 0);
}

/* Define the offset between two registers, one to be eliminated,
   and the other its replacement, at the start of a routine.  */

HOST_WIDE_INT
alpha_initial_elimination_offset (unsigned int from,
				  unsigned int to ATTRIBUTE_UNUSED)
{
  HOST_WIDE_INT ret;

  ret = cfun->machine->sa_size;
  ret += ALPHA_ROUND (crtl->outgoing_args_size);

  switch (from)
    {
    case FRAME_POINTER_REGNUM:
      break;

    case ARG_POINTER_REGNUM:
      ret += (ALPHA_ROUND (get_frame_size ()
			   + crtl->args.pretend_args_size)
	      - crtl->args.pretend_args_size);
      break;

    default:
      gcc_unreachable ();
    }

  return ret;
}

#if TARGET_ABI_OPEN_VMS

/* Worker function for TARGET_CAN_ELIMINATE.  */

static bool
alpha_vms_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
{
  switch (alpha_procedure_type)
    {
    case PT_NULL:
      /* NULL procedures have no frame of their own and we only
	 know how to resolve from the current stack pointer.  */
      return to == STACK_POINTER_REGNUM;

    case PT_REGISTER:
    case PT_STACK:
      /* We always eliminate except to the stack pointer if there is no
	 usable frame pointer at hand.  */
      return (to != STACK_POINTER_REGNUM
	      || vms_unwind_regno != HARD_FRAME_POINTER_REGNUM);
    }

  gcc_unreachable ();
}

/* FROM is to be eliminated for TO. Return the offset so that TO+offset
   designates the same location as FROM.  */

HOST_WIDE_INT
alpha_vms_initial_elimination_offset (unsigned int from, unsigned int to)
{ 
  /* The only possible attempts we ever expect are ARG or FRAME_PTR to
     HARD_FRAME or STACK_PTR.  We need the alpha_procedure_type to decide
     on the proper computations and will need the register save area size
     in most cases.  */

  HOST_WIDE_INT sa_size = cfun->machine->sa_size;

  /* PT_NULL procedures have no frame of their own and we only allow
     elimination to the stack pointer. This is the argument pointer and we
     resolve the soft frame pointer to that as well.  */
     
  if (alpha_procedure_type == PT_NULL)
    return 0;

  /* For a PT_STACK procedure the frame layout looks as follows

                      -----> decreasing addresses

		   <             size rounded up to 16       |   likewise   >
     --------------#------------------------------+++--------------+++-------#
     incoming args # pretended args | "frame" | regs sa | PV | outgoing args #
     --------------#---------------------------------------------------------#
                                   ^         ^              ^               ^
			      ARG_PTR FRAME_PTR HARD_FRAME_PTR       STACK_PTR

			      
     PT_REGISTER procedures are similar in that they may have a frame of their
     own. They have no regs-sa/pv/outgoing-args area.

     We first compute offset to HARD_FRAME_PTR, then add what we need to get
     to STACK_PTR if need be.  */
  
  {
    HOST_WIDE_INT offset;
    HOST_WIDE_INT pv_save_size = alpha_procedure_type == PT_STACK ? 8 : 0;

    switch (from)
      {
      case FRAME_POINTER_REGNUM:
	offset = ALPHA_ROUND (sa_size + pv_save_size);
	break;
      case ARG_POINTER_REGNUM:
	offset = (ALPHA_ROUND (sa_size + pv_save_size
			       + get_frame_size ()
			       + crtl->args.pretend_args_size)
		  - crtl->args.pretend_args_size);
	break;
      default:
	gcc_unreachable ();
      }
    
    if (to == STACK_POINTER_REGNUM)
      offset += ALPHA_ROUND (crtl->outgoing_args_size);
    
    return offset;
  }
}

#define COMMON_OBJECT "common_object"

static tree
common_object_handler (tree *node, tree name ATTRIBUTE_UNUSED,
		       tree args ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED,
		       bool *no_add_attrs ATTRIBUTE_UNUSED)
{
  tree decl = *node;
  gcc_assert (DECL_P (decl));

  DECL_COMMON (decl) = 1;
  return NULL_TREE;
}

static const struct attribute_spec vms_attribute_table[] =
{
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
       affects_type_identity, handler, exclude } */
  { COMMON_OBJECT,   0, 1, true,  false, false, false, common_object_handler,
    NULL },
  { NULL,            0, 0, false, false, false, false, NULL, NULL }
};

void
vms_output_aligned_decl_common(FILE *file, tree decl, const char *name,
			       unsigned HOST_WIDE_INT size,
			       unsigned int align)
{
  tree attr = DECL_ATTRIBUTES (decl);
  fprintf (file, "%s", COMMON_ASM_OP);
  assemble_name (file, name);
  fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED, size);
  /* ??? Unlike on OSF/1, the alignment factor is not in log units.  */
  fprintf (file, ",%u", align / BITS_PER_UNIT);
  if (attr)
    {
      attr = lookup_attribute (COMMON_OBJECT, attr);
      if (attr)
        fprintf (file, ",%s",
		 IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (attr))));
    }
  fputc ('\n', file);
}

#undef COMMON_OBJECT

#endif

bool
alpha_find_lo_sum_using_gp (rtx insn)
{
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
    {
      const_rtx x = *iter;
      if (GET_CODE (x) == LO_SUM && XEXP (x, 0) == pic_offset_table_rtx)
	return true;
    }
  return false;
}

static int
alpha_does_function_need_gp (void)
{
  rtx_insn *insn;

  /* The GP being variable is an OSF abi thing.  */
  if (! TARGET_ABI_OSF)
    return 0;

  /* We need the gp to load the address of __mcount.  */
  if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
    return 1;

  /* The code emitted by alpha_output_mi_thunk_osf uses the gp.  */
  if (cfun->is_thunk)
    return 1;

  /* The nonlocal receiver pattern assumes that the gp is valid for
     the nested function.  Reasonable because it's almost always set
     correctly already.  For the cases where that's wrong, make sure
     the nested function loads its gp on entry.  */
  if (crtl->has_nonlocal_goto)
    return 1;

  /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
     Even if we are a static function, we still need to do this in case
     our address is taken and passed to something like qsort.  */

  push_topmost_sequence ();
  insn = get_insns ();
  pop_topmost_sequence ();

  for (; insn; insn = NEXT_INSN (insn))
    if (NONDEBUG_INSN_P (insn)
	&& GET_CODE (PATTERN (insn)) != USE
	&& GET_CODE (PATTERN (insn)) != CLOBBER
	&& get_attr_usegp (insn))
      return 1;

  return 0;
}


/* Helper function to set RTX_FRAME_RELATED_P on instructions, including
   sequences.  */

static rtx_insn *
set_frame_related_p (void)
{
  rtx_insn *seq = get_insns ();
  rtx_insn *insn;

  end_sequence ();

  if (!seq)
    return NULL;

  if (INSN_P (seq))
    {
      insn = seq;
      while (insn != NULL_RTX)
	{
	  RTX_FRAME_RELATED_P (insn) = 1;
	  insn = NEXT_INSN (insn);
	}
      seq = emit_insn (seq);
    }
  else
    {
      seq = emit_insn (seq);
      RTX_FRAME_RELATED_P (seq) = 1;
    }
  return seq;
}

#define FRP(exp)  (start_sequence (), exp, set_frame_related_p ())

/* Generates a store with the proper unwind info attached.  VALUE is
   stored at BASE_REG+BASE_OFS.  If FRAME_BIAS is nonzero, then BASE_REG
   contains SP+FRAME_BIAS, and that is the unwind info that should be
   generated.  If FRAME_REG != VALUE, then VALUE is being stored on
   behalf of FRAME_REG, and FRAME_REG should be present in the unwind.  */

static void
emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias,
		    HOST_WIDE_INT base_ofs, rtx frame_reg)
{
  rtx addr, mem;
  rtx_insn *insn;

  addr = plus_constant (Pmode, base_reg, base_ofs);
  mem = gen_frame_mem (DImode, addr);

  insn = emit_move_insn (mem, value);
  RTX_FRAME_RELATED_P (insn) = 1;

  if (frame_bias || value != frame_reg)
    {
      if (frame_bias)
	{
	  addr = plus_constant (Pmode, stack_pointer_rtx,
			        frame_bias + base_ofs);
	  mem = gen_rtx_MEM (DImode, addr);
	}

      add_reg_note (insn, REG_FRAME_RELATED_EXPR,
		    gen_rtx_SET (mem, frame_reg));
    }
}

static void
emit_frame_store (unsigned int regno, rtx base_reg,
		  HOST_WIDE_INT frame_bias, HOST_WIDE_INT base_ofs)
{
  rtx reg = gen_rtx_REG (DImode, regno);
  emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg);
}

/* Write function prologue.  */

/* On vms we have two kinds of functions:

   - stack frame (PROC_STACK)
	these are 'normal' functions with local vars and which are
	calling other functions
   - register frame (PROC_REGISTER)
	keeps all data in registers, needs no stack

   We must pass this to the assembler so it can generate the
   proper pdsc (procedure descriptor)
   This is done with the '.pdesc' command.

   On not-vms, we don't really differentiate between the two, as we can
   simply allocate stack without saving registers.  */

void
alpha_expand_prologue (void)
{
  /* Registers to save.  */
  unsigned HOST_WIDE_INT sa_mask = cfun->machine->sa_mask;
  /* Stack space needed for pushing registers clobbered by us.  */
  HOST_WIDE_INT sa_size = cfun->machine->sa_size;
  /* Complete stack size needed.  */
  HOST_WIDE_INT frame_size = cfun->machine->frame_size;
  /* Probed stack size; it additionally includes the size of
     the "reserve region" if any.  */
  HOST_WIDE_INT probed_size, sa_bias;
  /* Offset from base reg to register save area.  */
  HOST_WIDE_INT reg_offset;
  rtx sa_reg;

  if (flag_stack_usage_info)
    current_function_static_stack_size = frame_size;

  if (TARGET_ABI_OPEN_VMS)
    reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
  else
    reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);

  /* Emit an insn to reload GP, if needed.  */
  if (TARGET_ABI_OSF)
    {
      alpha_function_needs_gp = alpha_does_function_need_gp ();
      if (alpha_function_needs_gp)
	emit_insn (gen_prologue_ldgp ());
    }

  /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
     the call to mcount ourselves, rather than having the linker do it
     magically in response to -pg.  Since _mcount has special linkage,
     don't represent the call as a call.  */
  if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
    emit_insn (gen_prologue_mcount ());

  /* Adjust the stack by the frame size.  If the frame size is > 4096
     bytes, we need to be sure we probe somewhere in the first and last
     4096 bytes (we can probably get away without the latter test) and
     every 8192 bytes in between.  If the frame size is > 32768, we
     do this in a loop.  Otherwise, we generate the explicit probe
     instructions.

     Note that we are only allowed to adjust sp once in the prologue.  */

  probed_size = frame_size;
  if (flag_stack_check || flag_stack_clash_protection)
    probed_size += get_stack_check_protect ();

  if (probed_size <= 32768)
    {
      if (probed_size > 4096)
	{
	  int probed;

	  for (probed = 4096; probed < probed_size; probed += 8192)
	    emit_insn (gen_stack_probe_internal (GEN_INT (-probed)));

	  /* We only have to do this probe if we aren't saving registers or
	     if we are probing beyond the frame because of -fstack-check.  */
	  if ((sa_size == 0 && probed_size > probed - 4096)
	      || flag_stack_check || flag_stack_clash_protection)
	    emit_insn (gen_stack_probe_internal (GEN_INT (-probed_size)));
	}

      if (frame_size != 0)
	FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
				    GEN_INT (-frame_size))));
    }
  else
    {
      /* Here we generate code to set R22 to SP + 4096 and set R23 to the
	 number of 8192 byte blocks to probe.  We then probe each block
	 in the loop and then set SP to the proper location.  If the
	 amount remaining is > 4096, we have to do one more probe if we
	 are not saving any registers or if we are probing beyond the
	 frame because of -fstack-check.  */

      HOST_WIDE_INT blocks = (probed_size + 4096) / 8192;
      HOST_WIDE_INT leftover = probed_size + 4096 - blocks * 8192;
      rtx ptr = gen_rtx_REG (DImode, 22);
      rtx count = gen_rtx_REG (DImode, 23);
      rtx seq;

      emit_move_insn (count, GEN_INT (blocks));
      emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));

      /* Because of the difficulty in emitting a new basic block this
	 late in the compilation, generate the loop as a single insn.  */
      emit_insn (gen_prologue_stack_probe_loop (count, ptr));

      if ((leftover > 4096 && sa_size == 0)
	  || flag_stack_check || flag_stack_clash_protection)
	{
	  rtx last = gen_rtx_MEM (DImode,
				  plus_constant (Pmode, ptr, -leftover));
	  MEM_VOLATILE_P (last) = 1;
	  emit_move_insn (last, const0_rtx);
	}

      if (flag_stack_check || flag_stack_clash_protection)
	{
	  /* If -fstack-check is specified we have to load the entire
	     constant into a register and subtract from the sp in one go,
	     because the probed stack size is not equal to the frame size.  */
	  HOST_WIDE_INT lo, hi;
	  lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
	  hi = frame_size - lo;

	  emit_move_insn (ptr, GEN_INT (hi));
	  emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo)));
	  seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
				       ptr));
	}
      else
	{
	  seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
				       GEN_INT (-leftover)));
	}

      /* This alternative is special, because the DWARF code cannot
         possibly intuit through the loop above.  So we invent this
         note it looks at instead.  */
      RTX_FRAME_RELATED_P (seq) = 1;
      add_reg_note (seq, REG_FRAME_RELATED_EXPR,
		    gen_rtx_SET (stack_pointer_rtx,
				 plus_constant (Pmode, stack_pointer_rtx,
						-frame_size)));
    }

  /* Cope with very large offsets to the register save area.  */
  sa_bias = 0;
  sa_reg = stack_pointer_rtx;
  if (reg_offset + sa_size > 0x8000)
    {
      int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
      rtx sa_bias_rtx;

      if (low + sa_size <= 0x8000)
	sa_bias = reg_offset - low, reg_offset = low;
      else
	sa_bias = reg_offset, reg_offset = 0;

      sa_reg = gen_rtx_REG (DImode, 24);
      sa_bias_rtx = GEN_INT (sa_bias);

      if (add_operand (sa_bias_rtx, DImode))
	emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_bias_rtx));
      else
	{
	  emit_move_insn (sa_reg, sa_bias_rtx);
	  emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_reg));
	}
    }

  /* Save regs in stack order.  Beginning with VMS PV.  */
  if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
    emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0);

  /* Save register RA next, followed by any other registers
     that need to be saved.  */
  for (unsigned i = REG_RA; sa_mask != 0; i = ctz_hwi(sa_mask))
    {
      emit_frame_store (i, sa_reg, sa_bias, reg_offset);
      reg_offset += 8;
      sa_mask &= ~(HOST_WIDE_INT_1U << i);
    }

  if (TARGET_ABI_OPEN_VMS)
    {
      /* Register frame procedures save the fp.  */
      if (alpha_procedure_type == PT_REGISTER)
	{
	  rtx_insn *insn =
	    emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
			    hard_frame_pointer_rtx);
	  add_reg_note (insn, REG_CFA_REGISTER, NULL);
	  RTX_FRAME_RELATED_P (insn) = 1;
	}

      if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
	emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
				    gen_rtx_REG (DImode, REG_PV)));

      if (alpha_procedure_type != PT_NULL
	  && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
	FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));

      /* If we have to allocate space for outgoing args, do it now.  */
      if (crtl->outgoing_args_size != 0)
	{
	  rtx_insn *seq
	    = emit_move_insn (stack_pointer_rtx,
			      plus_constant
			      (Pmode, hard_frame_pointer_rtx,
			       - (ALPHA_ROUND
				  (crtl->outgoing_args_size))));

	  /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
	     if ! frame_pointer_needed. Setting the bit will change the CFA
	     computation rule to use sp again, which would be wrong if we had
	     frame_pointer_needed, as this means sp might move unpredictably
	     later on.

	     Also, note that
	       frame_pointer_needed
	       => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
	     and
	       crtl->outgoing_args_size != 0
	       => alpha_procedure_type != PT_NULL,

	     so when we are not setting the bit here, we are guaranteed to
	     have emitted an FRP frame pointer update just before.  */
	  RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
	}
    }
  else
    {
      /* If we need a frame pointer, set it from the stack pointer.  */
      if (frame_pointer_needed)
	{
	  if (TARGET_CAN_FAULT_IN_PROLOGUE)
	    FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
	  else
	    /* This must always be the last instruction in the
	       prologue, thus we emit a special move + clobber.  */
	      FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
				           stack_pointer_rtx, sa_reg)));
	}
    }

  /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
     the prologue, for exception handling reasons, we cannot do this for
     any insn that might fault.  We could prevent this for mems with a
     (clobber:BLK (scratch)), but this doesn't work for fp insns.  So we
     have to prevent all such scheduling with a blockage.

     Linux, on the other hand, never bothered to implement OSF/1's
     exception handling, and so doesn't care about such things.  Anyone
     planning to use dwarf2 frame-unwind info can also omit the blockage.  */

  if (! TARGET_CAN_FAULT_IN_PROLOGUE)
    emit_insn (gen_blockage ());
}

/* Count the number of .file directives, so that .loc is up to date.  */
int num_source_filenames = 0;

/* Output the textual info surrounding the prologue.  */

void
alpha_start_function (FILE *file, const char *fnname,
		      tree decl ATTRIBUTE_UNUSED)
{
  unsigned long imask, fmask;
  /* Complete stack size needed.  */
  HOST_WIDE_INT frame_size = cfun->machine->frame_size;
  /* The maximum debuggable frame size.  */
  const HOST_WIDE_INT max_frame_size = HOST_WIDE_INT_1 << 31;
  /* Offset from base reg to register save area.  */
  HOST_WIDE_INT reg_offset;
  char *entry_label = (char *) alloca (strlen (fnname) + 6);
  char *tramp_label = (char *) alloca (strlen (fnname) + 6);
  int i;

#if TARGET_ABI_OPEN_VMS
  vms_start_function (fnname);
#endif

  alpha_fnname = fnname;

  if (TARGET_ABI_OPEN_VMS)
    reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
  else
    reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);

  imask = cfun->machine->sa_mask & 0xffffffffu;
  fmask = cfun->machine->sa_mask >> 32;

  /* Issue function start and label.  */
  if (TARGET_ABI_OPEN_VMS || !flag_inhibit_size_directive)
    {
      fputs ("\t.ent ", file);
      assemble_name (file, fnname);
      putc ('\n', file);

      /* If the function needs GP, we'll write the "..ng" label there.
	 Otherwise, do it here.  */
      if (TARGET_ABI_OSF
          && ! alpha_function_needs_gp
	  && ! cfun->is_thunk)
	{
	  putc ('$', file);
	  assemble_name (file, fnname);
	  fputs ("..ng:\n", file);
	}
    }
  /* Nested functions on VMS that are potentially called via trampoline
     get a special transfer entry point that loads the called functions
     procedure descriptor and static chain.  */
   if (TARGET_ABI_OPEN_VMS
       && !TREE_PUBLIC (decl)
       && DECL_CONTEXT (decl)
       && !TYPE_P (DECL_CONTEXT (decl))
       && TREE_CODE (DECL_CONTEXT (decl)) != TRANSLATION_UNIT_DECL)
     {
	strcpy (tramp_label, fnname);
	strcat (tramp_label, "..tr");
	ASM_OUTPUT_LABEL (file, tramp_label);
	fprintf (file, "\tldq $1,24($27)\n");
	fprintf (file, "\tldq $27,16($27)\n");
     }

  strcpy (entry_label, fnname);
  if (TARGET_ABI_OPEN_VMS)
    strcat (entry_label, "..en");

  ASM_OUTPUT_LABEL (file, entry_label);
  inside_function = TRUE;

  if (TARGET_ABI_OPEN_VMS)
    fprintf (file, "\t.base $%d\n", vms_base_regno);

  if (TARGET_ABI_OSF
      && TARGET_IEEE_CONFORMANT
      && !flag_inhibit_size_directive)
    {
      /* Set flags in procedure descriptor to request IEEE-conformant
	 math-library routines.  The value we set it to is PDSC_EXC_IEEE
	 (/usr/include/pdsc.h).  */
      fputs ("\t.eflag 48\n", file);
    }

  /* Set up offsets to alpha virtual arg/local debugging pointer.  */
  alpha_auto_offset = -frame_size + crtl->args.pretend_args_size;
  alpha_arg_offset = -frame_size + 48;

  /* Describe our frame.  If the frame size is larger than an integer,
     print it as zero to avoid an assembler error.  We won't be
     properly describing such a frame, but that's the best we can do.  */
  if (TARGET_ABI_OPEN_VMS)
    fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
	     HOST_WIDE_INT_PRINT_DEC "\n",
	     vms_unwind_regno,
	     frame_size >= max_frame_size ? 0 : frame_size,
	     reg_offset);
  else if (!flag_inhibit_size_directive)
    fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
	     (frame_pointer_needed
	      ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
	     frame_size >= max_frame_size ? 0 : frame_size,
	     crtl->args.pretend_args_size);

  /* Describe which registers were spilled.  */
  if (TARGET_ABI_OPEN_VMS)
    {
      if (imask)
        /* ??? Does VMS care if mask contains ra?  The old code didn't
           set it, so I don't here.  */
	fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
      if (fmask)
	fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
      if (alpha_procedure_type == PT_REGISTER)
	fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
    }
  else if (!flag_inhibit_size_directive)
    {
      if (imask)
	{
	  fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
		   frame_size >= max_frame_size ? 0 : reg_offset - frame_size);

	  for (i = 0; i < 32; ++i)
	    if (imask & (1UL << i))
	      reg_offset += 8;
	}

      if (fmask)
	fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
		 frame_size >= max_frame_size ? 0 : reg_offset - frame_size);
    }

#if TARGET_ABI_OPEN_VMS
  /* If a user condition handler has been installed at some point, emit
     the procedure descriptor bits to point the Condition Handling Facility
     at the indirection wrapper, and state the fp offset at which the user
     handler may be found.  */
  if (cfun->machine->uses_condition_handler)
    {
      fprintf (file, "\t.handler __gcc_shell_handler\n");
      fprintf (file, "\t.handler_data %d\n", VMS_COND_HANDLER_FP_OFFSET);
    }

#ifdef TARGET_VMS_CRASH_DEBUG
  /* Support of minimal traceback info.  */
  switch_to_section (readonly_data_section);
  fprintf (file, "\t.align 3\n");
  assemble_name (file, fnname); fputs ("..na:\n", file);
  fputs ("\t.ascii \"", file);
  assemble_name (file, fnname);
  fputs ("\\0\"\n", file);
  switch_to_section (text_section);
#endif
#endif /* TARGET_ABI_OPEN_VMS */
}

/* Emit the .prologue note at the scheduled end of the prologue.  */

static void
alpha_output_function_end_prologue (FILE *file)
{
  if (TARGET_ABI_OPEN_VMS)
    fputs ("\t.prologue\n", file);
  else if (!flag_inhibit_size_directive)
    fprintf (file, "\t.prologue %d\n",
	     alpha_function_needs_gp || cfun->is_thunk);
}

/* Write function epilogue.  */

void
alpha_expand_epilogue (void)
{
  /* Registers to save.  */
  unsigned HOST_WIDE_INT sa_mask = cfun->machine->sa_mask;
  /* Stack space needed for pushing registers clobbered by us.  */
  HOST_WIDE_INT sa_size = cfun->machine->sa_size;
  /* Complete stack size needed.  */
  HOST_WIDE_INT frame_size = cfun->machine->frame_size;
  /* Offset from base reg to register save area.  */
  HOST_WIDE_INT reg_offset;
  int fp_is_frame_pointer, fp_offset;
  rtx sa_reg, sa_reg_exp = NULL;
  rtx sp_adj1, sp_adj2, mem, reg, insn;
  rtx eh_ofs;
  rtx cfa_restores = NULL_RTX;

  if (TARGET_ABI_OPEN_VMS)
    {
       if (alpha_procedure_type == PT_STACK)
          reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
       else
          reg_offset = 0;
    }
  else
    reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);

  fp_is_frame_pointer
    = (TARGET_ABI_OPEN_VMS
       ? alpha_procedure_type == PT_STACK
       : frame_pointer_needed);
  fp_offset = 0;
  sa_reg = stack_pointer_rtx;

  if (crtl->calls_eh_return)
    eh_ofs = EH_RETURN_STACKADJ_RTX;
  else
    eh_ofs = NULL_RTX;

  if (sa_size)
    {
      /* If we have a frame pointer, restore SP from it.  */
      if (TARGET_ABI_OPEN_VMS
	  ? vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
	  : frame_pointer_needed)
	emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);

      /* Cope with very large offsets to the register save area.  */
      if (reg_offset + sa_size > 0x8000)
	{
	  int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
	  HOST_WIDE_INT bias;

	  if (low + sa_size <= 0x8000)
	    bias = reg_offset - low, reg_offset = low;
	  else
	    bias = reg_offset, reg_offset = 0;

	  sa_reg = gen_rtx_REG (DImode, 22);
	  sa_reg_exp = plus_constant (Pmode, stack_pointer_rtx, bias);

	  emit_move_insn (sa_reg, sa_reg_exp);
	}

      /* Restore registers in order, excepting a true frame pointer.  */
      for (unsigned i = REG_RA; sa_mask != 0; i = ctz_hwi(sa_mask))
	{
	  if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
	    fp_offset = reg_offset;
	  else
	    {
	      mem = gen_frame_mem (DImode,
				   plus_constant (Pmode, sa_reg,
						  reg_offset));
	      reg = gen_rtx_REG (DImode, i);
	      emit_move_insn (reg, mem);
	      cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
					     cfa_restores);
	    }
	  reg_offset += 8;
	  sa_mask &= ~(HOST_WIDE_INT_1U << i);
	}
    }

  if (frame_size || eh_ofs)
    {
      sp_adj1 = stack_pointer_rtx;

      if (eh_ofs)
	{
	  sp_adj1 = gen_rtx_REG (DImode, 23);
	  emit_move_insn (sp_adj1,
			  gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
	}

      /* If the stack size is large, begin computation into a temporary
	 register so as not to interfere with a potential fp restore,
	 which must be consecutive with an SP restore.  */
      if (frame_size < 32768 && !cfun->calls_alloca)
	sp_adj2 = GEN_INT (frame_size);
      else if (frame_size < 0x40007fffL)
	{
	  int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;

	  sp_adj2 = plus_constant (Pmode, sp_adj1, frame_size - low);
	  if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
	    sp_adj1 = sa_reg;
	  else
	    {
	      sp_adj1 = gen_rtx_REG (DImode, 23);
	      emit_move_insn (sp_adj1, sp_adj2);
	    }
	  sp_adj2 = GEN_INT (low);
	}
      else
	{
	  rtx tmp = gen_rtx_REG (DImode, 23);
	  sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3, false);
	  if (!sp_adj2)
	    {
	      /* We can't drop new things to memory this late, afaik,
		 so build it up by pieces.  */
	      sp_adj2 = alpha_emit_set_long_const (tmp, frame_size);
	      gcc_assert (sp_adj2);
	    }
	}

      /* From now on, things must be in order.  So emit blockages.  */

      /* Restore the frame pointer.  */
      if (fp_is_frame_pointer)
	{
	  emit_insn (gen_blockage ());
	  mem = gen_frame_mem (DImode, plus_constant (Pmode, sa_reg,
						      fp_offset));
	  emit_move_insn (hard_frame_pointer_rtx, mem);
	  cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
					 hard_frame_pointer_rtx, cfa_restores);
	}
      else if (TARGET_ABI_OPEN_VMS)
	{
	  emit_insn (gen_blockage ());
	  emit_move_insn (hard_frame_pointer_rtx,
			  gen_rtx_REG (DImode, vms_save_fp_regno));
	  cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
					 hard_frame_pointer_rtx, cfa_restores);
	}

      /* Restore the stack pointer.  */
      emit_insn (gen_blockage ());
      if (sp_adj2 == const0_rtx)
	insn = emit_move_insn (stack_pointer_rtx, sp_adj1);
      else
	insn = emit_move_insn (stack_pointer_rtx,
			       gen_rtx_PLUS (DImode, sp_adj1, sp_adj2));
      REG_NOTES (insn) = cfa_restores;
      add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx);
      RTX_FRAME_RELATED_P (insn) = 1;
    }
  else
    {
      gcc_assert (cfa_restores == NULL);

      if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
        {
          emit_insn (gen_blockage ());
          insn = emit_move_insn (hard_frame_pointer_rtx,
				 gen_rtx_REG (DImode, vms_save_fp_regno));
	  add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
	  RTX_FRAME_RELATED_P (insn) = 1;
        }
    }
}

/* Output the rest of the textual info surrounding the epilogue.  */

void
alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
{
  rtx_insn *insn;

  /* We output a nop after noreturn calls at the very end of the function to
     ensure that the return address always remains in the caller's code range,
     as not doing so might confuse unwinding engines.  */
  insn = get_last_insn ();
  if (!INSN_P (insn))
    insn = prev_active_insn (insn);
  if (insn && CALL_P (insn))
    output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL);

#if TARGET_ABI_OPEN_VMS
  /* Write the linkage entries.  */
  alpha_write_linkage (file, fnname);
#endif

  /* End the function.  */
  if (TARGET_ABI_OPEN_VMS
      || !flag_inhibit_size_directive)
    {
      fputs ("\t.end ", file);
      assemble_name (file, fnname);
      putc ('\n', file);
    }
  inside_function = FALSE;
}

#if TARGET_ABI_OSF
/* Emit a tail call to FUNCTION after adjusting THIS by DELTA.

   In order to avoid the hordes of differences between generated code
   with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
   lots of code loading up large constants, generate rtl and emit it
   instead of going straight to text.

   Not sure why this idea hasn't been explored before...  */

static void
alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
			   HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
			   tree function)
{
  const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
  HOST_WIDE_INT hi, lo;
  rtx this_rtx, funexp;
  rtx_insn *insn;

  /* We always require a valid GP.  */
  emit_insn (gen_prologue_ldgp ());
  emit_note (NOTE_INSN_PROLOGUE_END);

  /* Find the "this" pointer.  If the function returns a structure,
     the structure return pointer is in $16.  */
  if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
    this_rtx = gen_rtx_REG (Pmode, 17);
  else
    this_rtx = gen_rtx_REG (Pmode, 16);

  /* Add DELTA.  When possible we use ldah+lda.  Otherwise load the
     entire constant for the add.  */
  lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
  hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
  if (hi + lo == delta)
    {
      if (hi)
	emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (hi)));
      if (lo)
	emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (lo)));
    }
  else
    {
      rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0), delta);
      emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
    }

  /* Add a delta stored in the vtable at VCALL_OFFSET.  */
  if (vcall_offset)
    {
      rtx tmp, tmp2;

      tmp = gen_rtx_REG (Pmode, 0);
      emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));

      lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
      hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
      if (hi + lo == vcall_offset)
	{
	  if (hi)
	    emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi)));
	}
      else
	{
	  tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
					    vcall_offset);
          emit_insn (gen_adddi3 (tmp, tmp, tmp2));
	  lo = 0;
	}
      if (lo)
	tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo));
      else
	tmp2 = tmp;
      emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));

      emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
    }

  /* Generate a tail call to the target function.  */
  if (! TREE_USED (function))
    {
      assemble_external (function);
      TREE_USED (function) = 1;
    }
  funexp = XEXP (DECL_RTL (function), 0);
  funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
  insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
  SIBLING_CALL_P (insn) = 1;

  /* Run just enough of rest_of_compilation to get the insns emitted.
     There's not really enough bulk here to make other passes such as
     instruction scheduling worth while.  */
  insn = get_insns ();
  shorten_branches (insn);
  assemble_start_function (thunk_fndecl, fnname);
  final_start_function (insn, file, 1);
  final (insn, file, 1);
  final_end_function ();
  assemble_end_function (thunk_fndecl, fnname);
}
#endif /* TARGET_ABI_OSF */

/* Debugging support.  */

#include "gstab.h"

/* Name of the file containing the current function.  */

static const char *current_function_file = "";

/* Offsets to alpha virtual arg/local debugging pointers.  */

long alpha_arg_offset;
long alpha_auto_offset;

/* Emit a new filename to a stream.  */

void
alpha_output_filename (FILE *stream, const char *name)
{
  static int first_time = TRUE;

  if (first_time)
    {
      first_time = FALSE;
      ++num_source_filenames;
      current_function_file = name;
      fprintf (stream, "\t.file\t%d ", num_source_filenames);
      output_quoted_string (stream, name);
      fprintf (stream, "\n");
    }

  else if (name != current_function_file
	   && strcmp (name, current_function_file) != 0)
    {
      ++num_source_filenames;
      current_function_file = name;
      fprintf (stream, "\t.file\t%d ", num_source_filenames);

      output_quoted_string (stream, name);
      fprintf (stream, "\n");
    }
}

/* Structure to show the current status of registers and memory.  */

struct shadow_summary
{
  struct {
    unsigned int i     : 31;	/* Mask of int regs */
    unsigned int fp    : 31;	/* Mask of fp regs */
    unsigned int mem   :  1;	/* mem == imem | fpmem */
  } used, defd;
};

/* Summary the effects of expression X on the machine.  Update SUM, a pointer
   to the summary structure.  SET is nonzero if the insn is setting the
   object, otherwise zero.  */

static void
summarize_insn (rtx x, struct shadow_summary *sum, int set)
{
  const char *format_ptr;
  int i, j;

  if (x == 0)
    return;

  switch (GET_CODE (x))
    {
      /* ??? Note that this case would be incorrect if the Alpha had a
	 ZERO_EXTRACT in SET_DEST.  */
    case SET:
      summarize_insn (SET_SRC (x), sum, 0);
      summarize_insn (SET_DEST (x), sum, 1);
      break;

    case CLOBBER:
      summarize_insn (XEXP (x, 0), sum, 1);
      break;

    case USE:
      summarize_insn (XEXP (x, 0), sum, 0);
      break;

    case ASM_OPERANDS:
      for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
	summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
      break;

    case PARALLEL:
      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
	summarize_insn (XVECEXP (x, 0, i), sum, 0);
      break;

    case SUBREG:
      summarize_insn (SUBREG_REG (x), sum, 0);
      break;

    case REG:
      {
	int regno = REGNO (x);
	unsigned long mask = ((unsigned long) 1) << (regno % 32);

	if (regno == 31 || regno == 63)
	  break;

	if (set)
	  {
	    if (regno < 32)
	      sum->defd.i |= mask;
	    else
	      sum->defd.fp |= mask;
	  }
	else
	  {
	    if (regno < 32)
	      sum->used.i  |= mask;
	    else
	      sum->used.fp |= mask;
	  }
	}
      break;

    case MEM:
      if (set)
	sum->defd.mem = 1;
      else
	sum->used.mem = 1;

      /* Find the regs used in memory address computation: */
      summarize_insn (XEXP (x, 0), sum, 0);
      break;

    case CONST_INT:   case CONST_WIDE_INT:  case CONST_DOUBLE:
    case SYMBOL_REF:  case LABEL_REF:       case CONST:
    case SCRATCH:     case ASM_INPUT:
      break;

      /* Handle common unary and binary ops for efficiency.  */
    case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
    case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
    case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
    case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
    case NE:       case EQ:      case GE:      case GT:        case LE:
    case LT:       case GEU:     case GTU:     case LEU:       case LTU:
      summarize_insn (XEXP (x, 0), sum, 0);
      summarize_insn (XEXP (x, 1), sum, 0);
      break;

    case NEG:  case NOT:  case SIGN_EXTEND:  case ZERO_EXTEND:
    case TRUNCATE:  case FLOAT_EXTEND:  case FLOAT_TRUNCATE:  case FLOAT:
    case FIX:  case UNSIGNED_FLOAT:  case UNSIGNED_FIX:  case ABS:
    case SQRT:  case FFS:
      summarize_insn (XEXP (x, 0), sum, 0);
      break;

    default:
      format_ptr = GET_RTX_FORMAT (GET_CODE (x));
      for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
	switch (format_ptr[i])
	  {
	  case 'e':
	    summarize_insn (XEXP (x, i), sum, 0);
	    break;

	  case 'E':
	    for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	      summarize_insn (XVECEXP (x, i, j), sum, 0);
	    break;

	  case 'i':
	    break;

	  default:
	    gcc_unreachable ();
	  }
    }
}

/* Ensure a sufficient number of `trapb' insns are in the code when
   the user requests code with a trap precision of functions or
   instructions.

   In naive mode, when the user requests a trap-precision of
   "instruction", a trapb is needed after every instruction that may
   generate a trap.  This ensures that the code is resumption safe but
   it is also slow.

   When optimizations are turned on, we delay issuing a trapb as long
   as possible.  In this context, a trap shadow is the sequence of
   instructions that starts with a (potentially) trap generating
   instruction and extends to the next trapb or call_pal instruction
   (but GCC never generates call_pal by itself).  We can delay (and
   therefore sometimes omit) a trapb subject to the following
   conditions:

   (a) On entry to the trap shadow, if any Alpha register or memory
   location contains a value that is used as an operand value by some
   instruction in the trap shadow (live on entry), then no instruction
   in the trap shadow may modify the register or memory location.

   (b) Within the trap shadow, the computation of the base register
   for a memory load or store instruction may not involve using the
   result of an instruction that might generate an UNPREDICTABLE
   result.

   (c) Within the trap shadow, no register may be used more than once
   as a destination register.  (This is to make life easier for the
   trap-handler.)

   (d) The trap shadow may not include any branch instructions.  */

static void
alpha_handle_trap_shadows (void)
{
  struct shadow_summary shadow;
  int trap_pending, exception_nesting;
  rtx_insn *i, *n;

  trap_pending = 0;
  exception_nesting = 0;
  shadow.used.i = 0;
  shadow.used.fp = 0;
  shadow.used.mem = 0;
  shadow.defd = shadow.used;

  for (i = get_insns (); i ; i = NEXT_INSN (i))
    {
      if (NOTE_P (i))
	{
	  switch (NOTE_KIND (i))
	    {
	    case NOTE_INSN_EH_REGION_BEG:
	      exception_nesting++;
	      if (trap_pending)
		goto close_shadow;
	      break;

	    case NOTE_INSN_EH_REGION_END:
	      exception_nesting--;
	      if (trap_pending)
		goto close_shadow;
	      break;

	    case NOTE_INSN_EPILOGUE_BEG:
	      if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
		goto close_shadow;
	      break;
	    }
	}
      else if (trap_pending)
	{
	  if (alpha_tp == ALPHA_TP_FUNC)
	    {
	      if (JUMP_P (i)
		  && GET_CODE (PATTERN (i)) == RETURN)
		goto close_shadow;
	    }
	  else if (alpha_tp == ALPHA_TP_INSN)
	    {
	      if (optimize > 0)
		{
		  struct shadow_summary sum;

		  sum.used.i = 0;
		  sum.used.fp = 0;
		  sum.used.mem = 0;
		  sum.defd = sum.used;

		  switch (GET_CODE (i))
		    {
		    case INSN:
		      /* Annoyingly, get_attr_trap will die on these.  */
		      if (GET_CODE (PATTERN (i)) == USE
			  || GET_CODE (PATTERN (i)) == CLOBBER)
			break;

		      summarize_insn (PATTERN (i), &sum, 0);

		      if ((sum.defd.i & shadow.defd.i)
			  || (sum.defd.fp & shadow.defd.fp))
			{
			  /* (c) would be violated */
			  goto close_shadow;
			}

		      /* Combine shadow with summary of current insn: */
		      shadow.used.i   |= sum.used.i;
		      shadow.used.fp  |= sum.used.fp;
		      shadow.used.mem |= sum.used.mem;
		      shadow.defd.i   |= sum.defd.i;
		      shadow.defd.fp  |= sum.defd.fp;
		      shadow.defd.mem |= sum.defd.mem;

		      if ((sum.defd.i & shadow.used.i)
			  || (sum.defd.fp & shadow.used.fp)
			  || (sum.defd.mem & shadow.used.mem))
			{
			  /* (a) would be violated (also takes care of (b))  */
			  gcc_assert (get_attr_trap (i) != TRAP_YES
				      || (!(sum.defd.i & sum.used.i)
					  && !(sum.defd.fp & sum.used.fp)));

			  goto close_shadow;
			}
		      break;

		    case BARRIER:
		      /* __builtin_unreachable can expand to no code at all,
			 leaving (barrier) RTXes in the instruction stream.  */
		      goto close_shadow_notrapb;

		    case JUMP_INSN:
		    case CALL_INSN:
		    case CODE_LABEL:
		      goto close_shadow;

		    case DEBUG_INSN:
		      break;

		    default:
		      gcc_unreachable ();
		    }
		}
	      else
		{
		close_shadow:
		  n = emit_insn_before (gen_trapb (), i);
		  PUT_MODE (n, TImode);
		  PUT_MODE (i, TImode);
		close_shadow_notrapb:
		  trap_pending = 0;
		  shadow.used.i = 0;
		  shadow.used.fp = 0;
		  shadow.used.mem = 0;
		  shadow.defd = shadow.used;
		}
	    }
	}

      if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
	  && NONJUMP_INSN_P (i)
	  && GET_CODE (PATTERN (i)) != USE
	  && GET_CODE (PATTERN (i)) != CLOBBER
	  && get_attr_trap (i) == TRAP_YES)
	{
	  if (optimize && !trap_pending)
	    summarize_insn (PATTERN (i), &shadow, 0);
	  trap_pending = 1;
	}
    }
}

/* Alpha can only issue instruction groups simultaneously if they are
   suitably aligned.  This is very processor-specific.  */
/* There are a number of entries in alphaev4_insn_pipe and alphaev5_insn_pipe
   that are marked "fake".  These instructions do not exist on that target,
   but it is possible to see these insns with deranged combinations of 
   command-line options, such as "-mtune=ev4 -mmax".  Instead of aborting,
   choose a result at random.  */

enum alphaev4_pipe {
  EV4_STOP = 0,
  EV4_IB0 = 1,
  EV4_IB1 = 2,
  EV4_IBX = 4
};

enum alphaev5_pipe {
  EV5_STOP = 0,
  EV5_NONE = 1,
  EV5_E01 = 2,
  EV5_E0 = 4,
  EV5_E1 = 8,
  EV5_FAM = 16,
  EV5_FA = 32,
  EV5_FM = 64
};

static enum alphaev4_pipe
alphaev4_insn_pipe (rtx_insn *insn)
{
  if (recog_memoized (insn) < 0)
    return EV4_STOP;
  if (get_attr_length (insn) != 4)
    return EV4_STOP;

  switch (get_attr_type (insn))
    {
    case TYPE_ILD:
    case TYPE_LDSYM:
    case TYPE_FLD:
    case TYPE_LD_L:
      return EV4_IBX;

    case TYPE_IADD:
    case TYPE_ILOG:
    case TYPE_ICMOV:
    case TYPE_ICMP:
    case TYPE_FST:
    case TYPE_SHIFT:
    case TYPE_IMUL:
    case TYPE_FBR:
    case TYPE_MVI:		/* fake */
      return EV4_IB0;

    case TYPE_IST:
    case TYPE_MISC:
    case TYPE_IBR:
    case TYPE_JSR:
    case TYPE_CALLPAL:
    case TYPE_FCPYS:
    case TYPE_FCMOV:
    case TYPE_FADD:
    case TYPE_FDIV:
    case TYPE_FMUL:
    case TYPE_ST_C:
    case TYPE_MB:
    case TYPE_FSQRT:		/* fake */
    case TYPE_FTOI:		/* fake */
    case TYPE_ITOF:		/* fake */
      return EV4_IB1;

    default:
      gcc_unreachable ();
    }
}

static enum alphaev5_pipe
alphaev5_insn_pipe (rtx_insn *insn)
{
  if (recog_memoized (insn) < 0)
    return EV5_STOP;
  if (get_attr_length (insn) != 4)
    return EV5_STOP;

  switch (get_attr_type (insn))
    {
    case TYPE_ILD:
    case TYPE_FLD:
    case TYPE_LDSYM:
    case TYPE_IADD:
    case TYPE_ILOG:
    case TYPE_ICMOV:
    case TYPE_ICMP:
      return EV5_E01;

    case TYPE_IST:
    case TYPE_FST:
    case TYPE_SHIFT:
    case TYPE_IMUL:
    case TYPE_MISC:
    case TYPE_MVI:
    case TYPE_LD_L:
    case TYPE_ST_C:
    case TYPE_MB:
    case TYPE_FTOI:		/* fake */
    case TYPE_ITOF:		/* fake */
      return EV5_E0;

    case TYPE_IBR:
    case TYPE_JSR:
    case TYPE_CALLPAL:
      return EV5_E1;

    case TYPE_FCPYS:
      return EV5_FAM;

    case TYPE_FBR:
    case TYPE_FCMOV:
    case TYPE_FADD:
    case TYPE_FDIV:
    case TYPE_FSQRT:		/* fake */
      return EV5_FA;

    case TYPE_FMUL:
      return EV5_FM;

    default:
      gcc_unreachable ();
    }
}

/* IN_USE is a mask of the slots currently filled within the insn group.
   The mask bits come from alphaev4_pipe above.  If EV4_IBX is set, then
   the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.

   LEN is, of course, the length of the group in bytes.  */

static rtx_insn *
alphaev4_next_group (rtx_insn *insn, int *pin_use, int *plen)
{
  int len, in_use;

  len = in_use = 0;

  if (! INSN_P (insn)
      || GET_CODE (PATTERN (insn)) == CLOBBER
      || GET_CODE (PATTERN (insn)) == USE)
    goto next_and_done;

  while (1)
    {
      enum alphaev4_pipe pipe;

      pipe = alphaev4_insn_pipe (insn);
      switch (pipe)
	{
	case EV4_STOP:
	  /* Force complex instructions to start new groups.  */
	  if (in_use)
	    goto done;

	  /* If this is a completely unrecognized insn, it's an asm.
	     We don't know how long it is, so record length as -1 to
	     signal a needed realignment.  */
	  if (recog_memoized (insn) < 0)
	    len = -1;
	  else
	    len = get_attr_length (insn);
	  goto next_and_done;

	case EV4_IBX:
	  if (in_use & EV4_IB0)
	    {
	      if (in_use & EV4_IB1)
		goto done;
	      in_use |= EV4_IB1;
	    }
	  else
	    in_use |= EV4_IB0 | EV4_IBX;
	  break;

	case EV4_IB0:
	  if (in_use & EV4_IB0)
	    {
	      if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
		goto done;
	      in_use |= EV4_IB1;
	    }
	  in_use |= EV4_IB0;
	  break;

	case EV4_IB1:
	  if (in_use & EV4_IB1)
	    goto done;
	  in_use |= EV4_IB1;
	  break;

	default:
	  gcc_unreachable ();
	}
      len += 4;

      /* Haifa doesn't do well scheduling branches.  */
      if (JUMP_P (insn))
	goto next_and_done;

    next:
      insn = next_nonnote_insn (insn);

      if (!insn || ! INSN_P (insn))
	goto done;

      /* Let Haifa tell us where it thinks insn group boundaries are.  */
      if (GET_MODE (insn) == TImode)
	goto done;

      if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
	goto next;
    }

 next_and_done:
  insn = next_nonnote_insn (insn);

 done:
  *plen = len;
  *pin_use = in_use;
  return insn;
}

/* IN_USE is a mask of the slots currently filled within the insn group.
   The mask bits come from alphaev5_pipe above.  If EV5_E01 is set, then
   the insn in EV5_E0 can be swapped by the hardware into EV5_E1.

   LEN is, of course, the length of the group in bytes.  */

static rtx_insn *
alphaev5_next_group (rtx_insn *insn, int *pin_use, int *plen)
{
  int len, in_use;

  len = in_use = 0;

  if (! INSN_P (insn)
      || GET_CODE (PATTERN (insn)) == CLOBBER
      || GET_CODE (PATTERN (insn)) == USE)
    goto next_and_done;

  while (1)
    {
      enum alphaev5_pipe pipe;

      pipe = alphaev5_insn_pipe (insn);
      switch (pipe)
	{
	case EV5_STOP:
	  /* Force complex instructions to start new groups.  */
	  if (in_use)
	    goto done;

	  /* If this is a completely unrecognized insn, it's an asm.
	     We don't know how long it is, so record length as -1 to
	     signal a needed realignment.  */
	  if (recog_memoized (insn) < 0)
	    len = -1;
	  else
	    len = get_attr_length (insn);
	  goto next_and_done;

	/* ??? Most of the places below, we would like to assert never
	   happen, as it would indicate an error either in Haifa, or
	   in the scheduling description.  Unfortunately, Haifa never
	   schedules the last instruction of the BB, so we don't have
	   an accurate TI bit to go off.  */
	case EV5_E01:
	  if (in_use & EV5_E0)
	    {
	      if (in_use & EV5_E1)
		goto done;
	      in_use |= EV5_E1;
	    }
	  else
	    in_use |= EV5_E0 | EV5_E01;
	  break;

	case EV5_E0:
	  if (in_use & EV5_E0)
	    {
	      if (!(in_use & EV5_E01) || (in_use & EV5_E1))
		goto done;
	      in_use |= EV5_E1;
	    }
	  in_use |= EV5_E0;
	  break;

	case EV5_E1:
	  if (in_use & EV5_E1)
	    goto done;
	  in_use |= EV5_E1;
	  break;

	case EV5_FAM:
	  if (in_use & EV5_FA)
	    {
	      if (in_use & EV5_FM)
		goto done;
	      in_use |= EV5_FM;
	    }
	  else
	    in_use |= EV5_FA | EV5_FAM;
	  break;

	case EV5_FA:
	  if (in_use & EV5_FA)
	    goto done;
	  in_use |= EV5_FA;
	  break;

	case EV5_FM:
	  if (in_use & EV5_FM)
	    goto done;
	  in_use |= EV5_FM;
	  break;

	case EV5_NONE:
	  break;

	default:
	  gcc_unreachable ();
	}
      len += 4;

      /* Haifa doesn't do well scheduling branches.  */
      /* ??? If this is predicted not-taken, slotting continues, except
	 that no more IBR, FBR, or JSR insns may be slotted.  */
      if (JUMP_P (insn))
	goto next_and_done;

    next:
      insn = next_nonnote_insn (insn);

      if (!insn || ! INSN_P (insn))
	goto done;

      /* Let Haifa tell us where it thinks insn group boundaries are.  */
      if (GET_MODE (insn) == TImode)
	goto done;

      if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
	goto next;
    }

 next_and_done:
  insn = next_nonnote_insn (insn);

 done:
  *plen = len;
  *pin_use = in_use;
  return insn;
}

static rtx
alphaev4_next_nop (int *pin_use)
{
  int in_use = *pin_use;
  rtx nop;

  if (!(in_use & EV4_IB0))
    {
      in_use |= EV4_IB0;
      nop = gen_nop ();
    }
  else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
    {
      in_use |= EV4_IB1;
      nop = gen_nop ();
    }
  else if (TARGET_FP && !(in_use & EV4_IB1))
    {
      in_use |= EV4_IB1;
      nop = gen_fnop ();
    }
  else
    nop = gen_unop ();

  *pin_use = in_use;
  return nop;
}

static rtx
alphaev5_next_nop (int *pin_use)
{
  int in_use = *pin_use;
  rtx nop;

  if (!(in_use & EV5_E1))
    {
      in_use |= EV5_E1;
      nop = gen_nop ();
    }
  else if (TARGET_FP && !(in_use & EV5_FA))
    {
      in_use |= EV5_FA;
      nop = gen_fnop ();
    }
  else if (TARGET_FP && !(in_use & EV5_FM))
    {
      in_use |= EV5_FM;
      nop = gen_fnop ();
    }
  else
    nop = gen_unop ();

  *pin_use = in_use;
  return nop;
}

/* The instruction group alignment main loop.  */

static void
alpha_align_insns_1 (unsigned int max_align,
		     rtx_insn *(*next_group) (rtx_insn *, int *, int *),
		     rtx (*next_nop) (int *))
{
  /* ALIGN is the known alignment for the insn group.  */
  unsigned int align;
  /* OFS is the offset of the current insn in the insn group.  */
  int ofs;
  int prev_in_use, in_use, len, ldgp;
  rtx_insn *i, *next;

  /* Let shorten branches care for assigning alignments to code labels.  */
  shorten_branches (get_insns ());

  unsigned int option_alignment = align_functions.levels[0].get_value ();
  if (option_alignment < 4)
    align = 4;
  else if ((unsigned int) option_alignment < max_align)
    align = option_alignment;
  else
    align = max_align;

  ofs = prev_in_use = 0;
  i = get_insns ();
  if (NOTE_P (i))
    i = next_nonnote_insn (i);

  ldgp = alpha_function_needs_gp ? 8 : 0;

  while (i)
    {
      next = (*next_group) (i, &in_use, &len);

      /* When we see a label, resync alignment etc.  */
      if (LABEL_P (i))
	{
	  unsigned int new_align
	    = label_to_alignment (i).levels[0].get_value ();

	  if (new_align >= align)
	    {
	      align = new_align < max_align ? new_align : max_align;
	      ofs = 0;
	    }

	  else if (ofs & (new_align-1))
	    ofs = (ofs | (new_align-1)) + 1;
	  gcc_assert (!len);
	}

      /* Handle complex instructions special.  */
      else if (in_use == 0)
	{
	  /* Asms will have length < 0.  This is a signal that we have
	     lost alignment knowledge.  Assume, however, that the asm
	     will not mis-align instructions.  */
	  if (len < 0)
	    {
	      ofs = 0;
	      align = 4;
	      len = 0;
	    }
	}

      /* If the known alignment is smaller than the recognized insn group,
	 realign the output.  */
      else if ((int) align < len)
	{
	  unsigned int new_log_align = len > 8 ? 4 : 3;
	  rtx_insn *prev, *where;

	  where = prev = prev_nonnote_insn (i);
	  if (!where || !LABEL_P (where))
	    where = i;

	  /* Can't realign between a call and its gp reload.  */
	  if (! (TARGET_EXPLICIT_RELOCS
		 && prev && CALL_P (prev)))
	    {
	      emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
	      align = 1 << new_log_align;
	      ofs = 0;
	    }
	}

      /* We may not insert padding inside the initial ldgp sequence.  */
      else if (ldgp > 0)
	ldgp -= len;

      /* If the group won't fit in the same INT16 as the previous,
	 we need to add padding to keep the group together.  Rather
	 than simply leaving the insn filling to the assembler, we
	 can make use of the knowledge of what sorts of instructions
	 were issued in the previous group to make sure that all of
	 the added nops are really free.  */
      else if (ofs + len > (int) align)
	{
	  int nop_count = (align - ofs) / 4;
	  rtx_insn *where;

	  /* Insert nops before labels, branches, and calls to truly merge
	     the execution of the nops with the previous instruction group.  */
	  where = prev_nonnote_insn (i);
	  if (where)
	    {
	      if (LABEL_P (where))
		{
		  rtx_insn *where2 = prev_nonnote_insn (where);
		  if (where2 && JUMP_P (where2))
		    where = where2;
		}
	      else if (NONJUMP_INSN_P (where))
		where = i;
	    }
	  else
	    where = i;

	  do
	    emit_insn_before ((*next_nop)(&prev_in_use), where);
	  while (--nop_count);
	  ofs = 0;
	}

      ofs = (ofs + len) & (align - 1);
      prev_in_use = in_use;
      i = next;
    }
}

static void
alpha_align_insns (void)
{
  if (alpha_tune == PROCESSOR_EV4)
    alpha_align_insns_1 (8, alphaev4_next_group, alphaev4_next_nop);
  else if (alpha_tune == PROCESSOR_EV5)
    alpha_align_insns_1 (16, alphaev5_next_group, alphaev5_next_nop);
  else
    gcc_unreachable ();
}

/* Insert an unop between sibcall or noreturn function call and GP load.  */

static void
alpha_pad_function_end (void)
{
  rtx_insn *insn, *next;

  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      if (!CALL_P (insn)
	  || !(SIBLING_CALL_P (insn)
	       || find_reg_note (insn, REG_NORETURN, NULL_RTX)))
        continue;

      next = next_active_insn (insn);
      if (next)
	{
	  rtx pat = PATTERN (next);

	  if (GET_CODE (pat) == SET
	      && GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE
	      && XINT (SET_SRC (pat), 1) == UNSPECV_LDGP1)
	    emit_insn_after (gen_unop (), insn);
	}
    }
}

/* Machine dependent reorg pass.  */

static void
alpha_reorg (void)
{
  /* Workaround for a linker error that triggers when an exception
     handler immediatelly follows a sibcall or a noreturn function.

In the sibcall case:

     The instruction stream from an object file:

 1d8:   00 00 fb 6b     jmp     (t12)
 1dc:   00 00 ba 27     ldah    gp,0(ra)
 1e0:   00 00 bd 23     lda     gp,0(gp)
 1e4:   00 00 7d a7     ldq     t12,0(gp)
 1e8:   00 40 5b 6b     jsr     ra,(t12),1ec <__funcZ+0x1ec>

     was converted in the final link pass to:

   12003aa88:   67 fa ff c3     br      120039428 <...>
   12003aa8c:   00 00 fe 2f     unop
   12003aa90:   00 00 fe 2f     unop
   12003aa94:   48 83 7d a7     ldq     t12,-31928(gp)
   12003aa98:   00 40 5b 6b     jsr     ra,(t12),12003aa9c <__func+0x1ec>

And in the noreturn case:

     The instruction stream from an object file:

  54:   00 40 5b 6b     jsr     ra,(t12),58 <__func+0x58>
  58:   00 00 ba 27     ldah    gp,0(ra)
  5c:   00 00 bd 23     lda     gp,0(gp)
  60:   00 00 7d a7     ldq     t12,0(gp)
  64:   00 40 5b 6b     jsr     ra,(t12),68 <__func+0x68>

     was converted in the final link pass to:

   fdb24:       a0 03 40 d3     bsr     ra,fe9a8 <_called_func+0x8>
   fdb28:       00 00 fe 2f     unop
   fdb2c:       00 00 fe 2f     unop
   fdb30:       30 82 7d a7     ldq     t12,-32208(gp)
   fdb34:       00 40 5b 6b     jsr     ra,(t12),fdb38 <__func+0x68>

     GP load instructions were wrongly cleared by the linker relaxation
     pass.  This workaround prevents removal of GP loads by inserting
     an unop instruction between a sibcall or noreturn function call and
     exception handler prologue.  */

  if (current_function_has_exception_handlers ())
    alpha_pad_function_end ();

  /* CALL_PAL that implements trap insn, updates program counter to point
     after the insn.  In case trap is the last insn in the function,
     emit NOP to guarantee that PC remains inside function boundaries.
     This workaround is needed to get reliable backtraces.  */
  
  rtx_insn *insn = prev_active_insn (get_last_insn ());

  if (insn && NONJUMP_INSN_P (insn))
    {
      rtx pat = PATTERN (insn);
      if (GET_CODE (pat) == PARALLEL)
	{
	  rtx vec = XVECEXP (pat, 0, 0);
	  if (GET_CODE (vec) == TRAP_IF
	      && XEXP (vec, 0) == const1_rtx)
	    emit_insn_after (gen_unop (), insn);
	}
    }
}

static void
alpha_file_start (void)
{
  default_file_start ();

  fputs ("\t.set noreorder\n", asm_out_file);
  fputs ("\t.set volatile\n", asm_out_file);
  if (TARGET_ABI_OSF)
    fputs ("\t.set noat\n", asm_out_file);
  if (TARGET_EXPLICIT_RELOCS)
    fputs ("\t.set nomacro\n", asm_out_file);
  if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX)
    {
      const char *arch;

      if (alpha_cpu == PROCESSOR_EV6 || TARGET_FIX || TARGET_CIX)
	arch = "ev6";
      else if (TARGET_MAX)
	arch = "pca56";
      else if (TARGET_BWX)
	arch = "ev56";
      else if (alpha_cpu == PROCESSOR_EV5)
	arch = "ev5";
      else
	arch = "ev4";

      fprintf (asm_out_file, "\t.arch %s\n", arch);
    }
}

/* Since we don't have a .dynbss section, we should not allow global
   relocations in the .rodata section.  */

static int
alpha_elf_reloc_rw_mask (void)
{
  return flag_pic ? 3 : 2;
}

/* Return a section for X.  The only special thing we do here is to
   honor small data.  */

static section *
alpha_elf_select_rtx_section (machine_mode mode, rtx x,
			      unsigned HOST_WIDE_INT align)
{
  if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
    /* ??? Consider using mergeable sdata sections.  */
    return sdata_section;
  else
    return default_elf_select_rtx_section (mode, x, align);
}

static unsigned int
alpha_elf_section_type_flags (tree decl, const char *name, int reloc)
{
  unsigned int flags = 0;

  if (strcmp (name, ".sdata") == 0
      || startswith (name, ".sdata.")
      || startswith (name, ".gnu.linkonce.s.")
      || strcmp (name, ".sbss") == 0
      || startswith (name, ".sbss.")
      || startswith (name, ".gnu.linkonce.sb."))
    flags = SECTION_SMALL;

  flags |= default_section_type_flags (decl, name, reloc);
  return flags;
}

/* Structure to collect function names for final output in link section.  */
/* Note that items marked with GTY can't be ifdef'ed out.  */

enum reloc_kind
{
  KIND_LINKAGE,
  KIND_CODEADDR
};

struct GTY(()) alpha_links
{
  rtx func;
  rtx linkage;
  enum reloc_kind rkind;
};

#if TARGET_ABI_OPEN_VMS

/* Return the VMS argument type corresponding to MODE.  */

enum avms_arg_type
alpha_arg_type (machine_mode mode)
{
  switch (mode)
    {
    case E_SFmode:
      return TARGET_FLOAT_VAX ? FF : FS;
    case E_DFmode:
      return TARGET_FLOAT_VAX ? FD : FT;
    default:
      return I64;
    }
}

/* Return an rtx for an integer representing the VMS Argument Information
   register value.  */

rtx
alpha_arg_info_reg_val (CUMULATIVE_ARGS cum)
{
  unsigned HOST_WIDE_INT regval = cum.num_args;
  int i;

  for (i = 0; i < 6; i++)
    regval |= ((int) cum.atypes[i]) << (i * 3 + 8);

  return GEN_INT (regval);
}


/* Return a SYMBOL_REF representing the reference to the .linkage entry
   of function FUNC built for calls made from CFUNDECL.  LFLAG is 1 if
   this is the reference to the linkage pointer value, 0 if this is the
   reference to the function entry value.  RFLAG is 1 if this a reduced
   reference (code address only), 0 if this is a full reference.  */

rtx
alpha_use_linkage (rtx func, bool lflag, bool rflag)
{
  struct alpha_links *al = NULL;
  const char *name = XSTR (func, 0);

  if (cfun->machine->links)
    {
      /* Is this name already defined?  */
      alpha_links **slot = cfun->machine->links->get (name);
      if (slot)
	al = *slot;
    }
  else
    cfun->machine->links
      = hash_map<nofree_string_hash, alpha_links *>::create_ggc (64);

  if (al == NULL)
    {
      size_t buf_len;
      char *linksym;
      tree id;

      if (name[0] == '*')
	name++;

      /* Follow transparent alias, as this is used for CRTL translations.  */
      id = maybe_get_identifier (name);
      if (id)
        {
          while (IDENTIFIER_TRANSPARENT_ALIAS (id))
            id = TREE_CHAIN (id);
          name = IDENTIFIER_POINTER (id);
        }

      buf_len = strlen (name) + 8 + 9;
      linksym = (char *) alloca (buf_len);
      snprintf (linksym, buf_len, "$%d..%s..lk", cfun->funcdef_no, name);

      al = ggc_alloc<alpha_links> ();
      al->func = func;
      al->linkage = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (linksym));

      cfun->machine->links->put (ggc_strdup (name), al);
    }

  al->rkind = rflag ? KIND_CODEADDR : KIND_LINKAGE;

  if (lflag)
    return gen_rtx_MEM (Pmode, plus_constant (Pmode, al->linkage, 8));
  else
    return al->linkage;
}

static int
alpha_write_one_linkage (const char *name, alpha_links *link, FILE *stream)
{
  ASM_OUTPUT_INTERNAL_LABEL (stream, XSTR (link->linkage, 0));
  if (link->rkind == KIND_CODEADDR)
    {
      /* External and used, request code address.  */
      fprintf (stream, "\t.code_address ");
    }
  else
    {
      if (!SYMBOL_REF_EXTERNAL_P (link->func)
          && SYMBOL_REF_LOCAL_P (link->func))
	{
	  /* Locally defined, build linkage pair.  */
	  fprintf (stream, "\t.quad %s..en\n", name);
	  fprintf (stream, "\t.quad ");
	}
      else
	{
	  /* External, request linkage pair.  */
	  fprintf (stream, "\t.linkage ");
	}
    }
  assemble_name (stream, name);
  fputs ("\n", stream);

  return 0;
}

static void
alpha_write_linkage (FILE *stream, const char *funname)
{
  fprintf (stream, "\t.link\n");
  fprintf (stream, "\t.align 3\n");
  in_section = NULL;

#ifdef TARGET_VMS_CRASH_DEBUG
  fputs ("\t.name ", stream);
  assemble_name (stream, funname);
  fputs ("..na\n", stream);
#endif

  ASM_OUTPUT_LABEL (stream, funname);
  fprintf (stream, "\t.pdesc ");
  assemble_name (stream, funname);
  fprintf (stream, "..en,%s\n",
	   alpha_procedure_type == PT_STACK ? "stack"
	   : alpha_procedure_type == PT_REGISTER ? "reg" : "null");

  if (cfun->machine->links)
    {
      hash_map<nofree_string_hash, alpha_links *>::iterator iter
	= cfun->machine->links->begin ();
      for (; iter != cfun->machine->links->end (); ++iter)
	alpha_write_one_linkage ((*iter).first, (*iter).second, stream);
    }
}

/* Switch to an arbitrary section NAME with attributes as specified
   by FLAGS.  ALIGN specifies any known alignment requirements for
   the section; 0 if the default should be used.  */

static void
vms_asm_named_section (const char *name, unsigned int flags, 
		       tree decl ATTRIBUTE_UNUSED)
{
  fputc ('\n', asm_out_file);
  fprintf (asm_out_file, ".section\t%s", name);

  if (flags & SECTION_DEBUG)
    fprintf (asm_out_file, ",NOWRT");

  fputc ('\n', asm_out_file);
}

/* Record an element in the table of global constructors.  SYMBOL is
   a SYMBOL_REF of the function to be called; PRIORITY is a number
   between 0 and MAX_INIT_PRIORITY.

   Differs from default_ctors_section_asm_out_constructor in that the
   width of the .ctors entry is always 64 bits, rather than the 32 bits
   used by a normal pointer.  */

static void
vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
  switch_to_section (ctors_section);
  assemble_align (BITS_PER_WORD);
  assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
}

static void
vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
  switch_to_section (dtors_section);
  assemble_align (BITS_PER_WORD);
  assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
}
#else
rtx
alpha_use_linkage (rtx func ATTRIBUTE_UNUSED,
		   bool lflag ATTRIBUTE_UNUSED,
		   bool rflag ATTRIBUTE_UNUSED)
{
  return NULL_RTX;
}

#endif /* TARGET_ABI_OPEN_VMS */

static void
alpha_init_libfuncs (void)
{
  if (TARGET_ABI_OPEN_VMS)
    {
      /* Use the VMS runtime library functions for division and
	 remainder.  */
      set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
      set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
      set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
      set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
      set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
      set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
      set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
      set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
#ifdef MEM_LIBFUNCS_INIT
      MEM_LIBFUNCS_INIT;
#endif
    }
}

/* On the Alpha, we use this to disable the floating-point registers
   when they don't exist.  */

static void
alpha_conditional_register_usage (void)
{
  int i;
  if (! TARGET_FPREGS)
    for (i = 32; i < 63; i++)
      fixed_regs[i] = call_used_regs[i] = 1;
}

/* Canonicalize a comparison from one we don't have to one we do have.  */

static void
alpha_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
			       bool op0_preserve_value)
{
  if (!op0_preserve_value
      && (*code == GE || *code == GT || *code == GEU || *code == GTU)
      && (REG_P (*op1) || *op1 == const0_rtx))
    {
      std::swap (*op0, *op1);
      *code = (int)swap_condition ((enum rtx_code)*code);
    }

  if ((*code == LT || *code == LTU)
      && CONST_INT_P (*op1) && INTVAL (*op1) == 256)
    {
      *code = *code == LT ? LE : LEU;
      *op1 = GEN_INT (255);
    }
}

/* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV.  */

static void
alpha_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
{
  const unsigned HOST_WIDE_INT SWCR_STATUS_MASK = (0x3fUL << 17);

  tree fenv_var, get_fpscr, set_fpscr, mask, ld_fenv, masked_fenv;
  tree new_fenv_var, reload_fenv, restore_fnenv;
  tree update_call, atomic_feraiseexcept, hold_fnclex;

  /* Assume OSF/1 compatible interfaces.  */
  if (!TARGET_ABI_OSF)
    return;

  /* Generate the equivalent of :
       unsigned long fenv_var;
       fenv_var = __ieee_get_fp_control ();

       unsigned long masked_fenv;
       masked_fenv = fenv_var & mask;

       __ieee_set_fp_control (masked_fenv);  */

  fenv_var = create_tmp_var_raw (long_unsigned_type_node);
  get_fpscr
    = build_fn_decl ("__ieee_get_fp_control",
		     build_function_type_list (long_unsigned_type_node, NULL));
  set_fpscr
    = build_fn_decl ("__ieee_set_fp_control",
		     build_function_type_list (void_type_node, NULL));
  mask = build_int_cst (long_unsigned_type_node, ~SWCR_STATUS_MASK);
  ld_fenv = build4 (TARGET_EXPR, long_unsigned_type_node, fenv_var,
		    build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE);
  masked_fenv = build2 (BIT_AND_EXPR, long_unsigned_type_node, fenv_var, mask);
  hold_fnclex = build_call_expr (set_fpscr, 1, masked_fenv);
  *hold = build2 (COMPOUND_EXPR, void_type_node,
		  build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv),
		  hold_fnclex);

  /* Store the value of masked_fenv to clear the exceptions:
     __ieee_set_fp_control (masked_fenv);  */

  *clear = build_call_expr (set_fpscr, 1, masked_fenv);

  /* Generate the equivalent of :
       unsigned long new_fenv_var;
       new_fenv_var = __ieee_get_fp_control ();

       __ieee_set_fp_control (fenv_var);

       __atomic_feraiseexcept (new_fenv_var);  */

  new_fenv_var = create_tmp_var_raw (long_unsigned_type_node);
  reload_fenv = build4 (TARGET_EXPR, long_unsigned_type_node, new_fenv_var,
			build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE);
  restore_fnenv = build_call_expr (set_fpscr, 1, fenv_var);
  atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
  update_call
    = build_call_expr (atomic_feraiseexcept, 1,
		       fold_convert (integer_type_node, new_fenv_var));
  *update = build2 (COMPOUND_EXPR, void_type_node,
		    build2 (COMPOUND_EXPR, void_type_node,
			    reload_fenv, restore_fnenv), update_call);
}

/* Implement TARGET_HARD_REGNO_MODE_OK.  On Alpha, the integer registers
   can hold any mode.  The floating-point registers can hold 64-bit
   integers as well, but not smaller values.  */

static bool
alpha_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
  if (IN_RANGE (regno, 32, 62))
    return (mode == SFmode
	    || mode == DFmode
	    || mode == DImode
	    || mode == SCmode
	    || mode == DCmode);
  return true;
}

/* Implement TARGET_MODES_TIEABLE_P.  This asymmetric test is true when
   MODE1 could be put in an FP register but MODE2 could not.  */

static bool
alpha_modes_tieable_p (machine_mode mode1, machine_mode mode2)
{
  return (alpha_hard_regno_mode_ok (32, mode1)
	  ? alpha_hard_regno_mode_ok (32, mode2)
	  : true);
}

/* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */

static bool
alpha_can_change_mode_class (machine_mode from, machine_mode to,
			     reg_class_t rclass)
{
  return (GET_MODE_SIZE (from) == GET_MODE_SIZE (to)
	  || !reg_classes_intersect_p (FLOAT_REGS, rclass));
}

/* Initialize the GCC target structure.  */
#if TARGET_ABI_OPEN_VMS
# undef TARGET_ATTRIBUTE_TABLE
# define TARGET_ATTRIBUTE_TABLE vms_attribute_table
# undef TARGET_CAN_ELIMINATE
# define TARGET_CAN_ELIMINATE alpha_vms_can_eliminate
#endif

#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p

#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
#undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"

/* Default unaligned ops are provided for ELF systems.  To get unaligned
   data for non-ELF systems, we have to turn off auto alignment.  */
#if TARGET_ABI_OPEN_VMS
#undef TARGET_ASM_UNALIGNED_HI_OP
#define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
#undef TARGET_ASM_UNALIGNED_SI_OP
#define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
#undef TARGET_ASM_UNALIGNED_DI_OP
#define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
#endif

#undef  TARGET_ASM_RELOC_RW_MASK
#define TARGET_ASM_RELOC_RW_MASK  alpha_elf_reloc_rw_mask
#undef	TARGET_ASM_SELECT_RTX_SECTION
#define	TARGET_ASM_SELECT_RTX_SECTION  alpha_elf_select_rtx_section
#undef  TARGET_SECTION_TYPE_FLAGS
#define TARGET_SECTION_TYPE_FLAGS  alpha_elf_section_type_flags

#undef TARGET_ASM_FUNCTION_END_PROLOGUE
#define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue

#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS alpha_init_libfuncs

#undef TARGET_LEGITIMIZE_ADDRESS
#define TARGET_LEGITIMIZE_ADDRESS alpha_legitimize_address
#undef TARGET_MODE_DEPENDENT_ADDRESS_P
#define TARGET_MODE_DEPENDENT_ADDRESS_P alpha_mode_dependent_address_p

#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START alpha_file_start

#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
  alpha_multipass_dfa_lookahead

#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS HAVE_AS_TLS

#undef  TARGET_BUILTIN_DECL
#define TARGET_BUILTIN_DECL  alpha_builtin_decl
#undef  TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS alpha_init_builtins
#undef  TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN alpha_expand_builtin
#undef  TARGET_FOLD_BUILTIN
#define TARGET_FOLD_BUILTIN alpha_fold_builtin
#undef  TARGET_GIMPLE_FOLD_BUILTIN
#define TARGET_GIMPLE_FOLD_BUILTIN alpha_gimple_fold_builtin

#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
#undef TARGET_CANNOT_COPY_INSN_P
#define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
#undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P alpha_legitimate_constant_p
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem

#if TARGET_ABI_OSF
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
#undef TARGET_STDARG_OPTIMIZE_HOOK
#define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook
#endif

#undef TARGET_PRINT_OPERAND
#define TARGET_PRINT_OPERAND alpha_print_operand
#undef TARGET_PRINT_OPERAND_ADDRESS
#define TARGET_PRINT_OPERAND_ADDRESS alpha_print_operand_address
#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
#define TARGET_PRINT_OPERAND_PUNCT_VALID_P alpha_print_operand_punct_valid_p

/* Use 16-bits anchor.  */
#undef TARGET_MIN_ANCHOR_OFFSET
#define TARGET_MIN_ANCHOR_OFFSET -0x7fff - 1
#undef TARGET_MAX_ANCHOR_OFFSET
#define TARGET_MAX_ANCHOR_OFFSET 0x7fff
#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true

#undef TARGET_REGISTER_MOVE_COST
#define TARGET_REGISTER_MOVE_COST alpha_register_move_cost
#undef TARGET_MEMORY_MOVE_COST
#define TARGET_MEMORY_MOVE_COST alpha_memory_move_cost
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS alpha_rtx_costs
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0

#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg

#undef TARGET_PROMOTE_FUNCTION_MODE
#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
#undef TARGET_PROMOTE_PROTOTYPES
#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false

#undef TARGET_FUNCTION_VALUE
#define TARGET_FUNCTION_VALUE alpha_function_value
#undef TARGET_LIBCALL_VALUE
#define TARGET_LIBCALL_VALUE alpha_libcall_value
#undef TARGET_FUNCTION_VALUE_REGNO_P
#define TARGET_FUNCTION_VALUE_REGNO_P alpha_function_value_regno_p
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference
#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
#undef TARGET_STRICT_ARGUMENT_NAMING
#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
#undef TARGET_SPLIT_COMPLEX_ARG
#define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
#define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
#undef TARGET_ARG_PARTIAL_BYTES
#define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes
#undef TARGET_FUNCTION_ARG
#define TARGET_FUNCTION_ARG alpha_function_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE alpha_function_arg_advance
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT alpha_trampoline_init

#undef TARGET_INSTANTIATE_DECLS
#define TARGET_INSTANTIATE_DECLS alpha_instantiate_decls

#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD alpha_secondary_reload
#undef TARGET_SECONDARY_MEMORY_NEEDED
#define TARGET_SECONDARY_MEMORY_NEEDED alpha_secondary_memory_needed
#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
#define TARGET_SECONDARY_MEMORY_NEEDED_MODE alpha_secondary_memory_needed_mode

#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p

#undef TARGET_BUILD_BUILTIN_VA_LIST
#define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list

#undef TARGET_EXPAND_BUILTIN_VA_START
#define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start

#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE alpha_option_override

#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE \
  alpha_override_options_after_change

#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
#undef TARGET_MANGLE_TYPE
#define TARGET_MANGLE_TYPE alpha_mangle_type
#endif

#undef TARGET_LRA_P
#define TARGET_LRA_P hook_bool_void_false

#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P alpha_legitimate_address_p

#undef TARGET_CONDITIONAL_REGISTER_USAGE
#define TARGET_CONDITIONAL_REGISTER_USAGE alpha_conditional_register_usage

#undef TARGET_CANONICALIZE_COMPARISON
#define TARGET_CANONICALIZE_COMPARISON alpha_canonicalize_comparison

#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV alpha_atomic_assign_expand_fenv

#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK alpha_hard_regno_mode_ok

#undef TARGET_MODES_TIEABLE_P
#define TARGET_MODES_TIEABLE_P alpha_modes_tieable_p

#undef TARGET_CAN_CHANGE_MODE_CLASS
#define TARGET_CAN_CHANGE_MODE_CLASS alpha_can_change_mode_class

struct gcc_target targetm = TARGET_INITIALIZER;


#include "gt-alpha.h"
