diff gcc/config/alpha/alpha.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
line wrap: on
line diff
--- a/gcc/config/alpha/alpha.c	Sun Aug 21 07:07:55 2011 +0900
+++ b/gcc/config/alpha/alpha.c	Fri Oct 27 22:46:09 2017 +0900
@@ -1,7 +1,5 @@
 /* Subroutines used for code generation on the DEC Alpha.
-   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 1992-2017 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 This file is part of GCC.
@@ -24,39 +22,52 @@
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.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 "hard-reg-set.h"
-#include "insn-config.h"
-#include "conditions.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 "flags.h"
-#include "recog.h"
+#include "explow.h"
 #include "expr.h"
-#include "optabs.h"
 #include "reload.h"
-#include "obstack.h"
 #include "except.h"
-#include "function.h"
-#include "diagnostic-core.h"
-#include "ggc.h"
-#include "integrate.h"
-#include "tm_p.h"
-#include "target.h"
-#include "target-def.h"
+#include "common/common-target.h"
 #include "debug.h"
 #include "langhooks.h"
-#include "splay-tree.h"
-#include "cfglayout.h"
-#include "gimple.h"
-#include "tree-flow.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 "df.h"
 #include "libfuncs.h"
+#include "params.h"
+#include "builtins.h"
+#include "rtl-iter.h"
+
+/* This file should be included last.  */
+#include "target-def.h"
 
 /* Specify which cpu to schedule for.  */
 enum processor_type alpha_tune;
@@ -88,16 +99,12 @@
 
 /* The number of cycles of latency we should assume on memory reads.  */
 
-int alpha_memory_latency = 3;
+static int alpha_memory_latency = 3;
 
 /* Whether the function needs the GP.  */
 
 static int alpha_function_needs_gp;
 
-/* The alias set for prologue/epilogue register save/restore.  */
-
-static GTY(()) alias_set_type alpha_sr_alias_set;
-
 /* The assembler name of the current function.  */
 
 static const char *alpha_fnname;
@@ -184,7 +191,7 @@
 };
 
 /* Get the number of args of a function in one of two ways.  */
-#if TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK
+#if TARGET_ABI_OPEN_VMS
 #define NUM_ARGS crtl->args.info.num_args
 #else
 #define NUM_ARGS crtl->args.info
@@ -196,48 +203,122 @@
 /* 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 *, tree);
-static bool vms_valid_pointer_mode (enum machine_mode);
+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 void unicosmk_output_deferred_case_vectors (FILE *);
-static void unicosmk_gen_dsib (unsigned long *);
-static void unicosmk_output_ssib (FILE *, const char *);
-static int unicosmk_need_dex (rtx);
 
-/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
-static const struct default_options alpha_option_optimization_table[] =
-  {
-    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
-    { OPT_LEVELS_NONE, 0, NULL, 0 }
-  };
-
-/* Implement TARGET_HANDLE_OPTION.  */
-
-static bool
-alpha_handle_option (size_t code, const char *arg, int value)
-{
-  switch (code)
-    {
-    case OPT_mfp_regs:
-      if (value == 0)
-	target_flags |= MASK_SOFT_FP;
-      break;
-
-    case OPT_mieee:
-    case OPT_mieee_with_inexact:
-      target_flags |= MASK_IEEE_CONFORMANT;
-      break;
-
-    case OPT_mtls_size_:
-      if (value != 16 && value != 32 && value != 64)
-	error ("bad value %qs for -mtls-size switch", arg);
-      break;
-    }
-
-  return true;
+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
@@ -264,74 +345,64 @@
     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",	PROCESSOR_EV4, 0 },
-    { "ev45",	PROCESSOR_EV4, 0 },
-    { "21064",	PROCESSOR_EV4, 0 },
-    { "ev5",	PROCESSOR_EV5, 0 },
-    { "21164",	PROCESSOR_EV5, 0 },
-    { "ev56",	PROCESSOR_EV5, MASK_BWX },
-    { "21164a",	PROCESSOR_EV5, MASK_BWX },
-    { "pca56",	PROCESSOR_EV5, MASK_BWX|MASK_MAX },
-    { "21164PC",PROCESSOR_EV5, MASK_BWX|MASK_MAX },
-    { "21164pc",PROCESSOR_EV5, MASK_BWX|MASK_MAX },
-    { "ev6",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX },
-    { "21264",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX },
-    { "ev67",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX },
-    { "21264a",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX }
+    /* 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
 
-  /* Unicos/Mk doesn't have shared libraries.  */
-  if (TARGET_ABI_UNICOSMK && flag_pic)
-    {
-      warning (0, "-f%s ignored for Unicos/Mk (not supported)",
-	       (flag_pic > 1) ? "PIC" : "pic");
-      flag_pic = 0;
-    }
-
-  /* On Unicos/Mk, the native compiler consistently generates /d suffices for
-     floating-point instructions.  Make that the default for this target.  */
-  if (TARGET_ABI_UNICOSMK)
-    alpha_fprm = ALPHA_FPRM_DYN;
-  else
-    alpha_fprm = ALPHA_FPRM_NORM;
-
+  /* 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;
 
-  /* We cannot use su and sui qualifiers for conversion instructions on
-     Unicos/Mk.  I'm not sure if this is due to assembler or hardware
-     limitations.  Right now, we issue a warning if -mieee is specified
-     and then ignore it; eventually, we should either get it right or
-     disable the option altogether.  */
-
   if (TARGET_IEEE)
     {
-      if (TARGET_ABI_UNICOSMK)
-	warning (0, "-mieee not supported on Unicos/Mk");
-      else
-	{
-	  alpha_tp = ALPHA_TP_INSN;
-	  alpha_fptm = ALPHA_FPTM_SU;
-	}
-    }
-
+      alpha_tp = ALPHA_TP_INSN;
+      alpha_fptm = ALPHA_FPTM_SU;
+    }
   if (TARGET_IEEE_WITH_INEXACT)
     {
-      if (TARGET_ABI_UNICOSMK)
-	warning (0, "-mieee-with-inexact not supported on Unicos/Mk");
-      else
-	{
-	  alpha_tp = ALPHA_TP_INSN;
-	  alpha_fptm = ALPHA_FPTM_SUI;
-	}
+      alpha_tp = ALPHA_TP_INSN;
+      alpha_fptm = ALPHA_FPTM_SUI;
     }
 
   if (alpha_tp_string)
@@ -380,9 +451,12 @@
       for (i = 0; i < ct_size; i++)
 	if (! strcmp (alpha_cpu_string, cpu_table [i].name))
 	  {
-	    alpha_tune = alpha_cpu = cpu_table [i].processor;
+	    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;
+	    target_flags |= cpu_table[i].flags;
 	    break;
 	  }
       if (i == ct_size)
@@ -394,21 +468,31 @@
       for (i = 0; i < ct_size; i++)
 	if (! strcmp (alpha_tune_string, cpu_table [i].name))
 	  {
-	    alpha_tune = cpu_table [i].processor;
+	    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)
+    maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE, line_size,
+			   global_options.x_param_values,
+			   global_options_set.x_param_values);
+  if (l1_size)
+    maybe_set_param_value (PARAM_L1_CACHE_SIZE, l1_size,
+			   global_options.x_param_values,
+			   global_options_set.x_param_values);
+  if (l2_size)
+    maybe_set_param_value (PARAM_L2_CACHE_SIZE, l2_size,
+			   global_options.x_param_values,
+			   global_options_set.x_param_values);
+
   /* Do some sanity checks on the above options.  */
 
-  if (TARGET_ABI_UNICOSMK && alpha_fptm != ALPHA_FPTM_N)
-    {
-      warning (0, "trap mode not supported on Unicos/Mk");
-      alpha_fptm = ALPHA_FPTM_N;
-    }
-
   if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
       && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6)
     {
@@ -497,21 +581,7 @@
   else if (flag_pic == 2)
     target_flags &= ~MASK_SMALL_DATA;
 
-  /* Align labels and loops for optimal branching.  */
-  /* ??? Kludge these by not doing anything if we don't optimize and also if
-     we are writing ECOFF symbols to work around a bug in DEC's assembler.  */
-  if (optimize > 0 && write_symbols != SDB_DEBUG)
-    {
-      if (align_loops <= 0)
-	align_loops = 16;
-      if (align_jumps <= 0)
-	align_jumps = 16;
-    }
-  if (align_functions <= 0)
-    align_functions = 16;
-
-  /* Acquire a unique set number for our register saves and restores.  */
-  alpha_sr_alias_set = new_alias_set ();
+  alpha_override_options_after_change ();
 
   /* Register variables and functions with the garbage collector.  */
 
@@ -531,10 +601,24 @@
     target_flags |= MASK_LONG_DOUBLE_128;
 #endif
 
-  /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
-     can be optimized to ap = __builtin_next_arg (0).  */
-  if (TARGET_ABI_UNICOSMK)
-    targetm.expand_builtin_va_start = NULL;
+}
+
+/* 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 (align_loops <= 0)
+	align_loops = 16;
+      if (align_jumps <= 0)
+	align_jumps = 16;
+    }
+  if (align_functions <= 0)
+    align_functions = 16;
 }
 
 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
@@ -589,12 +673,12 @@
   if (reload_in_progress)
     {
       rtx tmp = op;
-      if (GET_CODE (tmp) == SUBREG)
+      if (SUBREG_P (tmp))
 	tmp = SUBREG_REG (tmp);
       if (REG_P (tmp)
 	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
 	{
-	  op = reg_equiv_memory_loc[REGNO (tmp)];
+	  op = reg_equiv_memory_loc (REGNO (tmp));
 	  if (op == 0)
 	    return 0;
 	}
@@ -604,26 +688,25 @@
 
 /* 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.  On unicosmk, we have the situation that HImode
-   doesn't map to any C type, but of course we still support that.  */
+   indicates only DFmode.  */
 
 static bool
-alpha_scalar_mode_supported_p (enum machine_mode mode)
+alpha_scalar_mode_supported_p (scalar_mode mode)
 {
   switch (mode)
     {
-    case QImode:
-    case HImode:
-    case SImode:
-    case DImode:
-    case TImode: /* via optabs.c */
+    case E_QImode:
+    case E_HImode:
+    case E_SImode:
+    case E_DImode:
+    case E_TImode: /* via optabs.c */
       return true;
 
-    case SFmode:
-    case DFmode:
+    case E_SFmode:
+    case E_DFmode:
       return true;
 
-    case TFmode:
+    case E_TFmode:
       return TARGET_HAS_XFLOATING_LIBS;
 
     default:
@@ -637,7 +720,7 @@
    or when expand_vector_operations can do something useful.  */
 
 static bool
-alpha_vector_mode_supported_p (enum machine_mode mode)
+alpha_vector_mode_supported_p (machine_mode mode)
 {
   return mode == V8QImode || mode == V4HImode || mode == V2SImode;
 }
@@ -647,7 +730,7 @@
 int
 direct_return (void)
 {
-  return (! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK
+  return (TARGET_ABI_OSF
 	  && reload_completed
 	  && alpha_sa_size () == 0
 	  && get_frame_size () == 0
@@ -655,59 +738,6 @@
 	  && crtl->args.pretend_args_size == 0);
 }
 
-/* Return the ADDR_VEC associated with a tablejump insn.  */
-
-rtx
-alpha_tablejump_addr_vec (rtx insn)
-{
-  rtx tmp;
-
-  tmp = JUMP_LABEL (insn);
-  if (!tmp)
-    return NULL_RTX;
-  tmp = NEXT_INSN (tmp);
-  if (!tmp)
-    return NULL_RTX;
-  if (JUMP_P (tmp)
-      && GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)
-    return PATTERN (tmp);
-  return NULL_RTX;
-}
-
-/* Return the label of the predicted edge, or CONST0_RTX if we don't know.  */
-
-rtx
-alpha_tablejump_best_label (rtx insn)
-{
-  rtx jump_table = alpha_tablejump_addr_vec (insn);
-  rtx best_label = NULL_RTX;
-
-  /* ??? Once the CFG doesn't keep getting completely rebuilt, look
-     there for edge frequency counts from profile data.  */
-
-  if (jump_table)
-    {
-      int n_labels = XVECLEN (jump_table, 1);
-      int best_count = -1;
-      int i, j;
-
-      for (i = 0; i < n_labels; i++)
-	{
-	  int count = 1;
-
-	  for (j = i + 1; j < n_labels; j++)
-	    if (XEXP (XVECEXP (jump_table, 1, i), 0)
-		== XEXP (XVECEXP (jump_table, 1, j), 0))
-	      count++;
-
-	  if (count > best_count)
-	    best_count = count, best_label = XVECEXP (jump_table, 1, i);
-	}
-    }
-
-  return best_label ? best_label : const0_rtx;
-}
-
 /* Return the TLS model to use for SYMBOL.  */
 
 static enum tls_model
@@ -763,9 +793,13 @@
   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 = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
+      const char *section = DECL_SECTION_NAME (exp);
       if (strcmp (section, ".sdata") == 0
 	  || strcmp (section, ".sbss") == 0)
 	return true;
@@ -785,7 +819,7 @@
 
 #if TARGET_ABI_OPEN_VMS
 static bool
-vms_valid_pointer_mode (enum machine_mode mode)
+vms_valid_pointer_mode (scalar_int_mode mode)
 {
   return (mode == SImode || mode == DImode);
 }
@@ -820,7 +854,7 @@
    low-order three bits; this is an "unaligned" access.  */
 
 static bool
-alpha_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
+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
@@ -830,7 +864,7 @@
     x = XEXP (x, 0);
 
   /* Discard non-paradoxical subregs.  */
-  if (GET_CODE (x) == SUBREG
+  if (SUBREG_P (x)
       && (GET_MODE_SIZE (GET_MODE (x))
 	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
     x = SUBREG_REG (x);
@@ -858,7 +892,7 @@
       x = XEXP (x, 0);
 
       /* Discard non-paradoxical subregs.  */
-      if (GET_CODE (x) == SUBREG
+      if (SUBREG_P (x)
           && (GET_MODE_SIZE (GET_MODE (x))
 	      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
 	x = SUBREG_REG (x);
@@ -892,7 +926,7 @@
 	  x = XEXP (x, 0);
 
 	  /* Discard non-paradoxical subregs.  */
-	  if (GET_CODE (x) == SUBREG
+	  if (SUBREG_P (x)
 	      && (GET_MODE_SIZE (GET_MODE (x))
 		  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
 	    x = SUBREG_REG (x);
@@ -931,7 +965,7 @@
    to be legitimate.  If we find one, return the new, valid address.  */
 
 static rtx
-alpha_legitimize_address_1 (rtx x, rtx scratch, enum machine_mode mode)
+alpha_legitimize_address_1 (rtx x, rtx scratch, machine_mode mode)
 {
   HOST_WIDE_INT addend;
 
@@ -986,7 +1020,8 @@
       && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
       && symbolic_operand (x, Pmode))
     {
-      rtx r0, r16, eqv, tga, tp, insn, dest, seq;
+      rtx r0, r16, eqv, tga, tp, dest, seq;
+      rtx_insn *insn;
 
       switch (tls_symbolic_operand_type (x))
 	{
@@ -994,66 +1029,70 @@
 	  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));
-	  insn = gen_call_value_osf_tlsgd (r0, tga, seq);
-	  insn = emit_call_insn (insn);
-	  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;
+	  {
+	    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));
-	  insn = gen_call_value_osf_tlsldm (r0, tga, seq);
-	  insn = emit_call_insn (insn);
-	  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 (VOIDmode, dest, eqv));
-	      emit_insn (gen_adddi3 (dest, dest, scratch));
-	      return dest;
-	    }
-	  if (alpha_tls_size == 32)
-	    {
-	      insn = gen_rtx_HIGH (Pmode, eqv);
-	      insn = gen_rtx_PLUS (Pmode, scratch, insn);
-	      scratch = gen_reg_rtx (Pmode);
-	      emit_insn (gen_rtx_SET (VOIDmode, scratch, insn));
-	    }
-	  return gen_rtx_LO_SUM (Pmode, scratch, eqv);
+	  {
+	    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);
@@ -1062,8 +1101,8 @@
 	  scratch = gen_reg_rtx (Pmode);
 	  dest = gen_reg_rtx (Pmode);
 
-	  emit_insn (gen_load_tp (tp));
-	  emit_insn (gen_rtx_SET (VOIDmode, scratch, eqv));
+	  emit_insn (gen_get_thread_pointerdi (tp));
+	  emit_insn (gen_rtx_SET (scratch, eqv));
 	  emit_insn (gen_adddi3 (dest, tp, scratch));
 	  return dest;
 
@@ -1072,13 +1111,13 @@
 	  eqv = gen_rtx_CONST (Pmode, eqv);
 	  tp = gen_reg_rtx (Pmode);
 
-	  emit_insn (gen_load_tp (tp));
+	  emit_insn (gen_get_thread_pointerdi (tp));
 	  if (alpha_tls_size == 32)
 	    {
-	      insn = gen_rtx_HIGH (Pmode, eqv);
-	      insn = gen_rtx_PLUS (Pmode, tp, insn);
+	      rtx temp = gen_rtx_HIGH (Pmode, eqv);
+	      temp = gen_rtx_PLUS (Pmode, tp, temp);
 	      tp = gen_reg_rtx (Pmode);
-	      emit_insn (gen_rtx_SET (VOIDmode, tp, insn));
+	      emit_insn (gen_rtx_SET (tp, temp));
 	    }
 	  return gen_rtx_LO_SUM (Pmode, tp, eqv);
 
@@ -1094,8 +1133,7 @@
 	    {
 	      if (can_create_pseudo_p ())
 	        scratch = gen_reg_rtx (Pmode);
-	      emit_insn (gen_rtx_SET (VOIDmode, scratch,
-				      gen_rtx_HIGH (Pmode, x)));
+	      emit_insn (gen_rtx_SET (scratch, gen_rtx_HIGH (Pmode, x)));
 	      return gen_rtx_LO_SUM (Pmode, scratch, x);
 	    }
 	}
@@ -1121,7 +1159,7 @@
 			       (!can_create_pseudo_p () ? scratch : NULL_RTX),
 			       1, OPTAB_LIB_WIDEN);
 
-    return plus_constant (x, low);
+    return plus_constant (Pmode, x, low);
   }
 }
 
@@ -1131,18 +1169,29 @@
 
 static rtx
 alpha_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
-			  enum machine_mode mode)
+			  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 (rtx x)
+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;
@@ -1165,42 +1214,40 @@
   return decl_has_samegp (decl);
 }
 
-int
-some_small_symbolic_operand_int (rtx *px, void *data ATTRIBUTE_UNUSED)
-{
-  rtx x = *px;
-
-  /* Don't re-split.  */
-  if (GET_CODE (x) == LO_SUM)
-    return -1;
-
-  return small_symbolic_operand (x, Pmode) != 0;
-}
-
-static int
-split_small_symbolic_operand_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
-{
-  rtx x = *px;
-
-  /* Don't re-split.  */
-  if (GET_CODE (x) == LO_SUM)
-    return -1;
-
-  if (small_symbolic_operand (x, Pmode))
-    {
-      x = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x);
-      *px = x;
-      return -1;
-    }
-
-  return 0;
+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);
-  for_each_rtx (&x, split_small_symbolic_operand_1, NULL);
+  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;
 }
 
@@ -1219,7 +1266,7 @@
    containing the call and branch to the block containing the ldgp.  */
 
 static bool
-alpha_cannot_copy_insn_p (rtx insn)
+alpha_cannot_copy_insn_p (rtx_insn *insn)
 {
   if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
     return false;
@@ -1235,7 +1282,7 @@
 
 rtx
 alpha_legitimize_reload_address (rtx x,
-				 enum machine_mode mode ATTRIBUTE_UNUSED,
+				 machine_mode mode ATTRIBUTE_UNUSED,
 				 int opnum, int type,
 				 int ind_levels ATTRIBUTE_UNUSED)
 {
@@ -1259,7 +1306,7 @@
       && REG_P (XEXP (x, 0))
       && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
       && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0)))
-      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+      && CONST_INT_P (XEXP (x, 1)))
     {
       HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
@@ -1286,15 +1333,45 @@
   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, int code, int outer_code, int *total,
+alpha_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total,
 		 bool speed)
 {
-  enum machine_mode mode = GET_MODE (x);
+  int code = GET_CODE (x);
   bool float_mode_p = FLOAT_MODE_P (mode);
   const struct alpha_rtx_cost_data *cost_data;
 
@@ -1319,6 +1396,7 @@
       /* FALLTHRU */
 
     case CONST_DOUBLE:
+    case CONST_WIDE_INT:
       if (x == CONST0_RTX (mode))
 	*total = 0;
       else if ((outer_code == PLUS && add_operand (x, VOIDmode))
@@ -1358,10 +1436,10 @@
       else if (GET_CODE (XEXP (x, 0)) == MULT
 	       && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
 	{
-	  *total = (rtx_cost (XEXP (XEXP (x, 0), 0),
-			      (enum rtx_code) outer_code, speed)
-		    + rtx_cost (XEXP (x, 1),
-				(enum rtx_code) outer_code, speed)
+	  *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;
 	}
@@ -1462,8 +1540,7 @@
 
   gcc_assert (MEM_P (ref));
 
-  if (reload_in_progress
-      && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
+  if (reload_in_progress)
     {
       base = find_replacement (&XEXP (ref, 0));
       gcc_assert (memory_address_p (GET_MODE (ref), base));
@@ -1493,10 +1570,7 @@
   *paligned_mem = widen_memory_access (ref, SImode, -offset);
 
   /* Convert the byte offset within the word to a bit offset.  */
-  if (WORDS_BIG_ENDIAN)
-    offset = 32 - (GET_MODE_BITSIZE (GET_MODE (ref)) + offset * 8);
-  else
-    offset *= 8;
+  offset *= BITS_PER_UNIT;
   *pbitnum = GEN_INT (offset);
 }
 
@@ -1511,11 +1585,9 @@
 
   gcc_assert (MEM_P (ref));
 
-  if (reload_in_progress
-      && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
+  if (reload_in_progress)
     {
       base = find_replacement (&XEXP (ref, 0));
-
       gcc_assert (memory_address_p (GET_MODE (ref), base));
     }
   else
@@ -1524,7 +1596,7 @@
   if (GET_CODE (base) == PLUS)
     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
 
-  return plus_constant (base, offset);
+  return plus_constant (Pmode, base, offset);
 }
 
 /* Compute a value X, such that X & 7 == (ADDR + OFS) & 7.
@@ -1556,8 +1628,8 @@
     return rclass;
 
   /* These sorts of constants we can easily drop to memory.  */
-  if (CONST_INT_P (x)
-      || GET_CODE (x) == CONST_DOUBLE
+  if (CONST_SCALAR_INT_P (x)
+      || CONST_DOUBLE_P (x)
       || GET_CODE (x) == CONST_VECTOR)
     {
       if (rclass == FLOAT_REGS)
@@ -1582,7 +1654,7 @@
 
 static reg_class_t
 alpha_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
-			enum machine_mode mode, secondary_reload_info *sri)
+			machine_mode mode, secondary_reload_info *sri)
 {
   enum reg_class rclass = (enum reg_class) rclass_i;
 
@@ -1616,33 +1688,36 @@
 
   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 ();
+}
 
-/* Subfunction of the following function.  Update the flags of any MEM
-   found in part of X.  */
-
-static int
-alpha_set_memflags_1 (rtx *xp, void *data)
-{
-  rtx x = *xp, orig = (rtx) data;
-
-  if (!MEM_P (x))
-    return 0;
-
-  MEM_VOLATILE_P (x) = MEM_VOLATILE_P (orig);
-  MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (orig);
-  MEM_SCALAR_P (x) = MEM_SCALAR_P (orig);
-  MEM_NOTRAP_P (x) = MEM_NOTRAP_P (orig);
-  MEM_READONLY_P (x) = MEM_READONLY_P (orig);
-
-  /* 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.  */
-
-  return -1;
-}
-
 /* 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
@@ -1651,7 +1726,7 @@
 void
 alpha_set_memflags (rtx seq, rtx ref)
 {
-  rtx insn;
+  rtx_insn *insn;
 
   if (!MEM_P (ref))
     return;
@@ -1660,20 +1735,35 @@
      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_IN_STRUCT_P (ref)
-      && !MEM_SCALAR_P (ref)
       && !MEM_NOTRAP_P (ref)
       && !MEM_READONLY_P (ref))
     return;
 
-  for (insn = seq; insn; insn = NEXT_INSN (insn))
+  subrtx_var_iterator::array_type array;
+  for (insn = as_a <rtx_insn *> (seq); insn; insn = NEXT_INSN (insn))
     if (INSN_P (insn))
-      for_each_rtx (&PATTERN (insn), alpha_set_memflags_1, (void *) ref);
+      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, enum machine_mode, HOST_WIDE_INT,
+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.
@@ -1681,7 +1771,7 @@
    and return pc_rtx if successful.  */
 
 static rtx
-alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
+alpha_emit_set_const_1 (rtx target, machine_mode mode,
 			HOST_WIDE_INT c, int n, bool no_output)
 {
   HOST_WIDE_INT new_const;
@@ -1692,11 +1782,9 @@
   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.  We always have
-     a sign-extended 32-bit constant when compiling on a narrow machine.  */
-
-  if (HOST_BITS_PER_WIDE_INT != 64
-      || c >> 31 == -1 || c >> 31 == 0)
+     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;
@@ -1725,7 +1813,7 @@
 	    return pc_rtx;
 	  if (target == NULL)
 	    target = gen_reg_rtx (mode);
-	  emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
+	  emit_insn (gen_rtx_SET (target, GEN_INT (c)));
 	  return target;
 	}
       else if (n >= 2 + (extra != 0))
@@ -1734,7 +1822,7 @@
 	    return pc_rtx;
 	  if (!can_create_pseudo_p ())
 	    {
-	      emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (high << 16)));
+	      emit_insn (gen_rtx_SET (target, GEN_INT (high << 16)));
 	      temp = target;
 	    }
 	  else
@@ -1752,7 +1840,7 @@
 	      if (! subtarget)
 		subtarget = gen_reg_rtx (mode);
 	      insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16));
-	      insn = gen_rtx_SET (VOIDmode, subtarget, insn);
+	      insn = gen_rtx_SET (subtarget, insn);
 	      emit_insn (insn);
 	      temp = subtarget;
 	    }
@@ -1760,7 +1848,7 @@
 	  if (target == NULL)
 	    target = gen_reg_rtx (mode);
 	  insn = gen_rtx_PLUS (mode, temp, GEN_INT (low));
-	  insn = gen_rtx_SET (VOIDmode, target, insn);
+	  insn = gen_rtx_SET (target, insn);
 	  emit_insn (insn);
 	  return target;
 	}
@@ -1838,11 +1926,9 @@
       /* 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.  */
-      /* On narrow hosts, don't shift a 1 into the high bit, since we'll
-	 confuse the recursive call and set all of the high 32 bits.  */
 
       bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
-	      - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64));
+	      - floor_log2 (c) - 1);
       if (bits > 0)
 	for (; bits > 0; bits--)
 	  {
@@ -1850,7 +1936,7 @@
 	    temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
 	    if (!temp)
 	      {
-		new_const = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
+		new_const = (c << bits) | ((HOST_WIDE_INT_1U << bits) - 1);
 	        temp = alpha_emit_set_const (subtarget, mode, new_const,
 					     i, no_output);
 	      }
@@ -1876,7 +1962,7 @@
 	    temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
 	    if (!temp)
 	      {
-		new_const = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
+		new_const = (c << bits) | ((HOST_WIDE_INT_1U << bits) - 1);
 	        temp = alpha_emit_set_const (subtarget, mode, new_const,
 					     i, no_output);
 	      }
@@ -1890,7 +1976,6 @@
 	  }
     }
 
-#if HOST_BITS_PER_WIDE_INT == 64
   /* 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.  */
@@ -1917,7 +2002,6 @@
 			       target, 0, OPTAB_WIDEN);
 	}
     }
-#endif
 
   return 0;
 }
@@ -1929,10 +2013,10 @@
    insns and emitted.  */
 
 static rtx
-alpha_emit_set_const (rtx target, enum machine_mode mode,
+alpha_emit_set_const (rtx target, machine_mode mode,
 		      HOST_WIDE_INT c, int n, bool no_output)
 {
-  enum machine_mode orig_mode = mode;
+  machine_mode orig_mode = mode;
   rtx orig_target = target;
   rtx result = 0;
   int i;
@@ -1961,7 +2045,8 @@
       result = alpha_emit_set_const_1 (target, mode, c, i, no_output);
       if (result)
 	{
-	  rtx insn, set;
+	  rtx_insn *insn;
+	  rtx set;
 
 	  if (no_output)
 	    return result;
@@ -1992,13 +2077,12 @@
    with alpha_emit_set_const.  */
 
 static rtx
-alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
+alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1)
 {
   HOST_WIDE_INT d1, d2, d3, d4;
 
   /* Decompose the entire word */
-#if HOST_BITS_PER_WIDE_INT >= 64
-  gcc_assert (c2 == -(c1 < 0));
+
   d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
   c1 -= d1;
   d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
@@ -2007,17 +2091,6 @@
   c1 -= d3;
   d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
   gcc_assert (c1 == d4);
-#else
-  d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
-  c1 -= d1;
-  d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
-  gcc_assert (c1 == d2);
-  c2 += (d2 < 0);
-  d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
-  c2 -= d3;
-  d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
-  gcc_assert (c2 == d4);
-#endif
 
   /* Construct the high word */
   if (d4)
@@ -2041,48 +2114,28 @@
   return target;
 }
 
-/* Given an integral CONST_INT, CONST_DOUBLE, or CONST_VECTOR, return 
-   the low 64 bits.  */
-
-static void
-alpha_extract_integer (rtx x, HOST_WIDE_INT *p0, HOST_WIDE_INT *p1)
-{
-  HOST_WIDE_INT i0, i1;
-
+/* 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);
 
-
-  if (CONST_INT_P (x))
-    {
-      i0 = INTVAL (x);
-      i1 = -(i0 < 0);
-    }
-  else if (HOST_BITS_PER_WIDE_INT >= 64)
-    {
-      i0 = CONST_DOUBLE_LOW (x);
-      i1 = -(i0 < 0);
-    }
-  else
-    {
-      i0 = CONST_DOUBLE_LOW (x);
-      i1 = CONST_DOUBLE_HIGH (x);
-    }
-
-  *p0 = i0;
-  *p1 = i1;
-}
-
-/* Implement LEGITIMATE_CONSTANT_P.  This is all constants for which we
-   are willing to load the value into a register via a move pattern.
+  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 (rtx x)
-{
-  enum machine_mode mode = GET_MODE (x);
-  HOST_WIDE_INT i0, i1;
+alpha_legitimate_constant_p (machine_mode mode, rtx x)
+{
+  HOST_WIDE_INT i0;
 
   switch (GET_CODE (x))
     {
@@ -2092,26 +2145,36 @@
 
     case CONST:
       if (GET_CODE (XEXP (x, 0)) == PLUS
-	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+	  && 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;
-      if (FLOAT_MODE_P (mode))
-	return false;
-      goto do_integer;
+      return false;
 
     case CONST_VECTOR:
       if (x == CONST0_RTX (mode))
@@ -2120,16 +2183,14 @@
 	return false;
       if (GET_MODE_SIZE (mode) != 8)
 	return false;
-      goto do_integer;
+      /* FALLTHRU */
 
     case CONST_INT:
-    do_integer:
       if (TARGET_BUILD_CONSTANTS)
 	return true;
-      alpha_extract_integer (x, &i0, &i1);
-      if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == (-i0 < 0))
-        return alpha_emit_set_const_1 (x, mode, i0, 3, true) != NULL;
-      return false;
+      i0 = alpha_extract_integer (x);
+    do_integer:
+      return alpha_emit_set_const_1 (NULL_RTX, mode, i0, 3, true) != NULL;
 
     default:
       return false;
@@ -2140,18 +2201,17 @@
    instruction to load.  Emit that multi-part load.  */
 
 bool
-alpha_split_const_mov (enum machine_mode mode, rtx *operands)
-{
-  HOST_WIDE_INT i0, i1;
+alpha_split_const_mov (machine_mode mode, rtx *operands)
+{
+  HOST_WIDE_INT i0;
   rtx temp = NULL_RTX;
 
-  alpha_extract_integer (operands[1], &i0, &i1);
-
-  if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == -(i0 < 0))
-    temp = alpha_emit_set_const (operands[0], mode, i0, 3, false);
+  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, i1);
+    temp = alpha_emit_set_long_const (operands[0], i0);
 
   if (temp)
     {
@@ -2167,7 +2227,7 @@
    We don't handle non-bwx subword loads here.  */
 
 bool
-alpha_expand_mov (enum machine_mode mode, rtx *operands)
+alpha_expand_mov (machine_mode mode, rtx *operands)
 {
   rtx tmp;
 
@@ -2195,7 +2255,6 @@
 
   /* Split large integers.  */
   if (CONST_INT_P (operands[1])
-      || GET_CODE (operands[1]) == CONST_DOUBLE
       || GET_CODE (operands[1]) == CONST_VECTOR)
     {
       if (alpha_split_const_mov (mode, operands))
@@ -2222,7 +2281,7 @@
    return true if all work is done.  */
 
 bool
-alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
+alpha_expand_mov_nobwx (machine_mode mode, rtx *operands)
 {
   rtx seq;
 
@@ -2344,7 +2403,7 @@
    that is not naturally aligned.  Emit instructions to load it.  */
 
 void
-alpha_expand_movmisalign (enum machine_mode mode, rtx *operands)
+alpha_expand_movmisalign (machine_mode mode, rtx *operands)
 {
   /* Honor misaligned loads, for those we promised to do so.  */
   if (MEM_P (operands[1]))
@@ -2424,7 +2483,7 @@
 alpha_emit_floatuns (rtx operands[2])
 {
   rtx neglab, donelab, i0, i1, f0, in, out;
-  enum machine_mode mode;
+  machine_mode mode;
 
   out = operands[0];
   in = force_reg (DImode, operands[1]);
@@ -2437,7 +2496,7 @@
 
   emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab);
 
-  emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
+  emit_insn (gen_rtx_SET (out, gen_rtx_FLOAT (mode, in)));
   emit_jump_insn (gen_jump (donelab));
   emit_barrier ();
 
@@ -2446,8 +2505,8 @@
   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 (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
-  emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
+  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);
 }
@@ -2455,10 +2514,10 @@
 /* Generate the comparison for a conditional branch.  */
 
 void
-alpha_emit_conditional_branch (rtx operands[], enum machine_mode cmp_mode)
+alpha_emit_conditional_branch (rtx operands[], machine_mode cmp_mode)
 {
   enum rtx_code cmp_code, branch_code;
-  enum machine_mode branch_mode = VOIDmode;
+  machine_mode branch_mode = VOIDmode;
   enum rtx_code code = GET_CODE (operands[0]);
   rtx op0 = operands[1], op1 = operands[2];
   rtx tem;
@@ -2476,7 +2535,7 @@
     {
     case EQ:  case LE:  case LT:  case LEU:  case LTU:
     case UNORDERED:
-      /* We have these compares: */
+      /* We have these compares.  */
       cmp_code = code, branch_code = NE;
       break;
 
@@ -2492,7 +2551,7 @@
 	{
 	  cmp_code = swap_condition (code);
 	  branch_code = NE;
-	  tem = op0, op0 = op1, op1 = tem;
+	  std::swap (op0, op1);
 	}
       else
 	{
@@ -2516,7 +2575,7 @@
 	  else if (op0 == CONST0_RTX (DFmode))
 	    {
 	      /* Undo the swap we probably did just above.  */
-	      tem = op0, op0 = op1, op1 = tem;
+	      std::swap (op0, op1);
 	      branch_code = swap_condition (cmp_code);
 	      cmp_code = UNKNOWN;
 	    }
@@ -2573,7 +2632,7 @@
     }
 
   /* Emit the branch instruction.  */
-  tem = gen_rtx_SET (VOIDmode, pc_rtx,
+  tem = gen_rtx_SET (pc_rtx,
 		     gen_rtx_IF_THEN_ELSE (VOIDmode,
 					   gen_rtx_fmt_ee (branch_code,
 							   branch_mode, tem,
@@ -2588,7 +2647,7 @@
    valid.  Return the final comparison, or NULL if we can't work.  */
 
 bool
-alpha_emit_setcc (rtx operands[], enum machine_mode cmp_mode)
+alpha_emit_setcc (rtx operands[], machine_mode cmp_mode)
 {
   enum rtx_code cmp_code;
   enum rtx_code code = GET_CODE (operands[1]);
@@ -2636,7 +2695,7 @@
       code = swap_condition (code);
       if (cmp_mode == DFmode)
 	cmp_code = code, code = NE;
-      tmp = op0, op0 = op1, op1 = tmp;
+      std::swap (op0, op1);
       break;
 
     default:
@@ -2655,16 +2714,16 @@
   if (cmp_code != UNKNOWN)
     {
       tmp = gen_reg_rtx (cmp_mode);
-      emit_insn (gen_rtx_SET (VOIDmode, tmp,
-			      gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1)));
+      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 (VOIDmode, operands[0],
-			  gen_rtx_fmt_ee (code, DImode, op0, op1)));
+  emit_insn (gen_rtx_SET (operands[0], gen_rtx_fmt_ee (code, DImode,
+						       op0, op1)));
   return true;
 }
 
@@ -2677,15 +2736,15 @@
    the conditional move).  */
 
 rtx
-alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
+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);
-  enum machine_mode cmp_mode
+  machine_mode cmp_mode
     = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
-  enum machine_mode cmov_mode = VOIDmode;
+  machine_mode cmov_mode = VOIDmode;
   int local_fast_math = flag_unsafe_math_optimizations;
   rtx tem;
 
@@ -2713,13 +2772,15 @@
       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:
-	  /* This must be reversed.  */
-	  cmp_code = EQ, code = EQ;
+	case ORDERED:
+	  /* These must be reversed.  */
+	  cmp_code = reverse_condition (code), code = EQ;
 	  break;
 
 	case GE: case GT: case GEU: case GTU:
@@ -2731,7 +2792,7 @@
 	    {
 	      cmp_code = swap_condition (code);
 	      code = NE;
-	      tem = op0, op0 = op1, op1 = tem;
+	      std::swap (op0, op1);
 	    }
 	  break;
 
@@ -2739,17 +2800,33 @@
 	  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 (VOIDmode, tem,
-			      gen_rtx_fmt_ee (cmp_code, cmp_mode,
-					      op0, op1)));
-
-      cmp_mode = cmp_mode == DImode ? DFmode : DImode;
+      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)
@@ -2768,22 +2845,24 @@
   switch (code)
     {
     case EQ:  case LE:  case LT:  case LEU:  case LTU:
+    case UNORDERED:
       /* We have these compares: */
       break;
 
     case NE:
-      /* This must be reversed.  */
+    case ORDERED:
+      /* These must be reversed.  */
       code = reverse_condition (code);
       cmov_code = EQ;
       break;
 
     case GE:  case GT:  case GEU:  case GTU:
-      /* These must be swapped.  */
-      if (op1 != CONST0_RTX (cmp_mode))
-	{
-	  code = swap_condition (code);
-	  tem = op0, op0 = op1, op1 = tem;
-	}
+      /* 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:
@@ -2819,7 +2898,7 @@
 			      rtx t_rtx, rtx f_rtx)
 {
   HOST_WIDE_INT t, f, diff;
-  enum machine_mode mode;
+  machine_mode mode;
   rtx target, subtarget, tmp;
 
   mode = GET_MODE (dest);
@@ -2831,8 +2910,8 @@
       || (code == GE || code == GT))
     {
       code = reverse_condition (code);
-      diff = t, t = f, f = diff;
-      diff = t - f;
+      std::swap (t, f);
+      diff = -diff;
     }
 
   subtarget = target = dest;
@@ -2855,16 +2934,16 @@
       && (diff <= 8 || alpha_tune == PROCESSOR_EV6))
     {
       tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
-      emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
+      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 (VOIDmode, target, tmp));
+      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 (VOIDmode, copy_rtx (subtarget), tmp));
+      emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp));
 
       emit_insn (gen_negdi2 (target, copy_rtx (subtarget)));
     }
@@ -2873,7 +2952,7 @@
       rtx add_op;
 
       tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
-      emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
+      emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp));
 
       if (diff == 1)
 	emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f)));
@@ -2885,7 +2964,7 @@
 	      tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget),
 				  GEN_INT (diff));
 	      tmp = gen_rtx_PLUS (DImode, tmp, add_op);
-	      emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
+	      emit_insn (gen_rtx_SET (target, tmp));
 	    }
 	  else
 	    return 0;
@@ -3017,7 +3096,7 @@
 alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
 			      int noperands, rtx equiv)
 {
-  rtx usage = NULL_RTX, tmp, reg;
+  rtx usage = NULL_RTX, reg;
   int regno = 16, i;
 
   start_sequence ();
@@ -3026,20 +3105,20 @@
     {
       switch (GET_MODE (operands[i]))
 	{
-	case TFmode:
+	case E_TFmode:
 	  reg = gen_rtx_REG (TFmode, regno);
 	  regno += 2;
 	  break;
 
-	case DFmode:
+	case E_DFmode:
 	  reg = gen_rtx_REG (DFmode, regno + 32);
 	  regno += 1;
 	  break;
 
-	case VOIDmode:
+	case E_VOIDmode:
 	  gcc_assert (CONST_INT_P (operands[i]));
 	  /* FALLTHRU */
-	case DImode:
+	case E_DImode:
 	  reg = gen_rtx_REG (DImode, regno);
 	  regno += 1;
 	  break;
@@ -3049,27 +3128,27 @@
 	}
 
       emit_move_insn (reg, operands[i]);
-      usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
+      use_reg (&usage, reg);
     }
 
   switch (GET_MODE (target))
     {
-    case TFmode:
+    case E_TFmode:
       reg = gen_rtx_REG (TFmode, 16);
       break;
-    case DFmode:
+    case E_DFmode:
       reg = gen_rtx_REG (DFmode, 32);
       break;
-    case DImode:
+    case E_DImode:
       reg = gen_rtx_REG (DImode, 0);
       break;
     default:
       gcc_unreachable ();
     }
 
-  tmp = gen_rtx_MEM (QImode, func);
-  tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
-					const0_rtx, const0_rtx));
+  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;
 
@@ -3145,12 +3224,9 @@
   operands[1] = op1;
   out = gen_reg_rtx (DImode);
 
-  /* What's actually returned is -1,0,1, not a proper boolean value,
-     so use an EXPR_LIST as with a generic libcall instead of a 
-     comparison type expression.  */
-  note = gen_rtx_EXPR_LIST (VOIDmode, op1, NULL_RTX);
-  note = gen_rtx_EXPR_LIST (VOIDmode, op0, note);
-  note = gen_rtx_EXPR_LIST (VOIDmode, func, note);
+  /* 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;
@@ -3204,7 +3280,7 @@
    This is used by *movtf_internal and *movti_internal.  */
   
 void
-alpha_split_tmode_pair (rtx operands[4], enum machine_mode mode,
+alpha_split_tmode_pair (rtx operands[4], machine_mode mode,
 			bool fixup_overlap)
 {
   switch (GET_CODE (operands[1]))
@@ -3219,7 +3295,7 @@
       operands[2] = adjust_address (operands[1], DImode, 0);
       break;
 
-    case CONST_INT:
+    CASE_CONST_SCALAR_INT:
     case CONST_DOUBLE:
       gcc_assert (operands[1] == CONST0_RTX (mode));
       operands[2] = operands[3] = const0_rtx;
@@ -3247,9 +3323,8 @@
 
   if (fixup_overlap && reg_overlap_mentioned_p (operands[0], operands[3]))
     {
-      rtx tmp;
-      tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
-      tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
+      std::swap (operands[0], operands[1]);
+      std::swap (operands[2], operands[3]);
     }
 }
 
@@ -3329,14 +3404,12 @@
 			     HOST_WIDE_INT ofs, int sign)
 {
   rtx meml, memh, addr, extl, exth, tmp, mema;
-  enum machine_mode mode;
+  machine_mode mode;
 
   if (TARGET_BWX && size == 2)
     {
       meml = adjust_address (mem, QImode, ofs);
       memh = adjust_address (mem, QImode, ofs+1);
-      if (BYTES_BIG_ENDIAN)
-	tmp = meml, meml = memh, memh = tmp;
       extl = gen_reg_rtx (DImode);
       exth = gen_reg_rtx (DImode);
       emit_insn (gen_zero_extendqidi2 (extl, meml));
@@ -3376,35 +3449,25 @@
 
   tmp = change_address (mem, DImode,
 			gen_rtx_AND (DImode,
-				     plus_constant (mema, ofs),
+				     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 (mema, ofs + size - 1),
+				     plus_constant (DImode, mema,
+						    ofs + size - 1),
 				     GEN_INT (-8)));
   set_mem_alias_set (tmp, 0);
   emit_move_insn (memh, tmp);
 
-  if (WORDS_BIG_ENDIAN && sign && (size == 2 || size == 4))
-    {
-      emit_move_insn (addr, plus_constant (mema, -1));
-
-      emit_insn (gen_extqh_be (extl, meml, addr));
-      emit_insn (gen_extxl_be (exth, memh, GEN_INT (64), addr));
-
-      addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
-      addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (64 - size*8),
-			   addr, 1, OPTAB_WIDEN);
-    }
-  else if (sign && size == 2)
-    {
-      emit_move_insn (addr, plus_constant (mema, ofs+2));
-
-      emit_insn (gen_extxl_le (extl, meml, GEN_INT (64), addr));
-      emit_insn (gen_extqh_le (exth, memh, addr));
+  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
@@ -3415,55 +3478,24 @@
     }
   else
     {
-      if (WORDS_BIG_ENDIAN)
-	{
-	  emit_move_insn (addr, plus_constant (mema, ofs+size-1));
-	  switch ((int) size)
-	    {
-	    case 2:
-	      emit_insn (gen_extwh_be (extl, meml, addr));
-	      mode = HImode;
-	      break;
-
-	    case 4:
-	      emit_insn (gen_extlh_be (extl, meml, addr));
-	      mode = SImode;
-	      break;
-
-	    case 8:
-	      emit_insn (gen_extqh_be (extl, meml, addr));
-	      mode = DImode;
-	      break;
-
-	    default:
-	      gcc_unreachable ();
-	    }
-	  emit_insn (gen_extxl_be (exth, memh, GEN_INT (size*8), addr));
-	}
-      else
-	{
-	  emit_move_insn (addr, plus_constant (mema, ofs));
-	  emit_insn (gen_extxl_le (extl, meml, GEN_INT (size*8), addr));
-	  switch ((int) size)
-	    {
-	    case 2:
-	      emit_insn (gen_extwh_le (exth, memh, addr));
-	      mode = HImode;
-	      break;
-
-	    case 4:
-	      emit_insn (gen_extlh_le (exth, memh, addr));
-	      mode = SImode;
-	      break;
-
-	    case 8:
-	      emit_insn (gen_extqh_le (exth, memh, addr));
-	      mode = DImode;
-	      break;
-
-	    default:
-	      gcc_unreachable ();
-	    }
+      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),
@@ -3497,8 +3529,6 @@
 
       meml = adjust_address (dst, QImode, ofs);
       memh = adjust_address (dst, QImode, ofs+1);
-      if (BYTES_BIG_ENDIAN)
-	addr = meml, meml = memh, memh = addr;
 
       emit_move_insn (meml, dstl);
       emit_move_insn (memh, dsth);
@@ -3520,98 +3550,58 @@
 
   meml = change_address (dst, DImode,
 			 gen_rtx_AND (DImode,
-				      plus_constant (dsta, ofs),
+				      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 (dsta, ofs + size - 1),
+				      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);
-  if (WORDS_BIG_ENDIAN)
-    {
-      addr = copy_addr_to_reg (plus_constant (dsta, ofs+size-1));
-
-      if (src != const0_rtx)
-	{
-	  switch ((int) size)
-	    {
-	    case 2:
-	      emit_insn (gen_inswl_be (insh, gen_lowpart (HImode,src), addr));
-	      break;
-	    case 4:
-	      emit_insn (gen_insll_be (insh, gen_lowpart (SImode,src), addr));
-	      break;
-	    case 8:
-	      emit_insn (gen_insql_be (insh, gen_lowpart (DImode,src), addr));
-	      break;
-	    }
-	  emit_insn (gen_insxh (insl, gen_lowpart (DImode, src),
-				GEN_INT (size*8), addr));
-	}
+
+  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_mskxl_be (dsth, dsth, GEN_INT (0xffff), addr));
+	  emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
 	  break;
 	case 4:
-	  {
-	    rtx msk = immed_double_const (0xffffffff, 0, DImode);
-	    emit_insn (gen_mskxl_be (dsth, dsth, msk, addr));
-	    break;
-	  }
+	  emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
+	  break;
 	case 8:
-	  emit_insn (gen_mskxl_be (dsth, dsth, constm1_rtx, addr));
+	  emit_insn (gen_insql (insl, gen_lowpart (DImode, src), addr));
 	  break;
-	}
-
-      emit_insn (gen_mskxh (dstl, dstl, GEN_INT (size*8), addr));
-    }
-  else
-    {
-      addr = copy_addr_to_reg (plus_constant (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_le (insl, gen_lowpart (HImode, src), addr));
-	      break;
-	    case 4:
-	      emit_insn (gen_insll_le (insl, gen_lowpart (SImode, src), addr));
-	      break;
-	    case 8:
-	      emit_insn (gen_insql_le (insl, gen_lowpart (DImode, src), addr));
-	      break;
-	    }
-	}
-
-      emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
-
-      switch ((int) size)
-	{
-	case 2:
-	  emit_insn (gen_mskxl_le (dstl, dstl, GEN_INT (0xffff), addr));
-	  break;
-	case 4:
-	  {
-	    rtx msk = immed_double_const (0xffffffff, 0, DImode);
-	    emit_insn (gen_mskxl_le (dstl, dstl, msk, addr));
-	    break;
-	  }
-	case 8:
-	  emit_insn (gen_mskxl_le (dstl, dstl, constm1_rtx, 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)))
@@ -3620,17 +3610,9 @@
       dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
     }
 
-  if (WORDS_BIG_ENDIAN)
-    {
-      emit_move_insn (meml, dstl);
-      emit_move_insn (memh, dsth);
-    }
-  else
-    {
-      /* Must store high before low for degenerate case of aligned.  */
-      emit_move_insn (memh, dsth);
-      emit_move_insn (meml, dstl);
-    }
+  /* 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
@@ -3648,7 +3630,6 @@
 				   HOST_WIDE_INT words, HOST_WIDE_INT ofs)
 {
   rtx const im8 = GEN_INT (-8);
-  rtx const i64 = GEN_INT (64);
   rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
   rtx sreg, areg, tmp, smema;
   HOST_WIDE_INT i;
@@ -3673,7 +3654,7 @@
     {
       tmp = change_address (smem, DImode,
 			    gen_rtx_AND (DImode,
-					 plus_constant (smema, 8*i),
+					 plus_constant (DImode, smema, 8*i),
 					 im8));
       set_mem_alias_set (tmp, 0);
       emit_move_insn (data_regs[i], tmp);
@@ -3681,7 +3662,8 @@
 
   tmp = change_address (smem, DImode,
 			gen_rtx_AND (DImode,
-				     plus_constant (smema, 8*words - 1),
+				     plus_constant (DImode, smema,
+						    8*words - 1),
 				     im8));
   set_mem_alias_set (tmp, 0);
   emit_move_insn (data_regs[words], tmp);
@@ -3693,21 +3675,11 @@
   sreg = copy_addr_to_reg (smema);
   areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
 		       1, OPTAB_WIDEN);
-  if (WORDS_BIG_ENDIAN)
-    emit_move_insn (sreg, plus_constant (sreg, 7));
   for (i = 0; i < words; ++i)
     {
-      if (WORDS_BIG_ENDIAN)
-	{
-	  emit_insn (gen_extqh_be (data_regs[i], data_regs[i], sreg));
-	  emit_insn (gen_extxl_be (ext_tmps[i], data_regs[i+1], i64, sreg));
-	}
-      else
-	{
-	  emit_insn (gen_extxl_le (data_regs[i], data_regs[i], i64, sreg));
-	  emit_insn (gen_extqh_le (ext_tmps[i], data_regs[i+1], sreg));
-	}
-      emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[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),
@@ -3730,7 +3702,6 @@
 				    HOST_WIDE_INT words, HOST_WIDE_INT ofs)
 {
   rtx const im8 = GEN_INT (-8);
-  rtx const i64 = GEN_INT (64);
   rtx ins_tmps[MAX_MOVE_WORDS];
   rtx st_tmp_1, st_tmp_2, dreg;
   rtx st_addr_1, st_addr_2, dmema;
@@ -3752,8 +3723,9 @@
 
   st_addr_2 = change_address (dmem, DImode,
 			      gen_rtx_AND (DImode,
-					   plus_constant (dmema, words*8 - 1),
-				       im8));
+					   plus_constant (DImode, dmema,
+							  words*8 - 1),
+					   im8));
   set_mem_alias_set (st_addr_2, 0);
 
   st_addr_1 = change_address (dmem, DImode,
@@ -3766,22 +3738,12 @@
 
   /* Shift the input data into place.  */
   dreg = copy_addr_to_reg (dmema);
-  if (WORDS_BIG_ENDIAN)
-    emit_move_insn (dreg, plus_constant (dreg, 7));
   if (data_regs != NULL)
     {
       for (i = words-1; i >= 0; --i)
 	{
-	  if (WORDS_BIG_ENDIAN)
-	    {
-	      emit_insn (gen_insql_be (ins_tmps[i], data_regs[i], dreg));
-	      emit_insn (gen_insxh (data_regs[i], data_regs[i], i64, dreg));
-	    }
-	  else
-	    {
-	      emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
-	      emit_insn (gen_insql_le (data_regs[i], data_regs[i], dreg));
-	    }
+	  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)
 	{
@@ -3792,16 +3754,8 @@
     }
 
   /* Split and merge the ends with the destination data.  */
-  if (WORDS_BIG_ENDIAN)
-    {
-      emit_insn (gen_mskxl_be (st_tmp_2, st_tmp_2, constm1_rtx, dreg));
-      emit_insn (gen_mskxh (st_tmp_1, st_tmp_1, i64, dreg));
-    }
-  else
-    {
-      emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
-      emit_insn (gen_mskxl_le (st_tmp_1, st_tmp_1, constm1_rtx, dreg));
-    }
+  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)
     {
@@ -3812,24 +3766,18 @@
     }
 
   /* Store it all.  */
-  if (WORDS_BIG_ENDIAN)
-    emit_move_insn (st_addr_1, st_tmp_1);
-  else
-    emit_move_insn (st_addr_2, st_tmp_2);
+  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(dmema,
-					     WORDS_BIG_ENDIAN ? i*8-1 : i*8),
+					     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);
     }
-  if (WORDS_BIG_ENDIAN)
-    emit_move_insn (st_addr_2, st_tmp_2);
-  else
-    emit_move_insn (st_addr_1, st_tmp_1);
+  emit_move_insn (st_addr_1, st_tmp_1);
 }
 
 
@@ -4131,7 +4079,6 @@
 
   if (alignofs > 0)
     {
-#if HOST_BITS_PER_WIDE_INT >= 64
       /* 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.  */
@@ -4139,7 +4086,7 @@
 	       && align >= 32
 	       && !(alignofs == 4 && bytes >= 4))
 	{
-	  enum machine_mode mode = (align >= 64 ? DImode : SImode);
+	  machine_mode mode = (align >= 64 ? DImode : SImode);
 	  int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
 	  rtx mem, tmp;
 	  HOST_WIDE_INT mask;
@@ -4147,10 +4094,10 @@
 	  mem = adjust_address (orig_dst, mode, ofs - inv_alignofs);
 	  set_mem_alias_set (mem, 0);
 
-	  mask = ~(~(HOST_WIDE_INT)0 << (inv_alignofs * 8));
+	  mask = ~(HOST_WIDE_INT_M1U << (inv_alignofs * 8));
 	  if (bytes < alignofs)
 	    {
-	      mask |= ~(HOST_WIDE_INT)0 << ((inv_alignofs + bytes) * 8);
+	      mask |= HOST_WIDE_INT_M1U << ((inv_alignofs + bytes) * 8);
 	      ofs += bytes;
 	      bytes = 0;
 	    }
@@ -4166,7 +4113,6 @@
 
 	  emit_move_insn (mem, tmp);
 	}
-#endif
 
       if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
 	{
@@ -4234,7 +4180,8 @@
 	  rtx mem
 	    = change_address (orig_dst, DImode,
 			      gen_rtx_AND (DImode,
-					   plus_constant (orig_dsta, ofs + i*8),
+					   plus_constant (DImode, orig_dsta,
+							  ofs + i*8),
 					   GEN_INT (-8)));
 	  set_mem_alias_set (mem, 0);
 	  emit_move_insn (mem, const0_rtx);
@@ -4277,7 +4224,6 @@
 
   /* Next clean up any trailing pieces.  */
 
-#if HOST_BITS_PER_WIDE_INT >= 64
   /* Count the number of bits in BYTES for which aligned stores could
      be emitted.  */
   words = 0;
@@ -4297,7 +4243,7 @@
 	  mem = adjust_address (orig_dst, DImode, ofs);
 	  set_mem_alias_set (mem, 0);
 
-	  mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
+	  mask = HOST_WIDE_INT_M1U << (bytes * 8);
 
 	  tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
 			      NULL_RTX, 1, OPTAB_WIDEN);
@@ -4313,7 +4259,7 @@
 	  mem = adjust_address (orig_dst, SImode, ofs);
 	  set_mem_alias_set (mem, 0);
 
-	  mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
+	  mask = HOST_WIDE_INT_M1U << (bytes * 8);
 
 	  tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
 			      NULL_RTX, 1, OPTAB_WIDEN);
@@ -4322,7 +4268,6 @@
 	  return 1;
 	}
     }
-#endif
 
   if (!TARGET_BWX && bytes >= 4)
     {
@@ -4367,49 +4312,22 @@
 {
   rtx result;
   int i;
-
-  if (HOST_BITS_PER_WIDE_INT >= 64)
-    {
-      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);
-    }
-  else
-    {
-      HOST_WIDE_INT mask_lo = 0, mask_hi = 0;
-
-      gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
-      
-      for (i = 7; i >= 4; --i)
-	{
-	  mask_hi <<= 8;
-	  if (!((value >> i) & 1))
-	    mask_hi |= 0xff;
-	}
-
-      for (i = 3; i >= 0; --i)
-	{
-	  mask_lo <<= 8;
-	  if (!((value >> i) & 1))
-	    mask_lo |= 0xff;
-	}
-
-      result = immed_double_const (mask_lo, mask_hi, DImode);
-    }
-
+  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),
-				   enum machine_mode mode,
+				   machine_mode mode,
 				   rtx op0, rtx op1, rtx op2)
 {
   op0 = gen_lowpart (mode, op0);
@@ -4433,19 +4351,16 @@
 static void
 emit_unlikely_jump (rtx cond, rtx label)
 {
-  rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
-  rtx x;
-
-  x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
-  x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
-  add_reg_note (x, REG_BR_PROB, very_unlikely);
+  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 ());
 }
 
 /* A subroutine of the atomic operation splitters.  Emit a load-locked
    instruction in MODE.  */
 
 static void
-emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
+emit_load_locked (machine_mode mode, rtx reg, rtx mem)
 {
   rtx (*fn) (rtx, rtx) = NULL;
   if (mode == SImode)
@@ -4459,7 +4374,7 @@
    instruction in MODE.  */
 
 static void
-emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
+emit_store_conditional (machine_mode mode, rtx res, rtx mem, rtx val)
 {
   rtx (*fn) (rtx, rtx, rtx) = NULL;
   if (mode == SImode)
@@ -4469,30 +4384,50 @@
   emit_insn (fn (res, mem, val));
 }
 
+/* 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 (enum machine_mode mode, rtx op1, rtx op2)
+emit_insxl (machine_mode mode, rtx op1, rtx op2)
 {
   rtx ret = gen_reg_rtx (DImode);
   rtx (*fn) (rtx, rtx, rtx);
 
-  if (WORDS_BIG_ENDIAN)
-    {
-      if (mode == QImode)
-	fn = gen_insbl_be;
-      else
-	fn = gen_inswl_be;
-    }
-  else
-    {
-      if (mode == QImode)
-	fn = gen_insbl_le;
-      else
-	fn = gen_inswl_le;
-    }
-  /* The insbl and inswl patterns require a register operand.  */
+  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));
 
@@ -4506,13 +4441,13 @@
    a scratch register.  */
 
 void
-alpha_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
-		       rtx before, rtx after, rtx scratch)
-{
-  enum machine_mode mode = GET_MODE (mem);
+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));
 
-  emit_insn (gen_memory_barrier ());
+  alpha_pre_atomic_barrier (model);
 
   label = gen_label_rtx ();
   emit_label (label);
@@ -4525,142 +4460,227 @@
   if (code == NOT)
     {
       x = gen_rtx_AND (mode, before, val);
-      emit_insn (gen_rtx_SET (VOIDmode, val, x));
+      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 (VOIDmode, after, copy_rtx (x)));
-  emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
+    emit_insn (gen_rtx_SET (after, copy_rtx (x)));
+  emit_insn (gen_rtx_SET (scratch, x));
 
   emit_store_conditional (mode, cond, mem, scratch);
 
   x = gen_rtx_EQ (DImode, cond, const0_rtx);
   emit_unlikely_jump (x, label);
 
-  emit_insn (gen_memory_barrier ());
+  alpha_post_atomic_barrier (model);
 }
 
 /* Expand a compare and swap operation.  */
 
 void
-alpha_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
-			      rtx scratch)
-{
-  enum machine_mode mode = GET_MODE (mem);
-  rtx label1, label2, x, cond = gen_lowpart (DImode, scratch);
-
-  emit_insn (gen_memory_barrier ());
-
-  label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
+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_label (XEXP (label1, 0));
 
   emit_load_locked (mode, retval, mem);
 
   x = gen_lowpart (DImode, retval);
   if (oldval == const0_rtx)
-    x = gen_rtx_NE (DImode, x, 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 (VOIDmode, cond, x));
+      emit_insn (gen_rtx_SET (cond, x));
       x = gen_rtx_EQ (DImode, cond, const0_rtx);
     }
   emit_unlikely_jump (x, label2);
 
-  emit_move_insn (scratch, newval);
-  emit_store_conditional (mode, cond, mem, scratch);
-
-  x = gen_rtx_EQ (DImode, cond, const0_rtx);
-  emit_unlikely_jump (x, label1);
-
-  emit_insn (gen_memory_barrier ());
-  emit_label (XEXP (label2, 0));
+  emit_move_insn (cond, newval);
+  emit_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 dst, rtx mem, rtx oldval, rtx newval)
-{
-  enum machine_mode mode = GET_MODE (mem);
+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;
-  rtx (*fn5) (rtx, rtx, rtx, rtx, rtx);
-
-  addr = force_reg (DImode, XEXP (mem, 0));
+  rtx (*gen) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+
+  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);
-  newval = emit_insxl (mode, newval, addr);
+
+  if (newval != const0_rtx)
+    newval = emit_insxl (mode, newval, addr);
 
   wdst = gen_reg_rtx (DImode);
   if (mode == QImode)
-    fn5 = gen_sync_compare_and_swapqi_1;
+    gen = gen_atomic_compare_and_swapqi_1;
   else
-    fn5 = gen_sync_compare_and_swaphi_1;
-  emit_insn (fn5 (wdst, addr, oldval, newval, align));
+    gen = gen_atomic_compare_and_swaphi_1;
+  emit_insn (gen (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 (enum machine_mode mode, rtx dest, rtx addr,
-				 rtx oldval, rtx newval, rtx align,
-				 rtx scratch, rtx cond)
-{
-  rtx label1, label2, mem, width, mask, x;
+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) = 1;
-
-  emit_insn (gen_memory_barrier ());
-  label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
+  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_label (XEXP (label1, 0));
 
   emit_load_locked (DImode, scratch, mem);
   
   width = GEN_INT (GET_MODE_BITSIZE (mode));
   mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
-  if (WORDS_BIG_ENDIAN)
-    emit_insn (gen_extxl_be (dest, scratch, width, addr));
-  else
-    emit_insn (gen_extxl_le (dest, scratch, width, addr));
+  emit_insn (gen_extxl (dest, scratch, width, addr));
 
   if (oldval == const0_rtx)
-    x = gen_rtx_NE (DImode, dest, 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 (VOIDmode, cond, x));
+      emit_insn (gen_rtx_SET (cond, x));
       x = gen_rtx_EQ (DImode, cond, const0_rtx);
     }
   emit_unlikely_jump (x, label2);
 
-  if (WORDS_BIG_ENDIAN)
-    emit_insn (gen_mskxl_be (scratch, scratch, mask, addr));
-  else
-    emit_insn (gen_mskxl_le (scratch, scratch, mask, addr));
-  emit_insn (gen_iordi3 (scratch, scratch, newval));
-
-  emit_store_conditional (DImode, scratch, mem, scratch);
-
-  x = gen_rtx_EQ (DImode, scratch, const0_rtx);
-  emit_unlikely_jump (x, label1);
-
-  emit_insn (gen_memory_barrier ());
-  emit_label (XEXP (label2, 0));
+  emit_insn (gen_mskxl (cond, scratch, mask, addr));
+
+  if (newval != const0_rtx)
+    emit_insn (gen_iordi3 (cond, cond, newval));
+
+  emit_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_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
-{
-  enum machine_mode mode = GET_MODE (mem);
-  rtx label, x, cond = gen_lowpart (DImode, scratch);
+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));
@@ -4672,44 +4692,67 @@
   x = gen_rtx_EQ (DImode, cond, const0_rtx);
   emit_unlikely_jump (x, label);
 
-  emit_insn (gen_memory_barrier ());
+  alpha_post_atomic_barrier (model);
 }
 
 void
-alpha_expand_lock_test_and_set_12 (rtx dst, rtx mem, rtx val)
-{
-  enum machine_mode mode = GET_MODE (mem);
+alpha_expand_atomic_exchange_12 (rtx operands[])
+{
+  rtx dst, mem, val, model;
+  machine_mode mode;
   rtx addr, align, wdst;
-  rtx (*fn4) (rtx, rtx, rtx, rtx);
-
-  /* Force the address into a register.  */
-  addr = force_reg (DImode, XEXP (mem, 0));
-
-  /* Align it to a multiple of 8.  */
+  rtx (*gen) (rtx, rtx, rtx, rtx, rtx);
+
+  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.  */
-  val = emit_insxl (mode, val, addr);
+  if (val != const0_rtx)
+    val = emit_insxl (mode, val, addr);
 
   wdst = gen_reg_rtx (DImode);
   if (mode == QImode)
-    fn4 = gen_sync_lock_test_and_setqi_1;
+    gen = gen_atomic_exchangeqi_1;
   else
-    fn4 = gen_sync_lock_test_and_sethi_1;
-  emit_insn (fn4 (wdst, addr, val, align));
+    gen = gen_atomic_exchangehi_1;
+  emit_insn (gen (wdst, mem, val, align, model));
 
   emit_move_insn (dst, gen_lowpart (mode, wdst));
 }
 
 void
-alpha_split_lock_test_and_set_12 (enum machine_mode mode, rtx dest, rtx addr,
-				  rtx val, rtx align, rtx scratch)
-{
+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) = 1;
+  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));
@@ -4718,38 +4761,32 @@
   
   width = GEN_INT (GET_MODE_BITSIZE (mode));
   mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
-  if (WORDS_BIG_ENDIAN)
-    {
-      emit_insn (gen_extxl_be (dest, scratch, width, addr));
-      emit_insn (gen_mskxl_be (scratch, scratch, mask, addr));
-    }
-  else
-    {
-      emit_insn (gen_extxl_le (dest, scratch, width, addr));
-      emit_insn (gen_mskxl_le (scratch, scratch, mask, addr));
-    }
-  emit_insn (gen_iordi3 (scratch, scratch, val));
+  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_store_conditional (DImode, scratch, mem, scratch);
 
   x = gen_rtx_EQ (DImode, scratch, const0_rtx);
   emit_unlikely_jump (x, label);
 
-  emit_insn (gen_memory_barrier ());
+  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, rtx link, rtx dep_insn, int cost)
+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 (REG_NOTE_KIND (link) != 0)
+  if (dep_type != 0)
     return cost;
 
   /* If we can't recognize the insns, we can't really do anything.  */
@@ -4793,25 +4830,18 @@
 
 /* Machine-specific function data.  */
 
+struct GTY(()) alpha_links;
+
 struct GTY(()) machine_function
 {
-  /* For unicosmk.  */
-  /* List of call information words for calls from this function.  */
-  struct rtx_def *first_ciw;
-  struct rtx_def *last_ciw;
-  int ciw_count;
-
-  /* List of deferred case vectors.  */
-  struct rtx_def *addr_list;
-
-  /* For OSF.  */
-  const char *some_ld_name;
-
-  /* For TARGET_LD_BUGGY_LDGP.  */
-  struct rtx_def *gp_save_rtx;
+  /* For flag_reorder_blocks_and_partition.  */
+  rtx gp_save_rtx;
 
   /* For VMS condition handlers.  */
-  bool uses_condition_handler;  
+  bool uses_condition_handler;
+
+  /* Linkage entries.  */
+  hash_map<nofree_string_hash, alpha_links *> *links;
 };
 
 /* How to allocate a 'struct machine_function'.  */
@@ -4819,7 +4849,7 @@
 static struct machine_function *
 alpha_init_machine_status (void)
 {
-  return ggc_alloc_cleared_machine_function ();
+  return ggc_cleared_alloc<machine_function> ();
 }
 
 /* Support for frame based VMS condition handlers.  */
@@ -4849,8 +4879,8 @@
 void
 alpha_expand_builtin_establish_vms_condition_handler (rtx target, rtx handler)
 {
-  rtx handler_slot_address
-    = plus_constant (hard_frame_pointer_rtx, VMS_COND_HANDLER_FP_OFFSET);
+  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);
@@ -4898,7 +4928,8 @@
 rtx
 alpha_gp_save_rtx (void)
 {
-  rtx seq, m = cfun->machine->gp_save_rtx;
+  rtx_insn *seq;
+  rtx m = cfun->machine->gp_save_rtx;
 
   if (m == NULL)
     {
@@ -4917,7 +4948,8 @@
 	 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));
+      insert_insn_on_edge (seq,
+			   single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
 
       cfun->machine->gp_save_rtx = m;
     }
@@ -4925,10 +4957,17 @@
   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 top;
+  rtx_insn *top;
 
   if (!has_hard_reg_initial_val (Pmode, REG_RA))
     return (int)df_regs_ever_live_p (REG_RA);
@@ -4937,7 +4976,7 @@
   top = get_insns ();
   pop_topmost_sequence ();
 
-  return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
+  return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL);
 }
 
 
@@ -5053,44 +5092,20 @@
   gcc_unreachable ();
 }
 
-/* Locate some local-dynamic symbol still in use by this function
-   so that we can print its name in some movdi_er_tlsldm pattern.  */
-
-static int
-get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
-{
-  rtx x = *px;
-
-  if (GET_CODE (x) == SYMBOL_REF
-      && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
-    {
-      cfun->machine->some_ld_name = XSTR (x, 0);
-      return 1;
-    }
-
-  return 0;
-}
-
-static const char *
-get_some_local_dynamic_name (void)
-{
-  rtx insn;
-
-  if (cfun->machine->some_ld_name)
-    return cfun->machine->some_ld_name;
-
-  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
-    if (INSN_P (insn)
-	&& for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
-      return cfun->machine->some_ld_name;
-
-  gcc_unreachable ();
-}
-
-/* Print an operand.  Recognize special options, documented below.  */
-
-void
-print_operand (FILE *file, rtx x, int code)
+/* 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;
 
@@ -5102,27 +5117,34 @@
       break;
 
     case '&':
-      assemble_name (file, get_some_local_dynamic_name ());
+      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, (TARGET_AS_SLASH_BEFORE_SUFFIX ? "/%s%s" : "%s%s"),
-		   (trap ? trap : ""), (round ? round : ""));
+	  fprintf (file, "/%s%s", (trap ? trap : ""), (round ? round : ""));
 	break;
       }
 
     case ',':
-      /* Generates single precision instruction suffix.  */
+      /* 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 instruction suffix.  */
+      /* Generates double precision suffix for floating point
+	 instructions (t for IEEE, g for VAX).  */
       fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
       break;
 
@@ -5138,13 +5160,6 @@
       fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
       break;
 
-    case 'H':
-      if (GET_CODE (x) == HIGH)
-	output_addr_const (file, XEXP (x, 0));
-      else
-	output_operand_lossage ("invalid %%H value");
-      break;
-
     case 'J':
       {
 	const char *lituse;
@@ -5219,7 +5234,7 @@
       if (!CONST_INT_P (x))
 	output_operand_lossage ("invalid %%P value");
 
-      fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
+      fprintf (file, HOST_WIDE_INT_PRINT_DEC, HOST_WIDE_INT_1 << INTVAL (x));
       break;
 
     case 'h':
@@ -5241,27 +5256,7 @@
 
     case 'm':
       /* Write mask for ZAP insn.  */
-      if (GET_CODE (x) == CONST_DOUBLE)
-	{
-	  HOST_WIDE_INT mask = 0;
-	  HOST_WIDE_INT value;
-
-	  value = CONST_DOUBLE_LOW (x);
-	  for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
-	       i++, value >>= 8)
-	    if (value & 0xff)
-	      mask |= (1 << i);
-
-	  value = CONST_DOUBLE_HIGH (x);
-	  for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
-	       i++, value >>= 8)
-	    if (value & 0xff)
-	      mask |= (1 << (i + sizeof (int)));
-
-	  fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
-	}
-
-      else if (CONST_INT_P (x))
+      if (CONST_INT_P (x))
 	{
 	  HOST_WIDE_INT mask = 0, value = INTVAL (x);
 
@@ -5277,9 +5272,7 @@
 
     case 'M':
       /* 'b', 'w', 'l', or 'q' as the value of the constant.  */
-      if (!CONST_INT_P (x)
-	  || (INTVAL (x) != 8 && INTVAL (x) != 16
-	      && INTVAL (x) != 32 && INTVAL (x) != 64))
+      if (!mode_width_operand (x, VOIDmode))
 	output_operand_lossage ("invalid %%M value");
 
       fprintf (file, "%s",
@@ -5316,55 +5309,18 @@
 	      break;
 	    }
 	}
-      else if (HOST_BITS_PER_WIDE_INT == 32
-	       && GET_CODE (x) == CONST_DOUBLE
-	       && CONST_DOUBLE_LOW (x) == 0xffffffff
-	       && CONST_DOUBLE_HIGH (x) == 0)
-	{
-	  fputc ('l', file);
-	  break;
-	}
+
       output_operand_lossage ("invalid %%U value");
       break;
 
     case 's':
-      /* Write the constant value divided by 8 for little-endian mode or
-	 (56 - value) / 8 for big-endian mode.  */
-
+      /* Write the constant value divided by 8.  */
       if (!CONST_INT_P (x)
-	  || (unsigned HOST_WIDE_INT) INTVAL (x) >= (WORDS_BIG_ENDIAN
-						     ? 56
-						     : 64)
+	  || (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
 	  || (INTVAL (x) & 7) != 0)
 	output_operand_lossage ("invalid %%s value");
 
-      fprintf (file, HOST_WIDE_INT_PRINT_DEC,
-	       WORDS_BIG_ENDIAN
-	       ? (56 - INTVAL (x)) / 8
-	       : INTVAL (x) / 8);
-      break;
-
-    case 'S':
-      /* Same, except compute (64 - c) / 8 */
-
-      if (!CONST_INT_P (x)
-	  && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
-	  && (INTVAL (x) & 7) != 8)
-	output_operand_lossage ("invalid %%s value");
-
-      fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
-      break;
-
-    case 't':
-      {
-        /* On Unicos/Mk systems: use a DEX expression if the symbol
-	   clashes with a register name.  */
-	int dex = unicosmk_need_dex (x);
-	if (dex)
-	  fprintf (file, "DEX(%d)", dex);
-	else
-	  output_addr_const (file, x);
-      }
+      fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
       break;
 
     case 'C': case 'D': case 'c': case 'd':
@@ -5425,7 +5381,7 @@
       if (REG_P (x))
 	fprintf (file, "%s", reg_names[REGNO (x)]);
       else if (MEM_P (x))
-	output_address (XEXP (x, 0));
+	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))
@@ -5448,8 +5404,10 @@
     }
 }
 
-void
-print_operand_address (FILE *file, rtx addr)
+/* 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;
@@ -5533,22 +5491,23 @@
       offset = INTVAL (addr);
       break;
 
-#if TARGET_ABI_OPEN_VMS
     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;
-    
-#endif
+
     default:
-      gcc_unreachable ();
+      output_operand_lossage ("invalid operand address");
+      return;
     }
 
   fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
@@ -5587,7 +5546,9 @@
 	 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 (0xffff0fff0000fff0), NULL);
+      word1 = expand_and (DImode, word1,
+			  GEN_INT (HOST_WIDE_INT_C (0xffff0fff0000fff0)),
+			  NULL);
     }
   else
     {
@@ -5598,8 +5559,8 @@
 	    nop
 	 We don't bother setting the HINT field of the jump; the nop
 	 is merely there for padding.  */
-      word1 = GEN_INT (0xa77b0010a43b0018);
-      word2 = GEN_INT (0x47ff041f6bfb0000);
+      word1 = GEN_INT (HOST_WIDE_INT_C (0xa77b0010a43b0018));
+      word2 = GEN_INT (HOST_WIDE_INT_C (0x47ff041f6bfb0000));
     }
 
   /* Store the first two words, as computed above.  */
@@ -5614,12 +5575,12 @@
   mem = adjust_address (m_tramp, Pmode, 24);
   emit_move_insn (mem, chain_value);
 
-  if (!TARGET_ABI_OPEN_VMS)
+  if (TARGET_ABI_OSF)
     {
       emit_insn (gen_imb ());
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
       emit_library_call (init_one_libfunc ("__enable_execute_stack"),
-			 LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
+			 LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
 #endif
     }
 }
@@ -5641,9 +5602,10 @@
    and the rest are pushed.  */
 
 static rtx
-alpha_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+alpha_function_arg (cumulative_args_t cum_v, machine_mode mode,
 		    const_tree type, bool named ATTRIBUTE_UNUSED)
 {
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   int basereg;
   int num_args;
 
@@ -5652,11 +5614,9 @@
     basereg = 16;
   else
     {
-#ifdef ENABLE_CHECKING
       /* With alpha_split_complex_arg, we shouldn't see any raw complex
 	 values here.  */
-      gcc_assert (!COMPLEX_MODE_P (mode));
-#endif
+      gcc_checking_assert (!COMPLEX_MODE_P (mode));
 
       /* Set up defaults for FP operands passed in FP registers, and
 	 integral operands passed in integer registers.  */
@@ -5702,11 +5662,12 @@
    (TYPE is null for libcalls where that information may not be available.)  */
 
 static void
-alpha_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+alpha_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
 			    const_tree type, bool named ATTRIBUTE_UNUSED)
 {
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   bool onstack = targetm.calls.must_pass_in_stack (mode, type);
-  int increment = onstack ? 6 : ALPHA_ARG_SIZE (mode, type, named);
+  int increment = onstack ? 6 : ALPHA_ARG_SIZE (mode, type);
 
 #if TARGET_ABI_OSF
   *cum += increment;
@@ -5718,21 +5679,20 @@
 }
 
 static int
-alpha_arg_partial_bytes (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
-			 enum machine_mode mode ATTRIBUTE_UNUSED,
+alpha_arg_partial_bytes (cumulative_args_t cum_v,
+			 machine_mode mode ATTRIBUTE_UNUSED,
 			 tree type ATTRIBUTE_UNUSED,
 			 bool named ATTRIBUTE_UNUSED)
 {
   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 (mode, type, named))
+      && 6 < cum->num_args + ALPHA_ARG_SIZE (mode, type))
     words = 6 - cum->num_args;
-#elif TARGET_ABI_UNICOSMK
-  /* Never any split arguments.  */
 #elif TARGET_ABI_OSF
-  if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (mode, type, named))
+  if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (mode, type))
     words = 6 - *cum;
 #else
 #error Unhandled ABI
@@ -5747,7 +5707,7 @@
 static bool
 alpha_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
 {
-  enum machine_mode mode = VOIDmode;
+  machine_mode mode = VOIDmode;
   int size;
 
   if (type)
@@ -5800,11 +5760,32 @@
 /* Return true if TYPE should be passed by invisible reference.  */
 
 static bool
-alpha_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
-			 enum machine_mode mode,
+alpha_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED,
+			 machine_mode mode,
 			 const_tree type ATTRIBUTE_UNUSED,
-			 bool named ATTRIBUTE_UNUSED)
-{
+			 bool named)
+{
+  /* 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 (mode == SFmode || mode == SCmode)
+    return !named;
+
   return mode == TFmode || mode == TCmode;
 }
 
@@ -5816,9 +5797,9 @@
    On Alpha the value is found in $0 for integer functions and
    $f0 for floating-point functions.  */
 
-rtx
-function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
-		enum machine_mode mode)
+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;
@@ -5849,7 +5830,7 @@
 
     case MODE_COMPLEX_FLOAT:
       {
-	enum machine_mode cmode = GET_MODE_INNER (mode);
+	machine_mode cmode = GET_MODE_INNER (mode);
 
 	return gen_rtx_PARALLEL
 	  (VOIDmode,
@@ -5873,6 +5854,33 @@
   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.  */
 
@@ -5887,7 +5895,7 @@
 {
   tree base, ofs, space, record, type_decl;
 
-  if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
+  if (TARGET_ABI_OPEN_VMS)
     return ptr_type_node;
 
   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
@@ -5910,10 +5918,6 @@
 		    integer_type_node);
   DECL_FIELD_CONTEXT (ofs) = record;
   DECL_CHAIN (ofs) = space;
-  /* ??? This is a hack, __offset is marked volatile to prevent
-     DCE that confuses stdarg optimization and results in
-     gcc.c-torture/execute/stdarg-1.c failure.  See PR 41089.  */
-  TREE_THIS_VOLATILE (ofs) = 1;
 
   base = build_decl (BUILTINS_LOCATION,
 		     FIELD_DECL, get_identifier ("__base"),
@@ -5932,10 +5936,10 @@
 /* Helper function for alpha_stdarg_optimize_hook.  Skip over casts
    and constant additions.  */
 
-static gimple
+static gimple *
 va_list_skip_additions (tree lhs)
 {
-  gimple stmt;
+  gimple  *stmt;
 
   for (;;)
     {
@@ -5956,7 +5960,7 @@
       if (!CONVERT_EXPR_CODE_P (code)
 	  && ((code != PLUS_EXPR && code != POINTER_PLUS_EXPR)
 	      || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST
-	      || !host_integerp (gimple_assign_rhs2 (stmt), 1)))
+	      || !tree_fits_uhwi_p (gimple_assign_rhs2 (stmt))))
 	return stmt;
 
       lhs = gimple_assign_rhs1 (stmt);
@@ -5982,11 +5986,11 @@
    current statement.  */
 
 static bool
-alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
+alpha_stdarg_optimize_hook (struct stdarg_info *si, const gimple *stmt)
 {
   tree base, offset, rhs;
   int offset_arg = 1;
-  gimple base_stmt;
+  gimple *base_stmt;
 
   if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
       != GIMPLE_SINGLE_RHS)
@@ -6037,19 +6041,19 @@
 
   base = get_base_address (base);
   if (TREE_CODE (base) != VAR_DECL
-      || !bitmap_bit_p (si->va_list_vars, DECL_UID (base)))
+      || !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);
+      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;
+	  gimple *arg1_stmt, *arg2_stmt;
 	  tree arg1, arg2;
 	  enum tree_code code1, code2;
 
@@ -6074,18 +6078,16 @@
 	  else if (code2 == COMPONENT_REF
 		   && (code1 == MINUS_EXPR || code1 == PLUS_EXPR))
 	    {
-	      gimple tem = arg1_stmt;
+	      std::swap (arg1_stmt, arg2_stmt);
 	      code2 = code1;
-	      arg1_stmt = arg2_stmt;
-	      arg2_stmt = tem;
 	    }
 	  else
 	    goto escapes;
 
-	  if (!host_integerp (gimple_assign_rhs2 (arg2_stmt), 0))
+	  if (!tree_fits_shwi_p (gimple_assign_rhs2 (arg2_stmt)))
 	    goto escapes;
 
-	  sub = tree_low_cst (gimple_assign_rhs2 (arg2_stmt), 0);
+	  sub = tree_to_shwi (gimple_assign_rhs2 (arg2_stmt));
 	  if (code2 == MINUS_EXPR)
 	    sub = -sub;
 	  if (sub < -48 || sub > -32)
@@ -6138,29 +6140,16 @@
    variable number of arguments.  */
 
 static void
-alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+alpha_setup_incoming_varargs (cumulative_args_t pcum, machine_mode mode,
 			      tree type, int *pretend_size, int no_rtl)
 {
-  CUMULATIVE_ARGS cum = *pcum;
+  CUMULATIVE_ARGS cum = *get_cumulative_args (pcum);
 
   /* Skip the current argument.  */
-  targetm.calls.function_arg_advance (&cum, mode, type, true);
-
-#if TARGET_ABI_UNICOSMK
-  /* On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
-     arguments on the stack. Unfortunately, it doesn't always store the first
-     one (i.e. the one that arrives in $16 or $f16). This is not a problem
-     with stdargs as we always have at least one named argument there.  */
-  if (cum.num_reg_words < 6)
-    {
-      if (!no_rtl)
-	{
-	  emit_insn (gen_umk_mismatch_args (GEN_INT (cum.num_reg_words)));
-	  emit_insn (gen_arg_home_umk ());
-	}
-      *pretend_size = 0;
-    }
-#elif TARGET_ABI_OPEN_VMS
+  targetm.calls.function_arg_advance (pack_cumulative_args (&cum), mode, type,
+				      true);
+
+#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.
@@ -6211,7 +6200,7 @@
       if (cfun->va_list_fpr_size & 1)
 	{
 	  tmp = gen_rtx_MEM (BLKmode,
-			     plus_constant (virtual_incoming_args_rtx,
+			     plus_constant (Pmode, virtual_incoming_args_rtx,
 					    (cum + 6) * UNITS_PER_WORD));
 	  MEM_NOTRAP_P (tmp) = 1;
 	  set_mem_alias_set (tmp, set);
@@ -6221,7 +6210,7 @@
       if (cfun->va_list_fpr_size & 2)
 	{
 	  tmp = gen_rtx_MEM (BLKmode,
-			     plus_constant (virtual_incoming_args_rtx,
+			     plus_constant (Pmode, virtual_incoming_args_rtx,
 					    cum * UNITS_PER_WORD));
 	  MEM_NOTRAP_P (tmp) = 1;
 	  set_mem_alias_set (tmp, set);
@@ -6241,9 +6230,6 @@
   if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
     return;
 
-  if (TARGET_ABI_UNICOSMK)
-    std_expand_builtin_va_start (valist, nextarg);
-
   /* 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,
@@ -6264,8 +6250,7 @@
   if (TARGET_ABI_OPEN_VMS)
     {
       t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
-      t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
-		 size_int (offset + NUM_ARGS * UNITS_PER_WORD));
+      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);
@@ -6281,8 +6266,7 @@
 			     valist, offset_field, NULL_TREE);
 
       t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
-      t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
-		  size_int (offset));
+      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);
@@ -6343,8 +6327,7 @@
     }
 
   /* Build the final address and force that value into a temporary.  */
-  addr = build2 (POINTER_PLUS_EXPR, ptr_type, fold_convert (ptr_type, base),
-	         fold_convert (sizetype, addend));
+  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);
@@ -6373,7 +6356,7 @@
   tree offset_field, base_field, offset, base, t, r;
   bool indirect;
 
-  if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
+  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);
@@ -6388,7 +6371,7 @@
      offset field so that it's the proper width for pointer arithmetic.  */
   base = get_formal_tmp_var (base_field, pre_p);
 
-  t = fold_convert (lang_hooks.types.type_for_size (64, 0), offset_field);
+  t = fold_convert (build_nonstandard_integer_type (64, 0), offset_field);
   offset = get_initialized_tmp_var (t, pre_p, NULL);
 
   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
@@ -6441,8 +6424,6 @@
   ALPHA_BUILTIN_AMASK,
   ALPHA_BUILTIN_IMPLVER,
   ALPHA_BUILTIN_RPCC,
-  ALPHA_BUILTIN_THREAD_POINTER,
-  ALPHA_BUILTIN_SET_THREAD_POINTER,
   ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
   ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER,
 
@@ -6471,35 +6452,33 @@
 
 static enum insn_code const code_for_builtin[ALPHA_BUILTIN_max] = {
   CODE_FOR_builtin_cmpbge,
-  CODE_FOR_builtin_extbl,
-  CODE_FOR_builtin_extwl,
-  CODE_FOR_builtin_extll,
-  CODE_FOR_builtin_extql,
-  CODE_FOR_builtin_extwh,
-  CODE_FOR_builtin_extlh,
-  CODE_FOR_builtin_extqh,
+  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_builtin_insql,
-  CODE_FOR_builtin_inswh,
-  CODE_FOR_builtin_inslh,
-  CODE_FOR_builtin_insqh,
-  CODE_FOR_builtin_mskbl,
-  CODE_FOR_builtin_mskwl,
-  CODE_FOR_builtin_mskll,
-  CODE_FOR_builtin_mskql,
-  CODE_FOR_builtin_mskwh,
-  CODE_FOR_builtin_msklh,
-  CODE_FOR_builtin_mskqh,
+  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_load_tp,
-  CODE_FOR_set_tp,
   CODE_FOR_builtin_establish_vms_condition_handler,
   CODE_FOR_builtin_revert_vms_condition_handler,
 
@@ -6585,6 +6564,7 @@
   { "__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;
@@ -6638,39 +6618,23 @@
 static void
 alpha_init_builtins (void)
 {
-  tree dimode_integer_type_node;
   tree ftype;
 
-  dimode_integer_type_node = lang_hooks.types.type_for_mode (DImode, 0);
-
-  /* Fwrite on VMS is non-standard.  */
-#if TARGET_ABI_OPEN_VMS
-  implicit_built_in_decls[(int) BUILT_IN_FWRITE] = NULL_TREE;
-  implicit_built_in_decls[(int) BUILT_IN_FWRITE_UNLOCKED] = NULL_TREE;
-#endif
-
-  ftype = build_function_type (dimode_integer_type_node, void_list_node);
-  alpha_add_builtins (zero_arg_builtins, ARRAY_SIZE (zero_arg_builtins),
-		      ftype);
-
-  ftype = build_function_type_list (dimode_integer_type_node,
-				    dimode_integer_type_node, NULL_TREE);
-  alpha_add_builtins (one_arg_builtins, ARRAY_SIZE (one_arg_builtins),
-		      ftype);
-
-  ftype = build_function_type_list (dimode_integer_type_node,
-				    dimode_integer_type_node,
-				    dimode_integer_type_node, NULL_TREE);
-  alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins),
-		      ftype);
-
-  ftype = build_function_type (ptr_type_node, void_list_node);
-  alpha_builtin_function ("__builtin_thread_pointer", ftype,
-			  ALPHA_BUILTIN_THREAD_POINTER, ECF_NOTHROW);
-
-  ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
-  alpha_builtin_function ("__builtin_set_thread_pointer", ftype,
-			  ALPHA_BUILTIN_SET_THREAD_POINTER, ECF_NOTHROW);
+  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)
     {
@@ -6685,12 +6649,9 @@
 					NULL_TREE);
       alpha_builtin_function ("__builtin_revert_vms_condition_handler", ftype,
 			      ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER, 0);
-    }
-
-  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);
+
+      vms_patch_builtins ();
+    }
 }
 
 /* Expand an expression EXP that calls a built-in function,
@@ -6702,7 +6663,7 @@
 static rtx
 alpha_expand_builtin (tree exp, rtx target,
 		      rtx subtarget ATTRIBUTE_UNUSED,
-		      enum machine_mode mode ATTRIBUTE_UNUSED,
+		      machine_mode mode ATTRIBUTE_UNUSED,
 		      int ignore ATTRIBUTE_UNUSED)
 {
 #define MAX_ARGS 2
@@ -6745,7 +6706,7 @@
 
   if (nonvoid)
     {
-      enum machine_mode tmode = insn_data[icode].operand[0].mode;
+      machine_mode tmode = insn_data[icode].operand[0].mode;
       if (!target
 	  || GET_MODE (target) != tmode
 	  || !(*insn_data[icode].operand[0].predicate) (target, tmode))
@@ -6779,13 +6740,6 @@
     return const0_rtx;
 }
 
-
-/* Several bits below assume HWI >= 64 bits.  This should be enforced
-   by config.gcc.  */
-#if HOST_BITS_PER_WIDE_INT < 64
-# error "HOST_WIDE_INT too small"
-#endif
-
 /* 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.  */
@@ -6803,10 +6757,10 @@
 	  if (c0 >= c1)
 	    val |= 1 << i;
 	}
-      return build_int_cst (long_integer_type_node, val);
+      return build_int_cst (alpha_dimode_u, val);
     }
   else if (op_const == 2 && opint[1] == 0)
-    return build_int_cst (long_integer_type_node, 0xff);
+    return build_int_cst (alpha_dimode_u, 0xff);
   return NULL;
 }
 
@@ -6833,14 +6787,14 @@
 	  mask |= (unsigned HOST_WIDE_INT)0xff << (i * 8);
 
       if (op_const & 1)
-	return build_int_cst (long_integer_type_node, opint[0] & mask);
+	return build_int_cst (alpha_dimode_u, opint[0] & mask);
 
       if (op)
-	return fold_build2 (BIT_AND_EXPR, long_integer_type_node, op[0],
-			    build_int_cst (long_integer_type_node, mask));
+	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 (long_integer_type_node, 0);
+    return build_int_cst (alpha_dimode_u, 0);
   return NULL;
 }
 
@@ -6859,9 +6813,7 @@
       unsigned HOST_WIDE_INT loc;
 
       loc = opint[1] & 7;
-      if (BYTES_BIG_ENDIAN)
-        loc ^= 7;
-      loc *= 8;
+      loc *= BITS_PER_UNIT;
 
       if (loc != 0)
 	{
@@ -6892,7 +6844,7 @@
 			  bool is_high)
 {
   if ((op_const & 1) && opint[0] == 0)
-    return build_int_cst (long_integer_type_node, 0);
+    return build_int_cst (alpha_dimode_u, 0);
 
   if (op_const & 2)
     {
@@ -6900,8 +6852,6 @@
       tree *zap_op = NULL;
 
       loc = opint[1] & 7;
-      if (BYTES_BIG_ENDIAN)
-        loc ^= 7;
       bytemask <<= loc;
 
       temp = opint[0];
@@ -6941,8 +6891,6 @@
       unsigned HOST_WIDE_INT loc;
 
       loc = opint[1] & 7;
-      if (BYTES_BIG_ENDIAN)
-        loc ^= 7;
       bytemask <<= loc;
 
       if (is_high)
@@ -6955,43 +6903,12 @@
 }
 
 static tree
-alpha_fold_builtin_umulh (unsigned HOST_WIDE_INT opint[], long op_const)
-{
-  switch (op_const)
-    {
-    case 3:
-      {
-	unsigned HOST_WIDE_INT l;
-	HOST_WIDE_INT h;
-
-	mul_double (opint[0], 0, opint[1], 0, &l, &h);
-
-#if HOST_BITS_PER_WIDE_INT > 64
-# error fixme
-#endif
-
-	return build_int_cst (long_integer_type_node, h);
-      }
-
-    case 1:
-      opint[1] = opint[0];
-      /* FALLTHRU */
-    case 2:
-      /* Note that (X*1) >> 64 == 0.  */
-      if (opint[1] == 0 || opint[1] == 1)
-	return build_int_cst (long_integer_type_node, 0);
-      break;
-    }
-  return NULL;
-}
-
-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, long_integer_type_node, val);
+  return fold_build1 (VIEW_CONVERT_EXPR, alpha_dimode_u, val);
 }
 
 static tree
@@ -7013,7 +6930,7 @@
 	temp += b - a;
     }
 
-  return build_int_cst (long_integer_type_node, temp);
+  return build_int_cst (alpha_dimode_u, temp);
 }
 
 static tree
@@ -7027,7 +6944,7 @@
   temp = opint[0] & 0xff;
   temp |= (opint[0] >> 24) & 0xff00;
 
-  return build_int_cst (long_integer_type_node, temp);
+  return build_int_cst (alpha_dimode_u, temp);
 }
 
 static tree
@@ -7043,7 +6960,7 @@
   temp |= (opint[0] >> 16) & 0xff0000;
   temp |= (opint[0] >> 24) & 0xff000000;
 
-  return build_int_cst (long_integer_type_node, temp);
+  return build_int_cst (alpha_dimode_u, temp);
 }
 
 static tree
@@ -7057,7 +6974,7 @@
   temp = opint[0] & 0xff;
   temp |= (opint[0] & 0xff00) << 24;
 
-  return build_int_cst (long_integer_type_node, temp);
+  return build_int_cst (alpha_dimode_u, temp);
 }
 
 static tree
@@ -7073,7 +6990,7 @@
   temp |= (opint[0] & 0x00ff0000) << 16;
   temp |= (opint[0] & 0xff000000) << 24;
 
-  return build_int_cst (long_integer_type_node, temp);
+  return build_int_cst (alpha_dimode_u, temp);
 }
 
 static tree
@@ -7089,7 +7006,7 @@
   else
     temp = exact_log2 (opint[0] & -opint[0]);
 
-  return build_int_cst (long_integer_type_node, temp);
+  return build_int_cst (alpha_dimode_u, temp);
 }
 
 static tree
@@ -7105,7 +7022,7 @@
   else
     temp = 64 - floor_log2 (opint[0]) - 1;
 
-  return build_int_cst (long_integer_type_node, temp);
+  return build_int_cst (alpha_dimode_u, temp);
 }
 
 static tree
@@ -7121,7 +7038,7 @@
   while (op)
     temp++, op &= op - 1;
 
-  return build_int_cst (long_integer_type_node, temp);
+  return build_int_cst (alpha_dimode_u, temp);
 }
 
 /* Fold one of our builtin functions.  */
@@ -7134,7 +7051,7 @@
   long op_const = 0;
   int i;
 
-  if (n_args >= MAX_ARGS)
+  if (n_args > MAX_ARGS)
     return NULL;
 
   for (i = 0; i < n_args; i++)
@@ -7201,9 +7118,6 @@
     case ALPHA_BUILTIN_MSKQH:
       return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, true);
 
-    case ALPHA_BUILTIN_UMULH:
-      return alpha_fold_builtin_umulh (opint, op_const);
-
     case ALPHA_BUILTIN_ZAP:
       opint[1] ^= 0xff;
       /* FALLTHRU */
@@ -7248,13 +7162,51 @@
     case ALPHA_BUILTIN_AMASK:
     case ALPHA_BUILTIN_IMPLVER:
     case ALPHA_BUILTIN_RPCC:
-    case ALPHA_BUILTIN_THREAD_POINTER:
-    case ALPHA_BUILTIN_SET_THREAD_POINTER:
       /* 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_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.  */
@@ -7306,8 +7258,7 @@
   /* One for every register we have to save.  */
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     if (! fixed_regs[i] && ! call_used_regs[i]
-	&& df_regs_ever_live_p (i) && i != REG_RA
-	&& (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
+	&& df_regs_ever_live_p (i) && i != REG_RA)
       {
 	if (i < 32)
 	  imask |= (1UL << i);
@@ -7346,40 +7297,12 @@
 
   alpha_sa_mask (&mask[0], &mask[1]);
 
-  if (TARGET_ABI_UNICOSMK)
-    {
-      if (mask[0] || mask[1])
-	sa_size = 14;
-    }
-  else
-    {
-      for (j = 0; j < 2; ++j)
-	for (i = 0; i < 32; ++i)
-	  if ((mask[j] >> i) & 1)
-	    sa_size++;
-    }
-
-  if (TARGET_ABI_UNICOSMK)
-    {
-      /* We might not need to generate a frame if we don't make any calls
-	 (including calls to __T3E_MISMATCH if this is a vararg function),
-	 don't have any local variables which require stack slots, don't
-	 use alloca and have not determined that we need a frame for other
-	 reasons.  */
-
-      alpha_procedure_type
-	= (sa_size || get_frame_size() != 0
-	   || crtl->outgoing_args_size
-	   || cfun->stdarg || cfun->calls_alloca
-	   || frame_pointer_needed)
-	  ? PT_STACK : PT_REGISTER;
-
-      /* Always reserve space for saving callee-saved registers if we
-	 need a frame as required by the calling convention.  */
-      if (alpha_procedure_type == PT_STACK)
-        sa_size = 14;
-    }
-  else if (TARGET_ABI_OPEN_VMS)
+  for (j = 0; j < 2; ++j)
+    for (i = 0; i < 32; ++i)
+      if ((mask[j] >> i) & 1)
+	sa_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
@@ -7582,9 +7505,10 @@
 
 static const struct attribute_spec vms_attribute_table[] =
 {
-  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-  { COMMON_OBJECT,   0, 1, true,  false, false, common_object_handler },
-  { NULL,            0, 0, false, false, false, NULL }
+  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
+       affects_type_identity } */
+  { COMMON_OBJECT,   0, 1, true,  false, false, common_object_handler, false },
+  { NULL,            0, 0, false, false, false, NULL, false }
 };
 
 void
@@ -7612,22 +7536,23 @@
 
 #endif
 
-static int
-find_lo_sum_using_gp (rtx *px, void *data ATTRIBUTE_UNUSED)
-{
-  return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
-}
-
-int
+bool
 alpha_find_lo_sum_using_gp (rtx insn)
 {
-  return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
+  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;
+  rtx_insn *insn;
 
   /* The GP being variable is an OSF abi thing.  */
   if (! TARGET_ABI_OSF)
@@ -7658,7 +7583,6 @@
 
   for (; insn; insn = NEXT_INSN (insn))
     if (NONDEBUG_INSN_P (insn)
-	&& ! JUMP_TABLE_DATA_P (insn)
 	&& GET_CODE (PATTERN (insn)) != USE
 	&& GET_CODE (PATTERN (insn)) != CLOBBER
 	&& get_attr_usegp (insn))
@@ -7671,16 +7595,16 @@
 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
    sequences.  */
 
-static rtx
+static rtx_insn *
 set_frame_related_p (void)
 {
-  rtx seq = get_insns ();
-  rtx insn;
+  rtx_insn *seq = get_insns ();
+  rtx_insn *insn;
 
   end_sequence ();
 
   if (!seq)
-    return NULL_RTX;
+    return NULL;
 
   if (INSN_P (seq))
     {
@@ -7712,11 +7636,11 @@
 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, insn;
-
-  addr = plus_constant (base_reg, base_ofs);
-  mem = gen_rtx_MEM (DImode, addr);
-  set_mem_alias_set (mem, alpha_sr_alias_set);
+  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;
@@ -7725,12 +7649,13 @@
     {
       if (frame_bias)
 	{
-	  addr = plus_constant (stack_pointer_rtx, frame_bias + base_ofs);
+	  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 (VOIDmode, mem, frame_reg));
+		    gen_rtx_SET (mem, frame_reg));
     }
 }
 
@@ -7753,12 +7678,6 @@
 			+ (alpha_procedure_type == PT_STACK ? 8 : 0)
 			+ size
 			+ crtl->args.pretend_args_size);
-  else if (TARGET_ABI_UNICOSMK)
-    /* We have to allocate space for the DSIB if we generate a frame.  */
-    return ALPHA_ROUND (sa_size
-			+ (alpha_procedure_type == PT_STACK ? 48 : 0))
-	   + ALPHA_ROUND (size
-			  + crtl->outgoing_args_size);
   else
     return ALPHA_ROUND (crtl->outgoing_args_size)
 	   + sa_size
@@ -7790,7 +7709,7 @@
   unsigned long imask = 0;
   unsigned long fmask = 0;
   /* Stack space needed for pushing registers clobbered by us.  */
-  HOST_WIDE_INT sa_size;
+  HOST_WIDE_INT sa_size, sa_bias;
   /* Complete stack size needed.  */
   HOST_WIDE_INT frame_size;
   /* Probed stack size; it additionally includes the size of
@@ -7804,7 +7723,7 @@
   sa_size = alpha_sa_size ();
   frame_size = compute_frame_size (get_frame_size (), sa_size);
 
-  if (flag_stack_usage)
+  if (flag_stack_usage_info)
     current_function_static_stack_size = frame_size;
 
   if (TARGET_ABI_OPEN_VMS)
@@ -7829,9 +7748,6 @@
   if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
     emit_insn (gen_prologue_mcount ());
 
-  if (TARGET_ABI_UNICOSMK)
-    unicosmk_gen_dsib (&imask);
-
   /* 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
@@ -7842,8 +7758,8 @@
      Note that we are only allowed to adjust sp once in the prologue.  */
 
   probed_size = frame_size;
-  if (flag_stack_check)
-    probed_size += STACK_CHECK_PROTECT;
+  if (flag_stack_check || flag_stack_clash_protection)
+    probed_size += get_stack_check_protect ();
 
   if (probed_size <= 32768)
     {
@@ -7852,22 +7768,18 @@
 	  int probed;
 
 	  for (probed = 4096; probed < probed_size; probed += 8192)
-	    emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
-						 ? -probed + 64
-						 : -probed)));
+	    emit_insn (gen_probe_stack (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_check || flag_stack_clash_protection)
 	    emit_insn (gen_probe_stack (GEN_INT (-probed_size)));
 	}
 
       if (frame_size != 0)
 	FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
-				    GEN_INT (TARGET_ABI_UNICOSMK
-					     ? -frame_size + 64
-					     : -frame_size))));
+				    GEN_INT (-frame_size))));
     }
   else
     {
@@ -7885,33 +7797,26 @@
       rtx seq;
 
       emit_move_insn (count, GEN_INT (blocks));
-      emit_insn (gen_adddi3 (ptr, stack_pointer_rtx,
-			     GEN_INT (TARGET_ABI_UNICOSMK ? 4096 - 64 : 4096)));
+      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)
-	{
-	  rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
+      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 (TARGET_ABI_WINDOWS_NT || flag_stack_check)
-	{
-	  /* For NT stack unwind (done by 'reverse execution'), it's
-	     not OK to take the result of a loop, even though the value
-	     is already in ptr, so we reload it via a single operation
-	     and subtract it to sp.
-
-	     Same if -fstack-check is specified, because the probed stack
-	     size is not equal to the frame size.
-
-	     Yes, that's correct -- we have to reload the whole constant
-	     into a temporary via ldah+lda then subtract from sp.  */
-
+      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;
@@ -7932,96 +7837,71 @@
          note it looks at instead.  */
       RTX_FRAME_RELATED_P (seq) = 1;
       add_reg_note (seq, REG_FRAME_RELATED_EXPR,
-		    gen_rtx_SET (VOIDmode, stack_pointer_rtx,
-				 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-					       GEN_INT (TARGET_ABI_UNICOSMK
-							? -frame_size + 64
-							: -frame_size))));
-    }
-
-  if (!TARGET_ABI_UNICOSMK)
-    {
-      HOST_WIDE_INT sa_bias = 0;
-
-      /* Cope with very large offsets to the register save area.  */
-      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.  */
-      if (imask & (1UL << REG_RA))
-	{
-	  emit_frame_store (REG_RA, sa_reg, sa_bias, reg_offset);
-	  imask &= ~(1UL << REG_RA);
-	  reg_offset += 8;
-	}
-
-      /* Now save any other registers required to be saved.  */
-      for (i = 0; i < 31; i++)
-	if (imask & (1UL << i))
-	  {
-	    emit_frame_store (i, sa_reg, sa_bias, reg_offset);
-	    reg_offset += 8;
-	  }
-
-      for (i = 0; i < 31; i++)
-	if (fmask & (1UL << i))
-	  {
-	    emit_frame_store (i+32, sa_reg, sa_bias, reg_offset);
-	    reg_offset += 8;
-	  }
-    }
-  else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
-    {
-      /* The standard frame on the T3E includes space for saving registers.
-	 We just have to use it. We don't have to save the return address and
-	 the old frame pointer here - they are saved in the DSIB.  */
-
-      reg_offset = -56;
-      for (i = 9; i < 15; i++)
-	if (imask & (1UL << i))
-	  {
-	    emit_frame_store (i, hard_frame_pointer_rtx, 0, reg_offset);
-	    reg_offset -= 8;
-	  }
-      for (i = 2; i < 10; i++)
-	if (fmask & (1UL << i))
-	  {
-	    emit_frame_store (i+32, hard_frame_pointer_rtx, 0, reg_offset);
-	    reg_offset -= 8;
-	  }
-    }
+		    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.  */
+  if (imask & (1UL << REG_RA))
+    {
+      emit_frame_store (REG_RA, sa_reg, sa_bias, reg_offset);
+      imask &= ~(1UL << REG_RA);
+      reg_offset += 8;
+    }
+
+  /* Now save any other registers required to be saved.  */
+  for (i = 0; i < 31; i++)
+    if (imask & (1UL << i))
+      {
+	emit_frame_store (i, sa_reg, sa_bias, reg_offset);
+	reg_offset += 8;
+      }
+
+  for (i = 0; i < 31; i++)
+    if (fmask & (1UL << i))
+      {
+	emit_frame_store (i+32, sa_reg, sa_bias, reg_offset);
+	reg_offset += 8;
+      }
 
   if (TARGET_ABI_OPEN_VMS)
     {
       /* Register frame procedures save the fp.  */
       if (alpha_procedure_type == PT_REGISTER)
 	{
-	  rtx insn = emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
-				     hard_frame_pointer_rtx);
+	  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;
 	}
@@ -8037,10 +7917,10 @@
       /* If we have to allocate space for outgoing args, do it now.  */
       if (crtl->outgoing_args_size != 0)
 	{
-	  rtx seq
+	  rtx_insn *seq
 	    = emit_move_insn (stack_pointer_rtx,
 			      plus_constant
-			      (hard_frame_pointer_rtx,
+			      (Pmode, hard_frame_pointer_rtx,
 			       - (ALPHA_ROUND
 				  (crtl->outgoing_args_size))));
 
@@ -8062,7 +7942,7 @@
 	  RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
 	}
     }
-  else if (!TARGET_ABI_UNICOSMK)
+  else
     {
       /* If we need a frame pointer, set it from the stack pointer.  */
       if (frame_pointer_needed)
@@ -8106,33 +7986,16 @@
   HOST_WIDE_INT sa_size;
   /* Complete stack size needed.  */
   unsigned HOST_WIDE_INT frame_size;
-  /* The maximum debuggable frame size (512 Kbytes using Tru64 as).  */
-  unsigned HOST_WIDE_INT max_frame_size = TARGET_ABI_OSF && !TARGET_GAS
-					  ? 524288
-					  : 1UL << 31;
+  /* The maximum debuggable frame size.  */
+  unsigned HOST_WIDE_INT max_frame_size = 1UL << 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;
 
-  /* Don't emit an extern directive for functions defined in the same file.  */
-  if (TARGET_ABI_UNICOSMK)
-    {
-      tree name_tree;
-      name_tree = get_identifier (fnname);
-      TREE_ASM_WRITTEN (name_tree) = 1;
-    }
-
 #if TARGET_ABI_OPEN_VMS
-  if (vms_debug_main
-      && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0)
-    {
-      targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER);
-      ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname);
-      switch_to_section (text_section);
-      vms_debug_main = NULL;
-    }
+  vms_start_function (fnname);
 #endif
 
   alpha_fnname = fnname;
@@ -8146,30 +8009,8 @@
 
   alpha_sa_mask (&imask, &fmask);
 
-  /* Ecoff can handle multiple .file directives, so put out file and lineno.
-     We have to do that before the .ent directive as we cannot switch
-     files within procedures with native ecoff because line numbers are
-     linked to procedure descriptors.
-     Outputting the lineno helps debugging of one line functions as they
-     would otherwise get no line number at all. Please note that we would
-     like to put out last_linenum from final.c, but it is not accessible.  */
-
-  if (write_symbols == SDB_DEBUG)
-    {
-#ifdef ASM_OUTPUT_SOURCE_FILENAME
-      ASM_OUTPUT_SOURCE_FILENAME (file,
-				  DECL_SOURCE_FILE (current_function_decl));
-#endif
-#ifdef SDB_OUTPUT_SOURCE_LINE
-      if (debug_info_level != DINFO_LEVEL_TERSE)
-        SDB_OUTPUT_SOURCE_LINE (file,
-				DECL_SOURCE_LINE (current_function_decl));
-#endif
-    }
-
   /* Issue function start and label.  */
-  if (TARGET_ABI_OPEN_VMS
-      || (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive))
+  if (TARGET_ABI_OPEN_VMS || !flag_inhibit_size_directive)
     {
       fputs ("\t.ent ", file);
       assemble_name (file, fnname);
@@ -8192,7 +8033,8 @@
    if (TARGET_ABI_OPEN_VMS
        && !TREE_PUBLIC (decl)
        && DECL_CONTEXT (decl)
-       && !TYPE_P (DECL_CONTEXT (decl)))
+       && !TYPE_P (DECL_CONTEXT (decl))
+       && TREE_CODE (DECL_CONTEXT (decl)) != TRANSLATION_UNIT_DECL)
      {
 	strcpy (tramp_label, fnname);
 	strcat (tramp_label, "..tr");
@@ -8205,18 +8047,14 @@
   if (TARGET_ABI_OPEN_VMS)
     strcat (entry_label, "..en");
 
-  /* For public functions, the label must be globalized by appending an
-     additional colon.  */
-  if (TARGET_ABI_UNICOSMK && TREE_PUBLIC (decl))
-    strcat (entry_label, ":");
-
   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_OPEN_VMS && !TARGET_ABI_UNICOSMK && TARGET_IEEE_CONFORMANT
+  if (TARGET_ABI_OSF
+      && TARGET_IEEE_CONFORMANT
       && !flag_inhibit_size_directive)
     {
       /* Set flags in procedure descriptor to request IEEE-conformant
@@ -8232,9 +8070,7 @@
   /* 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_UNICOSMK)
-    ;
-  else if (TARGET_ABI_OPEN_VMS)
+  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,
@@ -8248,9 +8084,7 @@
 	     crtl->args.pretend_args_size);
 
   /* Describe which registers were spilled.  */
-  if (TARGET_ABI_UNICOSMK)
-    ;
-  else if (TARGET_ABI_OPEN_VMS)
+  if (TARGET_ABI_OPEN_VMS)
     {
       if (imask)
         /* ??? Does VMS care if mask contains ra?  The old code didn't
@@ -8289,16 +8123,17 @@
       fprintf (file, "\t.handler_data %d\n", VMS_COND_HANDLER_FP_OFFSET);
     }
 
-  /* Ifdef'ed cause link_section are only available then.  */
+#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);
-  alpha_need_linkage (fnname, 1);
   switch_to_section (text_section);
 #endif
+#endif /* TARGET_ABI_OPEN_VMS */
 }
 
 /* Emit the .prologue note at the scheduled end of the prologue.  */
@@ -8306,12 +8141,8 @@
 static void
 alpha_output_function_end_prologue (FILE *file)
 {
-  if (TARGET_ABI_UNICOSMK)
-    ;
-  else if (TARGET_ABI_OPEN_VMS)
+  if (TARGET_ABI_OPEN_VMS)
     fputs ("\t.prologue\n", file);
-  else if (TARGET_ABI_WINDOWS_NT)
-    fputs ("\t.prologue 0\n", file);
   else if (!flag_inhibit_size_directive)
     fprintf (file, "\t.prologue %d\n",
 	     alpha_function_needs_gp || cfun->is_thunk);
@@ -8354,8 +8185,9 @@
   alpha_sa_mask (&imask, &fmask);
 
   fp_is_frame_pointer
-    = ((TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
-       || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
+    = (TARGET_ABI_OPEN_VMS
+       ? alpha_procedure_type == PT_STACK
+       : frame_pointer_needed);
   fp_offset = 0;
   sa_reg = stack_pointer_rtx;
 
@@ -8364,12 +8196,12 @@
   else
     eh_ofs = NULL_RTX;
 
-  if (!TARGET_ABI_UNICOSMK && sa_size)
+  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)
-	  || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
+      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.  */
@@ -8384,16 +8216,14 @@
 	    bias = reg_offset, reg_offset = 0;
 
 	  sa_reg = gen_rtx_REG (DImode, 22);
-	  sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
+	  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.  */
 
-      mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
-      if (! eh_ofs)
-        set_mem_alias_set (mem, alpha_sr_alias_set);
+      mem = gen_frame_mem (DImode, plus_constant (Pmode, sa_reg, reg_offset));
       reg = gen_rtx_REG (DImode, REG_RA);
       emit_move_insn (reg, mem);
       cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
@@ -8408,8 +8238,9 @@
 	      fp_offset = reg_offset;
 	    else
 	      {
-		mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
-		set_mem_alias_set (mem, alpha_sr_alias_set);
+		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,
@@ -8421,51 +8252,14 @@
       for (i = 0; i < 31; ++i)
 	if (fmask & (1UL << i))
 	  {
-	    mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
-	    set_mem_alias_set (mem, alpha_sr_alias_set);
+	    mem = gen_frame_mem (DFmode, plus_constant (Pmode, sa_reg,
+						        reg_offset));
 	    reg = gen_rtx_REG (DFmode, i+32);
 	    emit_move_insn (reg, mem);
 	    cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
 	    reg_offset += 8;
 	  }
     }
-  else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
-    {
-      /* Restore callee-saved general-purpose registers.  */
-
-      reg_offset = -56;
-
-      for (i = 9; i < 15; i++)
-	if (imask & (1UL << i))
-	  {
-	    mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
-						     reg_offset));
-	    set_mem_alias_set (mem, alpha_sr_alias_set);
-	    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;
-	  }
-
-      for (i = 2; i < 10; i++)
-	if (fmask & (1UL << i))
-	  {
-	    mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
-						     reg_offset));
-	    set_mem_alias_set (mem, alpha_sr_alias_set);
-	    reg = gen_rtx_REG (DFmode, i+32);
-	    emit_move_insn (reg, mem);
-	    cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
-	    reg_offset -= 8;
-	  }
-
-      /* Restore the return address from the DSIB.  */
-      mem = gen_rtx_MEM (DImode, plus_constant (hard_frame_pointer_rtx, -8));
-      set_mem_alias_set (mem, alpha_sr_alias_set);
-      reg = gen_rtx_REG (DImode, REG_RA);
-      emit_move_insn (reg, mem);
-      cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
-    }
 
   if (frame_size || eh_ofs)
     {
@@ -8481,20 +8275,13 @@
       /* 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
-	  && ! (TARGET_ABI_UNICOSMK && cfun->calls_alloca))
+      if (frame_size < 32768 && !cfun->calls_alloca)
 	sp_adj2 = GEN_INT (frame_size);
-      else if (TARGET_ABI_UNICOSMK)
-	{
-	  sp_adj1 = gen_rtx_REG (DImode, 23);
-	  emit_move_insn (sp_adj1, hard_frame_pointer_rtx);
-	  sp_adj2 = const0_rtx;
-	}
       else if (frame_size < 0x40007fffL)
 	{
 	  int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
 
-	  sp_adj2 = plus_constant (sp_adj1, frame_size - low);
+	  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
@@ -8512,8 +8299,7 @@
 	    {
 	      /* 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,
-						   -(frame_size < 0));
+	      sp_adj2 = alpha_emit_set_long_const (tmp, frame_size);
 	      gcc_assert (sp_adj2);
 	    }
 	}
@@ -8521,21 +8307,11 @@
       /* From now on, things must be in order.  So emit blockages.  */
 
       /* Restore the frame pointer.  */
-      if (TARGET_ABI_UNICOSMK)
+      if (fp_is_frame_pointer)
 	{
 	  emit_insn (gen_blockage ());
-	  mem = gen_rtx_MEM (DImode,
-			     plus_constant (hard_frame_pointer_rtx, -16));
-	  set_mem_alias_set (mem, alpha_sr_alias_set);
-	  emit_move_insn (hard_frame_pointer_rtx, mem);
-	  cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
-					 hard_frame_pointer_rtx, cfa_restores);
-	}
-      else if (fp_is_frame_pointer)
-	{
-	  emit_insn (gen_blockage ());
-	  mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, fp_offset));
-	  set_mem_alias_set (mem, alpha_sr_alias_set);
+	  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);
@@ -8572,14 +8348,6 @@
 	  add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
 	  RTX_FRAME_RELATED_P (insn) = 1;
         }
-      else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
-	{
-	  /* Decrement the frame pointer if the function does not have a
-	     frame.  */
-	  emit_insn (gen_blockage ());
-	  emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
-				 hard_frame_pointer_rtx, constm1_rtx));
-        }
     }
 }
 
@@ -8588,7 +8356,7 @@
 void
 alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
 {
-  rtx insn;
+  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,
@@ -8600,34 +8368,20 @@
     output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL);
 
 #if TARGET_ABI_OPEN_VMS
-  alpha_write_linkage (file, fnname, decl);
+  /* Write the linkage entries.  */
+  alpha_write_linkage (file, fnname);
 #endif
 
   /* End the function.  */
-  if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
+  if (TARGET_ABI_OPEN_VMS
+      || !flag_inhibit_size_directive)
     {
       fputs ("\t.end ", file);
       assemble_name (file, fnname);
       putc ('\n', file);
     }
   inside_function = FALSE;
-
-  /* Output jump tables and the static subroutine information block.  */
-  if (TARGET_ABI_UNICOSMK)
-    {
-      unicosmk_output_ssib (file, fnname);
-      unicosmk_output_deferred_case_vectors (file);
-    }
-}
-
-#if TARGET_ABI_OPEN_VMS
-void avms_asm_output_external (FILE *file, tree decl ATTRIBUTE_UNUSED, const char *name)
-{
-#ifdef DO_CRTL_NAMES
-  DO_CRTL_NAMES;
-#endif
-}
-#endif
+}
 
 #if TARGET_ABI_OSF
 /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
@@ -8645,7 +8399,8 @@
 			   tree function)
 {
   HOST_WIDE_INT hi, lo;
-  rtx this_rtx, insn, funexp;
+  rtx this_rtx, funexp;
+  rtx_insn *insn;
 
   /* We always require a valid GP.  */
   emit_insn (gen_prologue_ldgp ());
@@ -8671,8 +8426,7 @@
     }
   else
     {
-      rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
-					   delta, -(delta < 0));
+      rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0), delta);
       emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
     }
 
@@ -8694,7 +8448,7 @@
       else
 	{
 	  tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
-					    vcall_offset, -(vcall_offset < 0));
+					    vcall_offset);
           emit_insn (gen_adddi3 (tmp, tmp, tmp2));
 	  lo = 0;
 	}
@@ -8723,7 +8477,6 @@
      instruction scheduling worth while.  Note that use_thunk calls
      assemble_start_function and assemble_end_function.  */
   insn = get_insns ();
-  insn_locators_alloc ();
   shorten_branches (insn);
   final_start_function (insn, file, 1);
   final (insn, file, 1);
@@ -8735,11 +8488,6 @@
 
 #include "gstab.h"
 
-/* Count the number of sdb related labels are generated (to find block
-   start and end boundaries).  */
-
-int sdb_label_count = 0;
-
 /* Name of the file containing the current function.  */
 
 static const char *current_function_file = "";
@@ -8764,25 +8512,14 @@
       fprintf (stream, "\t.file\t%d ", num_source_filenames);
       output_quoted_string (stream, name);
       fprintf (stream, "\n");
-      if (!TARGET_GAS && write_symbols == DBX_DEBUG)
-	fprintf (stream, "\t#@stabs\n");
-    }
-
-  else if (write_symbols == DBX_DEBUG)
-    /* dbxout.c will emit an appropriate .stabs directive.  */
-    return;
+    }
 
   else if (name != current_function_file
 	   && strcmp (name, current_function_file) != 0)
     {
-      if (inside_function && ! TARGET_GAS)
-	fprintf (stream, "\t#.file\t%d ", num_source_filenames);
-      else
-	{
-	  ++num_source_filenames;
-	  current_function_file = name;
-	  fprintf (stream, "\t.file\t%d ", num_source_filenames);
-	}
+      ++num_source_filenames;
+      current_function_file = name;
+      fprintf (stream, "\t.file\t%d ", num_source_filenames);
 
       output_quoted_string (stream, name);
       fprintf (stream, "\n");
@@ -8879,8 +8616,8 @@
       summarize_insn (XEXP (x, 0), sum, 0);
       break;
 
-    case CONST_INT:   case CONST_DOUBLE:
-    case SYMBOL_REF:  case LABEL_REF:     case CONST:
+    case CONST_INT:   case CONST_WIDE_INT:  case CONST_DOUBLE:
+    case SYMBOL_REF:  case LABEL_REF:       case CONST:
     case SCRATCH:     case ASM_INPUT:
       break;
 
@@ -8963,7 +8700,7 @@
 {
   struct shadow_summary shadow;
   int trap_pending, exception_nesting;
-  rtx i, n;
+  rtx_insn *i, *n;
 
   trap_pending = 0;
   exception_nesting = 0;
@@ -9053,6 +8790,11 @@
 			}
 		      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:
@@ -9068,6 +8810,7 @@
 		  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;
@@ -9117,7 +8860,7 @@
 };
 
 static enum alphaev4_pipe
-alphaev4_insn_pipe (rtx insn)
+alphaev4_insn_pipe (rtx_insn *insn)
 {
   if (recog_memoized (insn) < 0)
     return EV4_STOP;
@@ -9166,7 +8909,7 @@
 }
 
 static enum alphaev5_pipe
-alphaev5_insn_pipe (rtx insn)
+alphaev5_insn_pipe (rtx_insn *insn)
 {
   if (recog_memoized (insn) < 0)
     return EV5_STOP;
@@ -9226,8 +8969,8 @@
 
    LEN is, of course, the length of the group in bytes.  */
 
-static rtx
-alphaev4_next_group (rtx insn, int *pin_use, int *plen)
+static rtx_insn *
+alphaev4_next_group (rtx_insn *insn, int *pin_use, int *plen)
 {
   int len, in_use;
 
@@ -9324,8 +9067,8 @@
 
    LEN is, of course, the length of the group in bytes.  */
 
-static rtx
-alphaev5_next_group (rtx insn, int *pin_use, int *plen)
+static rtx_insn *
+alphaev5_next_group (rtx_insn *insn, int *pin_use, int *plen)
 {
   int len, in_use;
 
@@ -9508,16 +9251,16 @@
 /* The instruction group alignment main loop.  */
 
 static void
-alpha_align_insns (unsigned int max_align,
-		   rtx (*next_group) (rtx, int *, int *),
-		   rtx (*next_nop) (int *))
+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 i, next;
+  rtx_insn *i, *next;
 
   /* Let shorten branches care for assigning alignments to code labels.  */
   shorten_branches (get_insns ());
@@ -9575,7 +9318,7 @@
       else if ((int) align < len)
 	{
 	  unsigned int new_log_align = len > 8 ? 4 : 3;
-	  rtx prev, where;
+	  rtx_insn *prev, *where;
 
 	  where = prev = prev_nonnote_insn (i);
 	  if (!where || !LABEL_P (where))
@@ -9604,7 +9347,7 @@
       else if (ofs + len > (int) align)
 	{
 	  int nop_count = (align - ofs) / 4;
-	  rtx where;
+	  rtx_insn *where;
 
 	  /* Insert nops before labels, branches, and calls to truly merge
 	     the execution of the nops with the previous instruction group.  */
@@ -9613,7 +9356,7 @@
 	    {
 	      if (LABEL_P (where))
 		{
-		  rtx where2 = prev_nonnote_insn (where);
+		  rtx_insn *where2 = prev_nonnote_insn (where);
 		  if (where2 && JUMP_P (where2))
 		    where = where2;
 		}
@@ -9635,21 +9378,40 @@
     }
 }
 
-/* Insert an unop between a noreturn function call and GP load.  */
+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_noreturn (void)
-{
-  rtx insn, next;
+alpha_pad_function_end (void)
+{
+  rtx_insn *insn, *next;
 
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     {
       if (!CALL_P (insn)
-	  || !find_reg_note (insn, REG_NORETURN, NULL_RTX))
+	  || !(SIBLING_CALL_P (insn)
+	       || find_reg_note (insn, REG_NORETURN, NULL_RTX)))
         continue;
 
+      /* Make sure we do not split a call and its corresponding
+	 CALL_ARG_LOCATION note.  */
+      next = NEXT_INSN (insn);
+      if (next == NULL)
+	continue;
+      if (NOTE_P (next) && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION)
+	insn = next;
+
       next = next_active_insn (insn);
-
       if (next)
 	{
 	  rtx pat = PATTERN (next);
@@ -9667,8 +9429,28 @@
 static void
 alpha_reorg (void)
 {
-  /* Workaround for a linker error that triggers when an
-     exception handler immediatelly follows a noreturn function.
+  /* 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:
 
@@ -9688,53 +9470,40 @@
 
      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 noreturn function call and
+     an unop instruction between a sibcall or noreturn function call and
      exception handler prologue.  */
 
   if (current_function_has_exception_handlers ())
-    alpha_pad_noreturn ();
-
-  if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
-    alpha_handle_trap_shadows ();
-
-  /* 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.  */
-  if (optimize && !optimize_size
-      && alpha_tp != ALPHA_TP_INSN
-      && flag_schedule_insns_after_reload)
-    {
-      if (alpha_tune == PROCESSOR_EV4)
-	alpha_align_insns (8, alphaev4_next_group, alphaev4_next_nop);
-      else if (alpha_tune == PROCESSOR_EV5)
-	alpha_align_insns (16, alphaev5_next_group, alphaev5_next_nop);
+    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);
+	}
     }
 }
 
-#if !TARGET_ABI_UNICOSMK
-
-#ifdef HAVE_STAMP_H
-#include <stamp.h>
-#endif
-
 static void
 alpha_file_start (void)
 {
-#ifdef OBJECT_FORMAT_ELF
-  /* If emitting dwarf2 debug information, we cannot generate a .file
-     directive to start the file, as it will conflict with dwarf2out
-     file numbers.  So it's only useful when emitting mdebug output.  */
-  targetm.asm_file_start_file_directive = (write_symbols == DBX_DEBUG);
-#endif
-
   default_file_start ();
-#ifdef MS_STAMP
-  fprintf (asm_out_file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
-#endif
 
   fputs ("\t.set noreorder\n", asm_out_file);
   fputs ("\t.set volatile\n", asm_out_file);
-  if (!TARGET_ABI_OPEN_VMS)
+  if (TARGET_ABI_OSF)
     fputs ("\t.set noat\n", asm_out_file);
   if (TARGET_EXPLICIT_RELOCS)
     fputs ("\t.set nomacro\n", asm_out_file);
@@ -9756,9 +9525,7 @@
       fprintf (asm_out_file, "\t.arch %s\n", arch);
     }
 }
-#endif
-
-#ifdef OBJECT_FORMAT_ELF
+
 /* Since we don't have a .dynbss section, we should not allow global
    relocations in the .rodata section.  */
 
@@ -9772,7 +9539,7 @@
    honor small data.  */
 
 static section *
-alpha_elf_select_rtx_section (enum machine_mode mode, rtx x,
+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)
@@ -9798,49 +9565,35 @@
   flags |= default_section_type_flags (decl, name, reloc);
   return flags;
 }
-#endif /* OBJECT_FORMAT_ELF */
 
 /* Structure to collect function names for final output in link section.  */
 /* Note that items marked with GTY can't be ifdef'ed out.  */
 
-enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
-enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
+enum reloc_kind
+{
+  KIND_LINKAGE,
+  KIND_CODEADDR
+};
 
 struct GTY(()) alpha_links
 {
-  int num;
-  const char *target;
+  rtx func;
   rtx linkage;
-  enum links_kind lkind;
   enum reloc_kind rkind;
 };
 
-struct GTY(()) alpha_funcs
-{
-  int num;
-  splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
-    links;
-};
-
-static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
-  splay_tree alpha_links_tree;
-static GTY ((param1_is (tree), param2_is (struct alpha_funcs *)))
-  splay_tree alpha_funcs_tree;
-
-static GTY(()) int alpha_funcs_num;
-
 #if TARGET_ABI_OPEN_VMS
 
 /* Return the VMS argument type corresponding to MODE.  */
 
 enum avms_arg_type
-alpha_arg_type (enum machine_mode mode)
+alpha_arg_type (machine_mode mode)
 {
   switch (mode)
     {
-    case SFmode:
+    case E_SFmode:
       return TARGET_FLOAT_VAX ? FF : FS;
-    case DFmode:
+    case E_DFmode:
       return TARGET_FLOAT_VAX ? FD : FT;
     default:
       return I64;
@@ -9862,95 +9615,6 @@
   return GEN_INT (regval);
 }
 
-/* Register the need for a (fake) .linkage entry for calls to function NAME.
-   IS_LOCAL is 1 if this is for a definition, 0 if this is for a real call.
-   Return a SYMBOL_REF suited to the call instruction.  */
-
-rtx
-alpha_need_linkage (const char *name, int is_local)
-{
-  splay_tree_node node;
-  struct alpha_links *al;
-  const char *target;
-  tree id;
-
-  if (name[0] == '*')
-    name++;
-
-  if (is_local)
-    {
-      struct alpha_funcs *cfaf;
-
-      if (!alpha_funcs_tree)
-        alpha_funcs_tree = splay_tree_new_ggc
-	 (splay_tree_compare_pointers,
-	  ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
-	  ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
-
-
-      cfaf = ggc_alloc_alpha_funcs ();
-
-      cfaf->links = 0;
-      cfaf->num = ++alpha_funcs_num;
-
-      splay_tree_insert (alpha_funcs_tree,
-			 (splay_tree_key) current_function_decl,
-			 (splay_tree_value) cfaf);
-    }
-
-  if (alpha_links_tree)
-    {
-      /* Is this name already defined?  */
-
-      node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
-      if (node)
-	{
-	  al = (struct alpha_links *) node->value;
-	  if (is_local)
-	    {
-	      /* Defined here but external assumed.  */
-	      if (al->lkind == KIND_EXTERN)
-		al->lkind = KIND_LOCAL;
-	    }
-	  else
-	    {
-	      /* Used here but unused assumed.  */
-	      if (al->lkind == KIND_UNUSED)
-		al->lkind = KIND_LOCAL;
-	    }
-	  return al->linkage;
-	}
-    }
-  else
-    alpha_links_tree = splay_tree_new_ggc
-	 ((splay_tree_compare_fn) strcmp,
-	  ggc_alloc_splay_tree_str_alpha_links_splay_tree_s,
-	  ggc_alloc_splay_tree_str_alpha_links_splay_tree_node_s);
-
-  al = ggc_alloc_alpha_links ();
-  name = ggc_strdup (name);
-
-  /* Assume external if no definition.  */
-  al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
-
-  /* Ensure we have an IDENTIFIER so assemble_name can mark it used
-     and find the ultimate alias target like assemble_name.  */
-  id = get_identifier (name);
-  target = NULL;
-  while (IDENTIFIER_TRANSPARENT_ALIAS (id))
-    {
-      id = TREE_CHAIN (id);
-      target = IDENTIFIER_POINTER (id);
-    }
-
-  al->target = target ? target : name;
-  al->linkage = gen_rtx_SYMBOL_REF (Pmode, name);
-
-  splay_tree_insert (alpha_links_tree, (splay_tree_key) name,
-		     (splay_tree_value) al);
-
-  return al->linkage;
-}
 
 /* Return a SYMBOL_REF representing the reference to the .linkage entry
    of function FUNC built for calls made from CFUNDECL.  LFLAG is 1 if
@@ -9959,137 +9623,102 @@
    reference (code address only), 0 if this is a full reference.  */
 
 rtx
-alpha_use_linkage (rtx func, tree cfundecl, int lflag, int rflag)
-{
-  splay_tree_node cfunnode;
-  struct alpha_funcs *cfaf;
-  struct alpha_links *al;
+alpha_use_linkage (rtx func, bool lflag, bool rflag)
+{
+  struct alpha_links *al = NULL;
   const char *name = XSTR (func, 0);
 
-  cfaf = (struct alpha_funcs *) 0;
-  al = (struct alpha_links *) 0;
-
-  cfunnode = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) cfundecl);
-  cfaf = (struct alpha_funcs *) cfunnode->value;
-
-  if (cfaf->links)
-    {
-      splay_tree_node lnode;
-
+  if (cfun->machine->links)
+    {
       /* Is this name already defined?  */
-
-      lnode = splay_tree_lookup (cfaf->links, (splay_tree_key) name);
-      if (lnode)
-	al = (struct alpha_links *) lnode->value;
+      alpha_links **slot = cfun->machine->links->get (name);
+      if (slot)
+	al = *slot;
     }
   else
-    cfaf->links = splay_tree_new_ggc
-      ((splay_tree_compare_fn) strcmp,
-       ggc_alloc_splay_tree_str_alpha_links_splay_tree_s,
-       ggc_alloc_splay_tree_str_alpha_links_splay_tree_node_s);
-
-  if (!al)
-    {
-      size_t name_len;
-      size_t buflen;
+    cfun->machine->links
+      = hash_map<nofree_string_hash, alpha_links *>::create_ggc (64);
+
+  if (al == NULL)
+    {
+      size_t buf_len;
       char *linksym;
-      splay_tree_node node = 0;
-      struct alpha_links *anl;
+      tree id;
 
       if (name[0] == '*')
 	name++;
 
-      name_len = strlen (name);
-      linksym = (char *) alloca (name_len + 50);
-
-      al = ggc_alloc_alpha_links ();
-      al->num = cfaf->num;
-      al->target = NULL;
-
-      node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
-      if (node)
-	{
-	  anl = (struct alpha_links *) node->value;
-	  al->lkind = anl->lkind;
-	  name = anl->target;
-	}
-
-      sprintf (linksym, "$%d..%s..lk", cfaf->num, name);
-      buflen = strlen (linksym);
-
-      al->linkage = gen_rtx_SYMBOL_REF
-	(Pmode, ggc_alloc_string (linksym, buflen + 1));
-
-      splay_tree_insert (cfaf->links, (splay_tree_key) name,
-			 (splay_tree_value) al);
-    }
-
-  if (rflag)
-    al->rkind = KIND_CODEADDR;
-  else
-    al->rkind = KIND_LINKAGE;
+      /* 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 (al->linkage, 8));
+    return gen_rtx_MEM (Pmode, plus_constant (Pmode, al->linkage, 8));
   else
     return al->linkage;
 }
 
 static int
-alpha_write_one_linkage (splay_tree_node node, void *data)
-{
-  const char *const name = (const char *) node->key;
-  struct alpha_links *link = (struct alpha_links *) node->value;
-  FILE *stream = (FILE *) data;
-
-  fprintf (stream, "$%d..%s..lk:\n", link->num, name);
+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)
     {
-      if (link->lkind == KIND_LOCAL)
-	{
-	  /* Local and used */
+      /* 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 and used, request code address.  */
-	  fprintf (stream, "\t.code_address %s\n", name);
-	}
-    }
-  else
-    {
-      if (link->lkind == KIND_LOCAL)
-	{
-	  /* Local and used, build linkage pair.  */
-	  fprintf (stream, "\t.quad %s..en\n", name);
-	  fprintf (stream, "\t.quad %s\n", name);
-	}
-      else
-	{
-	  /* External and used, request linkage pair.  */
-	  fprintf (stream, "\t.linkage %s\n", name);
-	}
-    }
+	  /* 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, tree fundecl)
-{
-  splay_tree_node node;
-  struct alpha_funcs *func;
-
+alpha_write_linkage (FILE *stream, const char *funname)
+{
   fprintf (stream, "\t.link\n");
   fprintf (stream, "\t.align 3\n");
   in_section = NULL;
 
-  node = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) fundecl);
-  func = (struct alpha_funcs *) node->value;
-
+#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);
@@ -10097,10 +9726,12 @@
 	   alpha_procedure_type == PT_STACK ? "stack"
 	   : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
 
-  if (func->links)
-    {
-      splay_tree_foreach (func->links, alpha_write_one_linkage, stream);
-      /* splay_tree_delete (func->links); */
+  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);
     }
 }
 
@@ -10145,815 +9776,20 @@
   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
 }
 #else
-
-rtx
-alpha_need_linkage (const char *name ATTRIBUTE_UNUSED,
-		    int is_local ATTRIBUTE_UNUSED)
-{
-  return NULL_RTX;
-}
-
 rtx
 alpha_use_linkage (rtx func ATTRIBUTE_UNUSED,
-		   tree cfundecl ATTRIBUTE_UNUSED,
-		   int lflag ATTRIBUTE_UNUSED,
-		   int rflag ATTRIBUTE_UNUSED)
+		   bool lflag ATTRIBUTE_UNUSED,
+		   bool rflag ATTRIBUTE_UNUSED)
 {
   return NULL_RTX;
 }
 
 #endif /* TARGET_ABI_OPEN_VMS */
 
-#if TARGET_ABI_UNICOSMK
-
-/* This evaluates to true if we do not know how to pass TYPE solely in
-   registers.  This is the case for all arguments that do not fit in two
-   registers.  */
-
-static bool
-unicosmk_must_pass_in_stack (enum machine_mode mode, const_tree type)
-{
-  if (type == NULL)
-    return false;
-
-  if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
-    return true;
-  if (TREE_ADDRESSABLE (type))
-    return true;
-
-  return ALPHA_ARG_SIZE (mode, type, 0) > 2;
-}
-
-/* Define the offset between two registers, one to be eliminated, and the
-   other its replacement, at the start of a routine.  */
-
-int
-unicosmk_initial_elimination_offset (int from, int to)
-{
-  int fixed_size;
-
-  fixed_size = alpha_sa_size();
-  if (fixed_size != 0)
-    fixed_size += 48;
-
-  if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
-    return -fixed_size;
-  else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
-    return 0;
-  else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-    return (ALPHA_ROUND (crtl->outgoing_args_size)
-	    + ALPHA_ROUND (get_frame_size()));
-  else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-    return (ALPHA_ROUND (fixed_size)
-	    + ALPHA_ROUND (get_frame_size()
-			   + crtl->outgoing_args_size));
-  else
-    gcc_unreachable ();
-}
-
-/* Output the module name for .ident and .end directives. We have to strip
-   directories and add make sure that the module name starts with a letter
-   or '$'.  */
-
-static void
-unicosmk_output_module_name (FILE *file)
-{
-  const char *name = lbasename (main_input_filename);
-  unsigned len = strlen (name);
-  char *clean_name = alloca (len + 2);
-  char *ptr = clean_name;
-
-  /* CAM only accepts module names that start with a letter or '$'. We
-     prefix the module name with a '$' if necessary.  */
-
-  if (!ISALPHA (*name))
-    *ptr++ = '$';
-  memcpy (ptr, name, len + 1);
-  clean_symbol_name (clean_name);
-  fputs (clean_name, file);
-}
-
-/* Output the definition of a common variable.  */
-
-void
-unicosmk_output_common (FILE *file, const char *name, int size, int align)
-{
-  tree name_tree;
-  printf ("T3E__: common %s\n", name);
-
-  in_section = NULL;
-  fputs("\t.endp\n\n\t.psect ", file);
-  assemble_name(file, name);
-  fprintf(file, ",%d,common\n", floor_log2 (align / BITS_PER_UNIT));
-  fprintf(file, "\t.byte\t0:%d\n", size);
-
-  /* Mark the symbol as defined in this module.  */
-  name_tree = get_identifier (name);
-  TREE_ASM_WRITTEN (name_tree) = 1;
-}
-
-#define SECTION_PUBLIC SECTION_MACH_DEP
-#define SECTION_MAIN (SECTION_PUBLIC << 1)
-static int current_section_align;
-
-/* A get_unnamed_section callback for switching to the text section.  */
-
-static void
-unicosmk_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
-{
-  static int count = 0;
-  fprintf (asm_out_file, "\t.endp\n\n\t.psect\tgcc@text___%d,code\n", count++);
-}
-
-/* A get_unnamed_section callback for switching to the data section.  */
-
-static void
-unicosmk_output_data_section_asm_op (const void *data ATTRIBUTE_UNUSED)
-{
-  static int count = 1;
-  fprintf (asm_out_file, "\t.endp\n\n\t.psect\tgcc@data___%d,data\n", count++);
-}
-
-/* Implement TARGET_ASM_INIT_SECTIONS.
-
-   The Cray assembler is really weird with respect to sections. It has only
-   named sections and you can't reopen a section once it has been closed.
-   This means that we have to generate unique names whenever we want to
-   reenter the text or the data section.  */
-
-static void
-unicosmk_init_sections (void)
-{
-  text_section = get_unnamed_section (SECTION_CODE,
-				      unicosmk_output_text_section_asm_op,
-				      NULL);
-  data_section = get_unnamed_section (SECTION_WRITE,
-				      unicosmk_output_data_section_asm_op,
-				      NULL);
-  readonly_data_section = data_section;
-}
-
-static unsigned int
-unicosmk_section_type_flags (tree decl, const char *name,
-			     int reloc ATTRIBUTE_UNUSED)
-{
-  unsigned int flags = default_section_type_flags (decl, name, reloc);
-
-  if (!decl)
-    return flags;
-
-  if (TREE_CODE (decl) == FUNCTION_DECL)
-    {
-      current_section_align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
-      if (align_functions_log > current_section_align)
-	current_section_align = align_functions_log;
-
-      if (! strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "main"))
-	flags |= SECTION_MAIN;
-    }
-  else
-    current_section_align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
-
-  if (TREE_PUBLIC (decl))
-    flags |= SECTION_PUBLIC;
-
-  return flags;
-}
-
-/* Generate a section name for decl and associate it with the
-   declaration.  */
-
-static void
-unicosmk_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
-{
-  const char *name;
-  int len;
-
-  gcc_assert (decl);
-
-  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-  name = default_strip_name_encoding (name);
-  len = strlen (name);
-
-  if (TREE_CODE (decl) == FUNCTION_DECL)
-    {
-      char *string;
-
-      /* It is essential that we prefix the section name here because
-	 otherwise the section names generated for constructors and
-	 destructors confuse collect2.  */
-
-      string = alloca (len + 6);
-      sprintf (string, "code@%s", name);
-      DECL_SECTION_NAME (decl) = build_string (len + 5, string);
-    }
-  else if (TREE_PUBLIC (decl))
-    DECL_SECTION_NAME (decl) = build_string (len, name);
-  else
-    {
-      char *string;
-
-      string = alloca (len + 6);
-      sprintf (string, "data@%s", name);
-      DECL_SECTION_NAME (decl) = build_string (len + 5, string);
-    }
-}
-
-/* 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
-unicosmk_asm_named_section (const char *name, unsigned int flags, 
-			    tree decl ATTRIBUTE_UNUSED)
-{
-  const char *kind;
-
-  /* Close the previous section.  */
-
-  fputs ("\t.endp\n\n", asm_out_file);
-
-  /* Find out what kind of section we are opening.  */
-
-  if (flags & SECTION_MAIN)
-    fputs ("\t.start\tmain\n", asm_out_file);
-
-  if (flags & SECTION_CODE)
-    kind = "code";
-  else if (flags & SECTION_PUBLIC)
-    kind = "common";
-  else
-    kind = "data";
-
-  if (current_section_align != 0)
-    fprintf (asm_out_file, "\t.psect\t%s,%d,%s\n", name,
-	     current_section_align, kind);
-  else
-    fprintf (asm_out_file, "\t.psect\t%s,%s\n", name, kind);
-}
-
-static void
-unicosmk_insert_attributes (tree decl, tree *attr_ptr ATTRIBUTE_UNUSED)
-{
-  if (DECL_P (decl)
-      && (TREE_PUBLIC (decl) || TREE_CODE (decl) == FUNCTION_DECL))
-    unicosmk_unique_section (decl, 0);
-}
-
-/* Output an alignment directive. We have to use the macro 'gcc@code@align'
-   in code sections because .align fill unused space with zeroes.  */
-
-void
-unicosmk_output_align (FILE *file, int align)
-{
-  if (inside_function)
-    fprintf (file, "\tgcc@code@align\t%d\n", align);
-  else
-    fprintf (file, "\t.align\t%d\n", align);
-}
-
-/* Add a case vector to the current function's list of deferred case
-   vectors. Case vectors have to be put into a separate section because CAM
-   does not allow data definitions in code sections.  */
-
-void
-unicosmk_defer_case_vector (rtx lab, rtx vec)
-{
-  struct machine_function *machine = cfun->machine;
-
-  vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
-  machine->addr_list = gen_rtx_EXPR_LIST (VOIDmode, vec,
-					  machine->addr_list);
-}
-
-/* Output a case vector.  */
-
-static void
-unicosmk_output_addr_vec (FILE *file, rtx vec)
-{
-  rtx lab  = XEXP (vec, 0);
-  rtx body = XEXP (vec, 1);
-  int vlen = XVECLEN (body, 0);
-  int idx;
-
-  (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (lab));
-
-  for (idx = 0; idx < vlen; idx++)
-    {
-      ASM_OUTPUT_ADDR_VEC_ELT
-        (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
-    }
-}
-
-/* Output current function's deferred case vectors.  */
-
-static void
-unicosmk_output_deferred_case_vectors (FILE *file)
-{
-  struct machine_function *machine = cfun->machine;
-  rtx t;
-
-  if (machine->addr_list == NULL_RTX)
-    return;
-
-  switch_to_section (data_section);
-  for (t = machine->addr_list; t; t = XEXP (t, 1))
-    unicosmk_output_addr_vec (file, XEXP (t, 0));
-}
-
-/* Generate the name of the SSIB section for the current function.  */
-
-#define SSIB_PREFIX "__SSIB_"
-#define SSIB_PREFIX_LEN 7
-
-static const char *
-unicosmk_ssib_name (void)
-{
-  /* This is ok since CAM won't be able to deal with names longer than that
-     anyway.  */
-
-  static char name[256];
-
-  rtx x;
-  const char *fnname;
-  int len;
-
-  x = DECL_RTL (cfun->decl);
-  gcc_assert (MEM_P (x));
-  x = XEXP (x, 0);
-  gcc_assert (GET_CODE (x) == SYMBOL_REF);
-  fnname = XSTR (x, 0);
-
-  len = strlen (fnname);
-  if (len + SSIB_PREFIX_LEN > 255)
-    len = 255 - SSIB_PREFIX_LEN;
-
-  strcpy (name, SSIB_PREFIX);
-  strncpy (name + SSIB_PREFIX_LEN, fnname, len);
-  name[len + SSIB_PREFIX_LEN] = 0;
-
-  return name;
-}
-
-/* Set up the dynamic subprogram information block (DSIB) and update the
-   frame pointer register ($15) for subroutines which have a frame. If the
-   subroutine doesn't have a frame, simply increment $15.  */
-
-static void
-unicosmk_gen_dsib (unsigned long *imaskP)
-{
-  if (alpha_procedure_type == PT_STACK)
-    {
-      const char *ssib_name;
-      rtx mem;
-
-      /* Allocate 64 bytes for the DSIB.  */
-
-      FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
-                                  GEN_INT (-64))));
-      emit_insn (gen_blockage ());
-
-      /* Save the return address.  */
-
-      mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 56));
-      set_mem_alias_set (mem, alpha_sr_alias_set);
-      FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
-      (*imaskP) &= ~(1UL << REG_RA);
-
-      /* Save the old frame pointer.  */
-
-      mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 48));
-      set_mem_alias_set (mem, alpha_sr_alias_set);
-      FRP (emit_move_insn (mem, hard_frame_pointer_rtx));
-      (*imaskP) &= ~(1UL << HARD_FRAME_POINTER_REGNUM);
-
-      emit_insn (gen_blockage ());
-
-      /* Store the SSIB pointer.  */
-
-      ssib_name = ggc_strdup (unicosmk_ssib_name ());
-      mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 32));
-      set_mem_alias_set (mem, alpha_sr_alias_set);
-
-      FRP (emit_move_insn (gen_rtx_REG (DImode, 5),
-                           gen_rtx_SYMBOL_REF (Pmode, ssib_name)));
-      FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 5)));
-
-      /* Save the CIW index.  */
-
-      mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 24));
-      set_mem_alias_set (mem, alpha_sr_alias_set);
-      FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 25)));
-
-      emit_insn (gen_blockage ());
-
-      /* Set the new frame pointer.  */
-      FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
-                                  stack_pointer_rtx, GEN_INT (64))));
-    }
-  else
-    {
-      /* Increment the frame pointer register to indicate that we do not
-         have a frame.  */
-      emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
-                             hard_frame_pointer_rtx, const1_rtx));
-    }
-}
-
-/* Output the static subroutine information block for the current
-   function.  */
-
-static void
-unicosmk_output_ssib (FILE *file, const char *fnname)
-{
-  int len;
-  int i;
-  rtx x;
-  rtx ciw;
-  struct machine_function *machine = cfun->machine;
-
-  in_section = NULL;
-  fprintf (file, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix,
-	   unicosmk_ssib_name ());
-
-  /* Some required stuff and the function name length.  */
-
-  len = strlen (fnname);
-  fprintf (file, "\t.quad\t^X20008%2.2X28\n", len);
-
-  /* Saved registers
-     ??? We don't do that yet.  */
-
-  fputs ("\t.quad\t0\n", file);
-
-  /* Function address.  */
-
-  fputs ("\t.quad\t", file);
-  assemble_name (file, fnname);
-  putc ('\n', file);
-
-  fputs ("\t.quad\t0\n", file);
-  fputs ("\t.quad\t0\n", file);
-
-  /* Function name.
-     ??? We do it the same way Cray CC does it but this could be
-     simplified.  */
-
-  for( i = 0; i < len; i++ )
-    fprintf (file, "\t.byte\t%d\n", (int)(fnname[i]));
-  if( (len % 8) == 0 )
-    fputs ("\t.quad\t0\n", file);
-  else
-    fprintf (file, "\t.bits\t%d : 0\n", (8 - (len % 8))*8);
-
-  /* All call information words used in the function.  */
-
-  for (x = machine->first_ciw; x; x = XEXP (x, 1))
-    {
-      ciw = XEXP (x, 0);
-#if HOST_BITS_PER_WIDE_INT == 32
-      fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_DOUBLE_HEX "\n",
-	       CONST_DOUBLE_HIGH (ciw), CONST_DOUBLE_LOW (ciw));
-#else
-      fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n", INTVAL (ciw));
-#endif
-    }
-}
-
-/* Add a call information word (CIW) to the list of the current function's
-   CIWs and return its index.
-
-   X is a CONST_INT or CONST_DOUBLE representing the CIW.  */
-
-rtx
-unicosmk_add_call_info_word (rtx x)
-{
-  rtx node;
-  struct machine_function *machine = cfun->machine;
-
-  node = gen_rtx_EXPR_LIST (VOIDmode, x, NULL_RTX);
-  if (machine->first_ciw == NULL_RTX)
-    machine->first_ciw = node;
-  else
-    XEXP (machine->last_ciw, 1) = node;
-
-  machine->last_ciw = node;
-  ++machine->ciw_count;
-
-  return GEN_INT (machine->ciw_count
-		  + strlen (current_function_name ())/8 + 5);
-}
-
-/* The Cray assembler doesn't accept extern declarations for symbols which
-   are defined in the same file. We have to keep track of all global
-   symbols which are referenced and/or defined in a source file and output
-   extern declarations for those which are referenced but not defined at
-   the end of file.  */
-
-/* List of identifiers for which an extern declaration might have to be
-   emitted.  */
-/* FIXME: needs to use GC, so it can be saved and restored for PCH.  */
-
-struct unicosmk_extern_list
-{
-  struct unicosmk_extern_list *next;
-  const char *name;
-};
-
-static struct unicosmk_extern_list *unicosmk_extern_head = 0;
-
-/* Output extern declarations which are required for every asm file.  */
-
-static void
-unicosmk_output_default_externs (FILE *file)
-{
-  static const char *const externs[] =
-    { "__T3E_MISMATCH" };
-
-  int i;
-  int n;
-
-  n = ARRAY_SIZE (externs);
-
-  for (i = 0; i < n; i++)
-    fprintf (file, "\t.extern\t%s\n", externs[i]);
-}
-
-/* Output extern declarations for global symbols which are have been
-   referenced but not defined.  */
-
-static void
-unicosmk_output_externs (FILE *file)
-{
-  struct unicosmk_extern_list *p;
-  const char *real_name;
-  int len;
-  tree name_tree;
-
-  len = strlen (user_label_prefix);
-  for (p = unicosmk_extern_head; p != 0; p = p->next)
-    {
-      /* We have to strip the encoding and possibly remove user_label_prefix
-	 from the identifier in order to handle -fleading-underscore and
-	 explicit asm names correctly (cf. gcc.dg/asm-names-1.c).  */
-      real_name = default_strip_name_encoding (p->name);
-      if (len && p->name[0] == '*'
-	  && !memcmp (real_name, user_label_prefix, len))
-	real_name += len;
-
-      name_tree = get_identifier (real_name);
-      if (! TREE_ASM_WRITTEN (name_tree))
-	{
-	  TREE_ASM_WRITTEN (name_tree) = 1;
-	  fputs ("\t.extern\t", file);
-	  assemble_name (file, p->name);
-	  putc ('\n', file);
-	}
-    }
-}
-
-/* Record an extern.  */
-
-void
-unicosmk_add_extern (const char *name)
-{
-  struct unicosmk_extern_list *p;
-
-  p = (struct unicosmk_extern_list *)
-       xmalloc (sizeof (struct unicosmk_extern_list));
-  p->next = unicosmk_extern_head;
-  p->name = name;
-  unicosmk_extern_head = p;
-}
-
-/* The Cray assembler generates incorrect code if identifiers which
-   conflict with register names are used as instruction operands. We have
-   to replace such identifiers with DEX expressions.  */
-
-/* Structure to collect identifiers which have been replaced by DEX
-   expressions.  */
-/* FIXME: needs to use GC, so it can be saved and restored for PCH.  */
-
-struct unicosmk_dex {
-  struct unicosmk_dex *next;
-  const char *name;
-};
-
-/* List of identifiers which have been replaced by DEX expressions. The DEX
-   number is determined by the position in the list.  */
-
-static struct unicosmk_dex *unicosmk_dex_list = NULL;
-
-/* The number of elements in the DEX list.  */
-
-static int unicosmk_dex_count = 0;
-
-/* Check if NAME must be replaced by a DEX expression.  */
-
-static int
-unicosmk_special_name (const char *name)
-{
-  if (name[0] == '*')
-    ++name;
-
-  if (name[0] == '$')
-    ++name;
-
-  if (name[0] != 'r' && name[0] != 'f' && name[0] != 'R' && name[0] != 'F')
-    return 0;
-
-  switch (name[1])
-    {
-    case '1':  case '2':
-      return (name[2] == '\0' || (ISDIGIT (name[2]) && name[3] == '\0'));
-
-    case '3':
-      return (name[2] == '\0'
-	       || ((name[2] == '0' || name[2] == '1') && name[3] == '\0'));
-
-    default:
-      return (ISDIGIT (name[1]) && name[2] == '\0');
-    }
-}
-
-/* Return the DEX number if X must be replaced by a DEX expression and 0
-   otherwise.  */
-
-static int
-unicosmk_need_dex (rtx x)
-{
-  struct unicosmk_dex *dex;
-  const char *name;
-  int i;
-
-  if (GET_CODE (x) != SYMBOL_REF)
-    return 0;
-
-  name = XSTR (x,0);
-  if (! unicosmk_special_name (name))
-    return 0;
-
-  i = unicosmk_dex_count;
-  for (dex = unicosmk_dex_list; dex; dex = dex->next)
-    {
-      if (! strcmp (name, dex->name))
-        return i;
-      --i;
-    }
-
-  dex = (struct unicosmk_dex *) xmalloc (sizeof (struct unicosmk_dex));
-  dex->name = name;
-  dex->next = unicosmk_dex_list;
-  unicosmk_dex_list = dex;
-
-  ++unicosmk_dex_count;
-  return unicosmk_dex_count;
-}
-
-/* Output the DEX definitions for this file.  */
-
-static void
-unicosmk_output_dex (FILE *file)
-{
-  struct unicosmk_dex *dex;
-  int i;
-
-  if (unicosmk_dex_list == NULL)
-    return;
-
-  fprintf (file, "\t.dexstart\n");
-
-  i = unicosmk_dex_count;
-  for (dex = unicosmk_dex_list; dex; dex = dex->next)
-    {
-      fprintf (file, "\tDEX (%d) = ", i);
-      assemble_name (file, dex->name);
-      putc ('\n', file);
-      --i;
-    }
-
-  fprintf (file, "\t.dexend\n");
-}
-
-/* Output text that to appear at the beginning of an assembler file.  */
-
-static void
-unicosmk_file_start (void)
-{
-  int i;
-
-  fputs ("\t.ident\t", asm_out_file);
-  unicosmk_output_module_name (asm_out_file);
-  fputs ("\n\n", asm_out_file);
-
-  /* The Unicos/Mk assembler uses different register names. Instead of trying
-     to support them, we simply use micro definitions.  */
-
-  /* CAM has different register names: rN for the integer register N and fN
-     for the floating-point register N. Instead of trying to use these in
-     alpha.md, we define the symbols $N and $fN to refer to the appropriate
-     register.  */
-
-  for (i = 0; i < 32; ++i)
-    fprintf (asm_out_file, "$%d <- r%d\n", i, i);
-
-  for (i = 0; i < 32; ++i)
-    fprintf (asm_out_file, "$f%d <- f%d\n", i, i);
-
-  putc ('\n', asm_out_file);
-
-  /* The .align directive fill unused space with zeroes which does not work
-     in code sections. We define the macro 'gcc@code@align' which uses nops
-     instead. Note that it assumes that code sections always have the
-     biggest possible alignment since . refers to the current offset from
-     the beginning of the section.  */
-
-  fputs ("\t.macro gcc@code@align n\n", asm_out_file);
-  fputs ("gcc@n@bytes = 1 << n\n", asm_out_file);
-  fputs ("gcc@here = . % gcc@n@bytes\n", asm_out_file);
-  fputs ("\t.if ne, gcc@here, 0\n", asm_out_file);
-  fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", asm_out_file);
-  fputs ("\tbis r31,r31,r31\n", asm_out_file);
-  fputs ("\t.endr\n", asm_out_file);
-  fputs ("\t.endif\n", asm_out_file);
-  fputs ("\t.endm gcc@code@align\n\n", asm_out_file);
-
-  /* Output extern declarations which should always be visible.  */
-  unicosmk_output_default_externs (asm_out_file);
-
-  /* Open a dummy section. We always need to be inside a section for the
-     section-switching code to work correctly.
-     ??? This should be a module id or something like that. I still have to
-     figure out what the rules for those are.  */
-  fputs ("\n\t.psect\t$SG00000,data\n", asm_out_file);
-}
-
-/* Output text to appear at the end of an assembler file. This includes all
-   pending extern declarations and DEX expressions.  */
-
-static void
-unicosmk_file_end (void)
-{
-  fputs ("\t.endp\n\n", asm_out_file);
-
-  /* Output all pending externs.  */
-
-  unicosmk_output_externs (asm_out_file);
-
-  /* Output dex definitions used for functions whose names conflict with
-     register names.  */
-
-  unicosmk_output_dex (asm_out_file);
-
-  fputs ("\t.end\t", asm_out_file);
-  unicosmk_output_module_name (asm_out_file);
-  putc ('\n', asm_out_file);
-}
-
-#else
-
-static void
-unicosmk_output_deferred_case_vectors (FILE *file ATTRIBUTE_UNUSED)
-{}
-
-static void
-unicosmk_gen_dsib (unsigned long *imaskP ATTRIBUTE_UNUSED)
-{}
-
-static void
-unicosmk_output_ssib (FILE * file ATTRIBUTE_UNUSED,
-		      const char * fnname ATTRIBUTE_UNUSED)
-{}
-
-rtx
-unicosmk_add_call_info_word (rtx x ATTRIBUTE_UNUSED)
-{
-  return NULL_RTX;
-}
-
-static int
-unicosmk_need_dex (rtx x ATTRIBUTE_UNUSED)
-{
-  return 0;
-}
-
-#endif /* TARGET_ABI_UNICOSMK */
-
 static void
 alpha_init_libfuncs (void)
 {
-  if (TARGET_ABI_UNICOSMK)
-    {
-      /* Prevent gcc from generating calls to __divsi3.  */
-      set_optab_libfunc (sdiv_optab, SImode, 0);
-      set_optab_libfunc (udiv_optab, SImode, 0);
-
-      /* Use the functions provided by the system library
-	 for DImode integer division.  */
-      set_optab_libfunc (sdiv_optab, DImode, "$sldiv");
-      set_optab_libfunc (udiv_optab, DImode, "$uldiv");
-    }
-  else if (TARGET_ABI_OPEN_VMS)
+  if (TARGET_ABI_OPEN_VMS)
     {
       /* Use the VMS runtime library functions for division and
 	 remainder.  */
@@ -10965,8 +9801,6 @@
       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");
-      abort_libfunc = init_one_libfunc ("decc$abort");
-      memcmp_libfunc = init_one_libfunc ("decc$memcmp");
 #ifdef MEM_LIBFUNCS_INIT
       MEM_LIBFUNCS_INIT;
 #endif
@@ -10984,6 +9818,131 @@
     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 = build2 (MODIFY_EXPR, long_unsigned_type_node,
+		    fenv_var, build_call_expr (get_fpscr, 0));
+  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 = build2 (MODIFY_EXPR, long_unsigned_type_node, new_fenv_var,
+			build_call_expr (get_fpscr, 0));
+  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
@@ -10996,21 +9955,6 @@
 #undef TARGET_IN_SMALL_DATA_P
 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
 
-#if TARGET_ABI_UNICOSMK
-# undef TARGET_INSERT_ATTRIBUTES
-# define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
-# undef TARGET_SECTION_TYPE_FLAGS
-# define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
-# undef TARGET_ASM_UNIQUE_SECTION
-# define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
-#undef TARGET_ASM_FUNCTION_RODATA_SECTION
-#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
-# undef TARGET_ASM_GLOBALIZE_LABEL
-# define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr
-# undef TARGET_MUST_PASS_IN_STACK
-# define TARGET_MUST_PASS_IN_STACK unicosmk_must_pass_in_stack
-#endif
-
 #undef TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
 #undef TARGET_ASM_ALIGNED_DI_OP
@@ -11018,7 +9962,7 @@
 
 /* Default unaligned ops are provided for ELF systems.  To get unaligned
    data for non-ELF systems, we have to turn off auto alignment.  */
-#if !defined (OBJECT_FORMAT_ELF) || TARGET_ABI_OPEN_VMS
+#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
@@ -11027,14 +9971,12 @@
 #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
 #endif
 
-#ifdef OBJECT_FORMAT_ELF
 #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
-#endif
 
 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
@@ -11044,18 +9986,11 @@
 
 #undef TARGET_LEGITIMIZE_ADDRESS
 #define TARGET_LEGITIMIZE_ADDRESS alpha_legitimize_address
-
-#if TARGET_ABI_UNICOSMK
-#undef TARGET_ASM_FILE_START
-#define TARGET_ASM_FILE_START unicosmk_file_start
-#undef TARGET_ASM_FILE_END
-#define TARGET_ASM_FILE_END unicosmk_file_end
-#else
+#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_ASM_FILE_START_FILE_DIRECTIVE
-#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
-#endif
 
 #undef TARGET_SCHED_ADJUST_COST
 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
@@ -11076,11 +10011,15 @@
 #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
 
@@ -11093,10 +10032,29 @@
 #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_bool_0
+#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
 
 #undef TARGET_MACHINE_DEPENDENT_REORG
 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
@@ -11105,6 +10063,13 @@
 #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
@@ -11128,8 +10093,15 @@
 #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
@@ -11142,35 +10114,42 @@
 #undef TARGET_EXPAND_BUILTIN_VA_START
 #define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start
 
-/* The Alpha architecture does not require sequential consistency.  See
-   http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html
-   for an example of how it can be violated in practice.  */
-#undef TARGET_RELAXED_ORDERING
-#define TARGET_RELAXED_ORDERING true
-
-#undef TARGET_DEFAULT_TARGET_FLAGS
-#define TARGET_DEFAULT_TARGET_FLAGS \
-  (TARGET_DEFAULT | TARGET_CPU_DEFAULT | TARGET_DEFAULT_EXPLICIT_RELOCS)
-#undef TARGET_HANDLE_OPTION
-#define TARGET_HANDLE_OPTION alpha_handle_option
-
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE alpha_option_override
 
-#undef TARGET_OPTION_OPTIMIZATION_TABLE
-#define TARGET_OPTION_OPTIMIZATION_TABLE alpha_option_optimization_table
+#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;