OSDN Git Service

* config/alpha/alpha.c (alpha_legitimate_constant_p): Reject CONST
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / alpha.c
index 800b354..fe515d4 100644 (file)
@@ -1,6 +1,7 @@
 /* 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 Free Software Foundation, Inc.
+   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 This file is part of GCC.
@@ -51,7 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include <splay-tree.h>
 #include "cfglayout.h"
-#include "tree-gimple.h"
+#include "gimple.h"
 #include "tree-flow.h"
 #include "tree-stdarg.h"
 #include "tm-constrs.h"
@@ -80,11 +81,6 @@ enum alpha_fp_rounding_mode alpha_fprm;
 
 enum alpha_fp_trap_mode alpha_fptm;
 
-/* Save information from a "cmpxx" operation until the branch or scc is
-   emitted.  */
-
-struct alpha_compare alpha_compare;
-
 /* Nonzero if inside of a function, because the Alpha asm can't
    handle .files inside of functions.  */
 
@@ -189,9 +185,9 @@ static struct alpha_rtx_cost_data const alpha_rtx_cost_size =
 
 /* Get the number of args of a function in one of two ways.  */
 #if TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK
-#define NUM_ARGS current_function_args_info.num_args
+#define NUM_ARGS crtl->args.info.num_args
 #else
-#define NUM_ARGS current_function_args_info
+#define NUM_ARGS crtl->args.info
 #endif
 
 #define REG_PV 27
@@ -274,10 +270,10 @@ override_options (void)
     { "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 },
-    { 0, 0, 0 }
+    { "21264a",        PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX }
   };
 
+  int const ct_size = ARRAY_SIZE (cpu_table);
   int i;
 
   /* Unicos/Mk doesn't have shared libraries.  */
@@ -369,7 +365,7 @@ override_options (void)
 
   if (alpha_cpu_string)
     {
-      for (i = 0; cpu_table [i].name; i++)
+      for (i = 0; i < ct_size; i++)
        if (! strcmp (alpha_cpu_string, cpu_table [i].name))
          {
            alpha_tune = alpha_cpu = cpu_table [i].processor;
@@ -377,19 +373,19 @@ override_options (void)
            target_flags |= cpu_table [i].flags;
            break;
          }
-      if (! cpu_table [i].name)
+      if (i == ct_size)
        error ("bad value %qs for -mcpu switch", alpha_cpu_string);
     }
 
   if (alpha_tune_string)
     {
-      for (i = 0; cpu_table [i].name; i++)
+      for (i = 0; i < ct_size; i++)
        if (! strcmp (alpha_tune_string, cpu_table [i].name))
          {
            alpha_tune = cpu_table [i].processor;
            break;
          }
-      if (! cpu_table [i].name)
+      if (i == ct_size)
        error ("bad value %qs for -mcpu switch", alpha_tune_string);
     }
 
@@ -583,7 +579,7 @@ resolve_reload_operand (rtx op)
       rtx tmp = op;
       if (GET_CODE (tmp) == SUBREG)
        tmp = SUBREG_REG (tmp);
-      if (GET_CODE (tmp) == REG
+      if (REG_P (tmp)
          && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
        {
          op = reg_equiv_memory_loc[REGNO (tmp)];
@@ -643,8 +639,8 @@ direct_return (void)
          && reload_completed
          && alpha_sa_size () == 0
          && get_frame_size () == 0
-         && current_function_outgoing_args_size == 0
-         && current_function_pretend_args_size == 0);
+         && crtl->outgoing_args_size == 0
+         && crtl->args.pretend_args_size == 0);
 }
 
 /* Return the ADDR_VEC associated with a tablejump insn.  */
@@ -660,7 +656,7 @@ alpha_tablejump_addr_vec (rtx insn)
   tmp = NEXT_INSN (tmp);
   if (!tmp)
     return NULL_RTX;
-  if (GET_CODE (tmp) == JUMP_INSN
+  if (JUMP_P (tmp)
       && GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)
     return PATTERN (tmp);
   return NULL_RTX;
@@ -708,7 +704,7 @@ tls_symbolic_operand_type (rtx symbol)
   enum tls_model model;
 
   if (GET_CODE (symbol) != SYMBOL_REF)
-    return 0;
+    return TLS_MODEL_NONE;
   model = SYMBOL_REF_TLS_MODEL (symbol);
 
   /* Local-exec with a 64-bit size is the same code as initial-exec.  */
@@ -805,13 +801,13 @@ alpha_linkage_symbol_p (const char *symname)
    any of those forms can be surrounded with an AND that clear the
    low-order three bits; this is an "unaligned" access.  */
 
-bool
-alpha_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
+static bool
+alpha_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
 {
   /* If this is an ldq_u type address, discard the outer AND.  */
   if (mode == DImode
       && GET_CODE (x) == AND
-      && GET_CODE (XEXP (x, 1)) == CONST_INT
+      && CONST_INT_P (XEXP (x, 1))
       && INTVAL (XEXP (x, 1)) == -8)
     x = XEXP (x, 0);
 
@@ -853,7 +849,7 @@ alpha_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
        {
          if (! strict
              && NONSTRICT_REG_OK_FP_BASE_P (x)
-             && GET_CODE (ofs) == CONST_INT)
+             && CONST_INT_P (ofs))
            return true;
          if ((strict
               ? STRICT_REG_OK_FOR_BASE_P (x)
@@ -863,9 +859,11 @@ alpha_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
        }
     }
 
-  /* If we're managing explicit relocations, LO_SUM is valid, as
-     are small data symbols.  */
-  else if (TARGET_EXPLICIT_RELOCS)
+  /* If we're managing explicit relocations, LO_SUM is valid, as are small
+     data symbols.  Avoid explicit relocations of modes larger than word
+     mode since i.e. $LC0+8($1) can fold around +/- 32k offset.  */
+  else if (TARGET_EXPLICIT_RELOCS
+          && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
     {
       if (small_symbolic_operand (x, Pmode))
        return true;
@@ -914,9 +912,8 @@ get_tls_get_addr (void)
 /* Try machine-dependent ways of modifying an illegitimate address
    to be legitimate.  If we find one, return the new, valid address.  */
 
-rtx
-alpha_legitimize_address (rtx x, rtx scratch,
-                         enum machine_mode mode ATTRIBUTE_UNUSED)
+static rtx
+alpha_legitimize_address_1 (rtx x, rtx scratch, enum machine_mode mode)
 {
   HOST_WIDE_INT addend;
 
@@ -924,8 +921,8 @@ alpha_legitimize_address (rtx x, rtx scratch,
      valid offset, compute the high part of the constant and add it to
      the register.  Then our address is (plus temp low-part-const).  */
   if (GET_CODE (x) == PLUS
-      && GET_CODE (XEXP (x, 0)) == REG
-      && GET_CODE (XEXP (x, 1)) == CONST_INT
+      && REG_P (XEXP (x, 0))
+      && CONST_INT_P (XEXP (x, 1))
       && ! CONSTANT_ADDRESS_P (XEXP (x, 1)))
     {
       addend = INTVAL (XEXP (x, 1));
@@ -940,7 +937,7 @@ alpha_legitimize_address (rtx x, rtx scratch,
   if (can_create_pseudo_p ()
       && GET_CODE (x) == CONST
       && GET_CODE (XEXP (x, 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+      && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
     {
       addend = INTVAL (XEXP (XEXP (x, 0), 1));
       x = force_reg (Pmode, XEXP (XEXP (x, 0), 0));
@@ -952,10 +949,10 @@ alpha_legitimize_address (rtx x, rtx scratch,
      our address.  */
   if (can_create_pseudo_p ()
       && GET_CODE (x) == PLUS
-      && GET_CODE (XEXP (x, 0)) == REG
+      && REG_P (XEXP (x, 0))
       && GET_CODE (XEXP (x, 1)) == CONST
       && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == CONST_INT)
+      && CONST_INT_P (XEXP (XEXP (XEXP (x, 1), 0), 1)))
     {
       addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1));
       x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0),
@@ -964,8 +961,12 @@ alpha_legitimize_address (rtx x, rtx scratch,
       goto split_addend;
     }
 
-  /* If this is a local symbol, split the address into HIGH/LO_SUM parts.  */
-  if (TARGET_EXPLICIT_RELOCS && symbolic_operand (x, Pmode))
+  /* If this is a local symbol, split the address into HIGH/LO_SUM parts.
+     Avoid modes larger than word mode since i.e. $LC0+8($1) can fold
+     around +/- 32k offset.  */
+  if (TARGET_EXPLICIT_RELOCS
+      && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
+      && symbolic_operand (x, Pmode))
     {
       rtx r0, r16, eqv, tga, tp, insn, dest, seq;
 
@@ -986,7 +987,7 @@ alpha_legitimize_address (rtx x, rtx scratch,
          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);
-         CONST_OR_PURE_CALL_P (insn) = 1;
+         RTL_CONST_CALL_P (insn) = 1;
          use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
 
           insn = get_insns ();
@@ -1007,7 +1008,7 @@ alpha_legitimize_address (rtx x, rtx scratch,
          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);
-         CONST_OR_PURE_CALL_P (insn) = 1;
+         RTL_CONST_CALL_P (insn) = 1;
          use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
 
           insn = get_insns ();
@@ -1106,6 +1107,18 @@ alpha_legitimize_address (rtx x, rtx scratch,
   }
 }
 
+
+/* Try machine-dependent ways of modifying an illegitimate address
+   to be legitimate.  Return X or the new, valid address.  */
+
+static rtx
+alpha_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+                         enum machine_mode mode)
+{
+  rtx new_x = alpha_legitimize_address_1 (x, NULL_RTX, mode);
+  return new_x ? new_x : x;
+}
+
 /* 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.  */
@@ -1211,13 +1224,13 @@ alpha_legitimize_reload_address (rtx x,
   /* We must recognize output that we have already generated ourselves.  */
   if (GET_CODE (x) == PLUS
       && GET_CODE (XEXP (x, 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
-      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+      && REG_P (XEXP (XEXP (x, 0), 0))
+      && CONST_INT_P (XEXP (XEXP (x, 0), 1))
+      && CONST_INT_P (XEXP (x, 1)))
     {
       push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
                   BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
-                  opnum, type);
+                  opnum, (enum reload_type) type);
       return x;
     }
 
@@ -1225,7 +1238,7 @@ alpha_legitimize_reload_address (rtx x,
      splitting the addend across an ldah and the mem insn.  This
      cuts number of extra insns needed from 3 to 1.  */
   if (GET_CODE (x) == PLUS
-      && GET_CODE (XEXP (x, 0)) == REG
+      && 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)
@@ -1248,7 +1261,7 @@ alpha_legitimize_reload_address (rtx x,
 
       push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
                   BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
-                  opnum, type);
+                  opnum, (enum reload_type) type);
       return x;
     }
 
@@ -1260,13 +1273,14 @@ alpha_legitimize_reload_address (rtx x,
    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, int code, int outer_code, int *total,
+                bool speed)
 {
   enum machine_mode mode = GET_MODE (x);
   bool float_mode_p = FLOAT_MODE_P (mode);
   const struct alpha_rtx_cost_data *cost_data;
 
-  if (optimize_size)
+  if (!speed)
     cost_data = &alpha_rtx_cost_size;
   else
     cost_data = &alpha_rtx_cost_data[alpha_tune];
@@ -1311,7 +1325,7 @@ alpha_rtx_costs (rtx x, int code, int outer_code, int *total)
        *total = COSTS_N_INSNS (15);
       else
        /* Otherwise we do a load from the GOT.  */
-       *total = COSTS_N_INSNS (optimize_size ? 1 : alpha_memory_latency);
+       *total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency);
       return true;
 
     case HIGH:
@@ -1326,8 +1340,11 @@ alpha_rtx_costs (rtx x, int code, int outer_code, int *total)
       else if (GET_CODE (XEXP (x, 0)) == MULT
               && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
        {
-         *total = (rtx_cost (XEXP (XEXP (x, 0), 0), outer_code)
-                   + rtx_cost (XEXP (x, 1), outer_code) + COSTS_N_INSNS (1));
+         *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)
+                   + COSTS_N_INSNS (1));
          return true;
        }
       return false;
@@ -1342,7 +1359,7 @@ alpha_rtx_costs (rtx x, int code, int outer_code, int *total)
       return false;
 
     case ASHIFT:
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+      if (CONST_INT_P (XEXP (x, 1))
          && INTVAL (XEXP (x, 1)) <= 3)
        {
          *total = COSTS_N_INSNS (1);
@@ -1375,7 +1392,7 @@ alpha_rtx_costs (rtx x, int code, int outer_code, int *total)
       return false;
 
     case MEM:
-      *total = COSTS_N_INSNS (optimize_size ? 1 : alpha_memory_latency);
+      *total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency);
       return true;
 
     case NEG:
@@ -1403,7 +1420,7 @@ alpha_rtx_costs (rtx x, int code, int outer_code, int *total)
       return false;
 
     case FLOAT_EXTEND:
-      if (GET_CODE (XEXP (x, 0)) == MEM)
+      if (MEM_P (XEXP (x, 0)))
        *total = 0;
       else
        *total = cost_data->fp_add;
@@ -1425,7 +1442,7 @@ get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum)
   rtx base;
   HOST_WIDE_INT disp, offset;
 
-  gcc_assert (GET_CODE (ref) == MEM);
+  gcc_assert (MEM_P (ref));
 
   if (reload_in_progress
       && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
@@ -1470,7 +1487,7 @@ get_unaligned_address (rtx ref)
   rtx base;
   HOST_WIDE_INT offset = 0;
 
-  gcc_assert (GET_CODE (ref) == MEM);
+  gcc_assert (MEM_P (ref));
 
   if (reload_in_progress
       && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
@@ -1506,43 +1523,43 @@ get_unaligned_offset (rtx addr, HOST_WIDE_INT ofs)
 
 /* On the Alpha, all (non-symbolic) constants except zero go into
    a floating-point register via memory.  Note that we cannot
-   return anything that is not a subset of CLASS, and that some
+   return anything that is not a subset of RCLASS, and that some
    symbolic constants cannot be dropped to memory.  */
 
 enum reg_class
-alpha_preferred_reload_class(rtx x, enum reg_class class)
+alpha_preferred_reload_class(rtx x, enum reg_class rclass)
 {
   /* Zero is present in any register class.  */
   if (x == CONST0_RTX (GET_MODE (x)))
-    return class;
+    return rclass;
 
   /* These sorts of constants we can easily drop to memory.  */
-  if (GET_CODE (x) == CONST_INT
+  if (CONST_INT_P (x)
       || GET_CODE (x) == CONST_DOUBLE
       || GET_CODE (x) == CONST_VECTOR)
     {
-      if (class == FLOAT_REGS)
+      if (rclass == FLOAT_REGS)
        return NO_REGS;
-      if (class == ALL_REGS)
+      if (rclass == ALL_REGS)
        return GENERAL_REGS;
-      return class;
+      return rclass;
     }
 
   /* All other kinds of constants should not (and in the case of HIGH
      cannot) be dropped to memory -- instead we use a GENERAL_REGS
      secondary reload.  */
   if (CONSTANT_P (x))
-    return (class == ALL_REGS ? GENERAL_REGS : class);
+    return (rclass == ALL_REGS ? GENERAL_REGS : rclass);
 
-  return class;
+  return rclass;
 }
 
 /* Inform reload about cases where moving X with a mode MODE to a register in
-   CLASS requires an extra scratch or immediate register.  Return the class
+   RCLASS requires an extra scratch or immediate register.  Return the class
    needed for the immediate register.  */
 
 static enum reg_class
-alpha_secondary_reload (bool in_p, rtx x, enum reg_class class,
+alpha_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
                        enum machine_mode mode, secondary_reload_info *sri)
 {
   /* Loading and storing HImode or QImode values to and from memory
@@ -1564,7 +1581,7 @@ alpha_secondary_reload (bool in_p, rtx x, enum reg_class class,
 
   /* We also cannot do integral arithmetic into FP regs, as might result
      from register elimination into a DImode fp register.  */
-  if (class == FLOAT_REGS)
+  if (rclass == FLOAT_REGS)
     {
       if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND)
        return GENERAL_REGS;
@@ -1584,7 +1601,7 @@ alpha_set_memflags_1 (rtx *xp, void *data)
 {
   rtx x = *xp, orig = (rtx) data;
 
-  if (GET_CODE (x) != MEM)
+  if (!MEM_P (x))
     return 0;
 
   MEM_VOLATILE_P (x) = MEM_VOLATILE_P (orig);
@@ -1602,18 +1619,17 @@ alpha_set_memflags_1 (rtx *xp, void *data)
   return -1;
 }
 
-/* Given INSN, which is an INSN list or the PATTERN of a single insn
-   generated to perform a memory operation, look for any MEMs in either
+/* Given SEQ, which is an INSN list, look for any MEMs in either
    a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
    volatile flags from REF into each of the MEMs found.  If REF is not
    a MEM, don't do anything.  */
 
 void
-alpha_set_memflags (rtx insn, rtx ref)
+alpha_set_memflags (rtx seq, rtx ref)
 {
-  rtx *base_ptr;
+  rtx insn;
 
-  if (GET_CODE (ref) != MEM)
+  if (!MEM_P (ref))
     return;
 
   /* This is only called from alpha.md, after having had something
@@ -1626,11 +1642,11 @@ alpha_set_memflags (rtx insn, rtx ref)
       && !MEM_READONLY_P (ref))
     return;
 
-  if (INSN_P (insn))
-    base_ptr = &PATTERN (insn);
-  else
-    base_ptr = &insn;
-  for_each_rtx (base_ptr, alpha_set_memflags_1, (void *) ref);
+  for (insn = seq; insn; insn = NEXT_INSN (insn))
+    if (INSN_P (insn))
+      for_each_rtx (&PATTERN (insn), alpha_set_memflags_1, (void *) ref);
+    else
+      gcc_unreachable ();
 }
 \f
 static rtx alpha_emit_set_const (rtx, enum machine_mode, HOST_WIDE_INT,
@@ -1644,7 +1660,7 @@ static rtx
 alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
                        HOST_WIDE_INT c, int n, bool no_output)
 {
-  HOST_WIDE_INT new;
+  HOST_WIDE_INT new_const;
   int i, bits;
   /* Use a pseudo if highly optimizing and still generating RTL.  */
   rtx subtarget
@@ -1743,15 +1759,15 @@ alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
       /* First, see if minus some low bits, we've an easy load of
         high bits.  */
 
-      new = ((c & 0xffff) ^ 0x8000) - 0x8000;
-      if (new != 0)
+      new_const = ((c & 0xffff) ^ 0x8000) - 0x8000;
+      if (new_const != 0)
        {
-          temp = alpha_emit_set_const (subtarget, mode, c - new, i, no_output);
+          temp = alpha_emit_set_const (subtarget, mode, c - new_const, i, no_output);
          if (temp)
            {
              if (no_output)
                return temp;
-             return expand_binop (mode, add_optab, temp, GEN_INT (new),
+             return expand_binop (mode, add_optab, temp, GEN_INT (new_const),
                                   target, 0, OPTAB_WIDEN);
            }
        }
@@ -1778,12 +1794,12 @@ alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
       if (bits > 0)
        for (; bits > 0; bits--)
          {
-           new = c >> bits;
-           temp = alpha_emit_set_const (subtarget, mode, new, i, no_output);
+           new_const = c >> bits;
+           temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
            if (!temp && c < 0)
              {
-               new = (unsigned HOST_WIDE_INT)c >> bits;
-               temp = alpha_emit_set_const (subtarget, mode, new,
+               new_const = (unsigned HOST_WIDE_INT)c >> bits;
+               temp = alpha_emit_set_const (subtarget, mode, new_const,
                                             i, no_output);
              }
            if (temp)
@@ -1806,12 +1822,12 @@ alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
       if (bits > 0)
        for (; bits > 0; bits--)
          {
-           new = c << bits;
-           temp = alpha_emit_set_const (subtarget, mode, new, i, no_output);
+           new_const = c << bits;
+           temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
            if (!temp)
              {
-               new = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
-               temp = alpha_emit_set_const (subtarget, mode, new,
+               new_const = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
+               temp = alpha_emit_set_const (subtarget, mode, new_const,
                                             i, no_output);
              }
            if (temp)
@@ -1832,12 +1848,12 @@ alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
       if (bits > 0)
        for (; bits > 0; bits--)
          {
-           new = c << bits;
-           temp = alpha_emit_set_const (subtarget, mode, new, i, no_output);
+           new_const = c << bits;
+           temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
            if (!temp)
              {
-               new = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
-               temp = alpha_emit_set_const (subtarget, mode, new,
+               new_const = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
+               temp = alpha_emit_set_const (subtarget, mode, new_const,
                                             i, no_output);
              }
            if (temp)
@@ -1855,25 +1871,25 @@ alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
      constant except that all bytes that are 0 are changed to be 0xff.  If we
      can, then we can do a ZAPNOT to obtain the desired constant.  */
 
-  new = c;
+  new_const = c;
   for (i = 0; i < 64; i += 8)
-    if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
-      new |= (HOST_WIDE_INT) 0xff << i;
+    if ((new_const & ((HOST_WIDE_INT) 0xff << i)) == 0)
+      new_const |= (HOST_WIDE_INT) 0xff << i;
 
   /* We are only called for SImode and DImode.  If this is SImode, ensure that
      we are sign extended to a full word.  */
 
   if (mode == SImode)
-    new = ((new & 0xffffffff) ^ 0x80000000) - 0x80000000;
+    new_const = ((new_const & 0xffffffff) ^ 0x80000000) - 0x80000000;
 
-  if (new != c)
+  if (new_const != c)
     {
-      temp = alpha_emit_set_const (subtarget, mode, new, n - 1, no_output);
+      temp = alpha_emit_set_const (subtarget, mode, new_const, n - 1, no_output);
       if (temp)
        {
          if (no_output)
            return temp;
-         return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
+         return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new_const),
                               target, 0, OPTAB_WIDEN);
        }
     }
@@ -1900,7 +1916,7 @@ alpha_emit_set_const (rtx target, enum machine_mode mode,
   /* If we can't make any pseudos, TARGET is an SImode hard register, we
      can't load this constant in one insn, do this in DImode.  */
   if (!can_create_pseudo_p () && mode == SImode
-      && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER)
+      && REG_P (target) && REGNO (target) < FIRST_PSEUDO_REGISTER)
     {
       result = alpha_emit_set_const_1 (target, mode, c, 1, no_output);
       if (result)
@@ -2013,7 +2029,7 @@ alpha_extract_integer (rtx x, HOST_WIDE_INT *p0, HOST_WIDE_INT *p1)
     x = simplify_subreg (DImode, x, GET_MODE (x), 0);
 
 
-  if (GET_CODE (x) == CONST_INT)
+  if (CONST_INT_P (x))
     {
       i0 = INTVAL (x);
       i1 = -(i0 < 0);
@@ -2046,11 +2062,22 @@ alpha_legitimate_constant_p (rtx x)
 
   switch (GET_CODE (x))
     {
-    case CONST:
     case LABEL_REF:
     case HIGH:
       return true;
 
+    case CONST:
+      if (GET_CODE (XEXP (x, 0)) == PLUS
+         && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+       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;
@@ -2118,17 +2145,17 @@ alpha_split_const_mov (enum machine_mode mode, rtx *operands)
 bool
 alpha_expand_mov (enum machine_mode mode, rtx *operands)
 {
+  rtx tmp;
+
   /* If the output is not a register, the input must be.  */
-  if (GET_CODE (operands[0]) == MEM
+  if (MEM_P (operands[0])
       && ! reg_or_0_operand (operands[1], mode))
     operands[1] = force_reg (mode, operands[1]);
 
   /* Allow legitimize_address to perform some simplifications.  */
   if (mode == Pmode && symbolic_operand (operands[1], mode))
     {
-      rtx tmp;
-
-      tmp = alpha_legitimize_address (operands[1], operands[0], mode);
+      tmp = alpha_legitimize_address_1 (operands[1], operands[0], mode);
       if (tmp)
        {
          if (tmp == operands[0])
@@ -2143,7 +2170,7 @@ alpha_expand_mov (enum machine_mode mode, rtx *operands)
     return false;
 
   /* Split large integers.  */
-  if (GET_CODE (operands[1]) == CONST_INT
+  if (CONST_INT_P (operands[1])
       || GET_CODE (operands[1]) == CONST_DOUBLE
       || GET_CODE (operands[1]) == CONST_VECTOR)
     {
@@ -2152,14 +2179,18 @@ alpha_expand_mov (enum machine_mode mode, rtx *operands)
     }
 
   /* Otherwise we've nothing left but to drop the thing to memory.  */
-  operands[1] = force_const_mem (mode, operands[1]);
+  tmp = force_const_mem (mode, operands[1]);
+
+  if (tmp == NULL_RTX)
+    return false;
+
   if (reload_in_progress)
     {
-      emit_move_insn (operands[0], XEXP (operands[1], 0));
-      operands[1] = replace_equiv_address (operands[1], operands[0]);
+      emit_move_insn (operands[0], XEXP (tmp, 0));
+      operands[1] = replace_equiv_address (tmp, operands[0]);
     }
   else
-    operands[1] = validize_mem (operands[1]);
+    operands[1] = validize_mem (tmp);
   return false;
 }
 
@@ -2201,7 +2232,7 @@ alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
              get_aligned_mem (operands[1], &aligned_mem, &bitnum);
 
              subtarget = operands[0];
-             if (GET_CODE (subtarget) == REG)
+             if (REG_P (subtarget))
                subtarget = gen_lowpart (DImode, subtarget), copyout = false;
              else
                subtarget = gen_reg_rtx (DImode), copyout = true;
@@ -2231,7 +2262,7 @@ alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
          temp2 = gen_reg_rtx (DImode);
 
          subtarget = operands[0];
-         if (GET_CODE (subtarget) == REG)
+         if (REG_P (subtarget))
            subtarget = gen_lowpart (DImode, subtarget), copyout = false;
          else
            subtarget = gen_reg_rtx (DImode), copyout = true;
@@ -2399,19 +2430,20 @@ alpha_emit_floatuns (rtx operands[2])
 
 /* Generate the comparison for a conditional branch.  */
 
-rtx
-alpha_emit_conditional_branch (enum rtx_code code)
+void
+alpha_emit_conditional_branch (rtx operands[], enum machine_mode cmp_mode)
 {
   enum rtx_code cmp_code, branch_code;
-  enum machine_mode cmp_mode, branch_mode = VOIDmode;
-  rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
+  enum machine_mode branch_mode = VOIDmode;
+  enum rtx_code code = GET_CODE (operands[0]);
+  rtx op0 = operands[1], op1 = operands[2];
   rtx tem;
 
-  if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
+  if (cmp_mode == TFmode)
     {
       op0 = alpha_emit_xfloating_compare (&code, op0, op1);
       op1 = const0_rtx;
-      alpha_compare.fp_p = 0;
+      cmp_mode = DImode;
     }
 
   /* The general case: fold the comparison code to the types of compares
@@ -2432,7 +2464,7 @@ alpha_emit_conditional_branch (enum rtx_code code)
 
     case GE:  case GT: case GEU:  case GTU:
       /* For FP, we swap them, for INT, we reverse them.  */
-      if (alpha_compare.fp_p)
+      if (cmp_mode == DFmode)
        {
          cmp_code = swap_condition (code);
          branch_code = NE;
@@ -2449,10 +2481,9 @@ alpha_emit_conditional_branch (enum rtx_code code)
       gcc_unreachable ();
     }
 
-  if (alpha_compare.fp_p)
+  if (cmp_mode == DFmode)
     {
-      cmp_mode = DFmode;
-      if (flag_unsafe_math_optimizations)
+      if (flag_unsafe_math_optimizations && cmp_code != UNORDERED)
        {
          /* When we are not as concerned about non-finite values, and we
             are comparing against zero, we can branch directly.  */
@@ -2476,8 +2507,6 @@ alpha_emit_conditional_branch (enum rtx_code code)
     }
   else
     {
-      cmp_mode = DImode;
-
       /* The following optimizations are only for signed compares.  */
       if (code != LEU && code != LTU && code != GEU && code != GTU)
        {
@@ -2491,10 +2520,10 @@ alpha_emit_conditional_branch (enum rtx_code code)
          /* ??? Don't do this when comparing against symbols, otherwise
             we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
             be declared false out of hand (at least for non-weak).  */
-         else if (GET_CODE (op1) == CONST_INT
+         else if (CONST_INT_P (op1)
                   && (code == EQ || code == NE)
                   && !(symbolic_operand (op0, VOIDmode)
-                       || (GET_CODE (op0) == REG && REG_POINTER (op0))))
+                       || (REG_P (op0) && REG_POINTER (op0))))
            {
              rtx n_op1 = GEN_INT (-INTVAL (op1));
 
@@ -2519,36 +2548,38 @@ alpha_emit_conditional_branch (enum rtx_code code)
       emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
     }
 
-  /* Zero the operands.  */
-  memset (&alpha_compare, 0, sizeof (alpha_compare));
-
-  /* Return the branch comparison.  */
-  return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
+  /* Emit the branch instruction.  */
+  tem = gen_rtx_SET (VOIDmode, pc_rtx,
+                    gen_rtx_IF_THEN_ELSE (VOIDmode,
+                                          gen_rtx_fmt_ee (branch_code,
+                                                          branch_mode, tem,
+                                                          CONST0_RTX (cmp_mode)),
+                                          gen_rtx_LABEL_REF (VOIDmode,
+                                                             operands[3]),
+                                          pc_rtx));
+  emit_jump_insn (tem);
 }
 
 /* Certain simplifications can be done to make invalid setcc operations
    valid.  Return the final comparison, or NULL if we can't work.  */
 
-rtx
-alpha_emit_setcc (enum rtx_code code)
+bool
+alpha_emit_setcc (rtx operands[], enum machine_mode cmp_mode)
 {
   enum rtx_code cmp_code;
-  rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
-  int fp_p = alpha_compare.fp_p;
+  enum rtx_code code = GET_CODE (operands[1]);
+  rtx op0 = operands[2], op1 = operands[3];
   rtx tmp;
 
-  /* Zero the operands.  */
-  memset (&alpha_compare, 0, sizeof (alpha_compare));
-
-  if (fp_p && GET_MODE (op0) == TFmode)
+  if (cmp_mode == TFmode)
     {
       op0 = alpha_emit_xfloating_compare (&code, op0, op1);
       op1 = const0_rtx;
-      fp_p = 0;
+      cmp_mode = DImode;
     }
 
-  if (fp_p && !TARGET_FIX)
-    return NULL_RTX;
+  if (cmp_mode == DFmode && !TARGET_FIX)
+    return 0;
 
   /* The general case: fold the comparison code to the types of compares
      that we have, choosing the branch as necessary.  */
@@ -2559,12 +2590,12 @@ alpha_emit_setcc (enum rtx_code code)
     case EQ:  case LE:  case LT:  case LEU:  case LTU:
     case UNORDERED:
       /* We have these compares.  */
-      if (fp_p)
+      if (cmp_mode == DFmode)
        cmp_code = code, code = NE;
       break;
 
     case NE:
-      if (!fp_p && op1 == const0_rtx)
+      if (cmp_mode == DImode && op1 == const0_rtx)
        break;
       /* FALLTHRU */
 
@@ -2576,10 +2607,10 @@ alpha_emit_setcc (enum rtx_code code)
     case GE:  case GT: case GEU:  case GTU:
       /* These normally need swapping, but for integer zero we have
         special patterns that recognize swapped operands.  */
-      if (!fp_p && op1 == const0_rtx)
+      if (cmp_mode == DImode && op1 == const0_rtx)
        break;
       code = swap_condition (code);
-      if (fp_p)
+      if (cmp_mode == DFmode)
        cmp_code = code, code = NE;
       tmp = op0, op0 = op1, op1 = tmp;
       break;
@@ -2588,7 +2619,7 @@ alpha_emit_setcc (enum rtx_code code)
       gcc_unreachable ();
     }
 
-  if (!fp_p)
+  if (cmp_mode == DImode)
     {
       if (!register_operand (op0, DImode))
        op0 = force_reg (DImode, op0);
@@ -2599,18 +2630,18 @@ alpha_emit_setcc (enum rtx_code code)
   /* Emit an initial compare instruction, if necessary.  */
   if (cmp_code != UNKNOWN)
     {
-      enum machine_mode mode = fp_p ? DFmode : DImode;
-
-      tmp = gen_reg_rtx (mode);
+      tmp = gen_reg_rtx (cmp_mode);
       emit_insn (gen_rtx_SET (VOIDmode, tmp,
-                             gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
+                             gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1)));
 
-      op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
+      op0 = cmp_mode != DImode ? gen_lowpart (DImode, tmp) : tmp;
       op1 = const0_rtx;
     }
 
-  /* Return the setcc comparison.  */
-  return gen_rtx_fmt_ee (code, DImode, op0, op1);
+  /* Emit the setcc instruction.  */
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+                         gen_rtx_fmt_ee (code, DImode, op0, op1)));
+  return true;
 }
 
 
@@ -2626,20 +2657,17 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
 {
   enum rtx_code code = GET_CODE (cmp);
   enum rtx_code cmov_code = NE;
-  rtx op0 = alpha_compare.op0;
-  rtx op1 = alpha_compare.op1;
-  int fp_p = alpha_compare.fp_p;
+  rtx op0 = XEXP (cmp, 0);
+  rtx op1 = XEXP (cmp, 1);
   enum machine_mode cmp_mode
     = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
-  enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
   enum machine_mode cmov_mode = VOIDmode;
   int local_fast_math = flag_unsafe_math_optimizations;
   rtx tem;
 
-  /* Zero the operands.  */
-  memset (&alpha_compare, 0, sizeof (alpha_compare));
+  gcc_assert (cmp_mode == DFmode || cmp_mode == DImode);
 
-  if (fp_p != FLOAT_MODE_P (mode))
+  if (FLOAT_MODE_P (cmp_mode) != FLOAT_MODE_P (mode))
     {
       enum rtx_code cmp_code;
 
@@ -2666,7 +2694,7 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
        case GE: case GT: case GEU: case GTU:
          /* These normally need swapping, but for integer zero we have
             special patterns that recognize swapped operands.  */
-         if (!fp_p && op1 == const0_rtx)
+         if (cmp_mode == DImode && op1 == const0_rtx)
            cmp_code = code, code = NE;
          else
            {
@@ -2680,22 +2708,21 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
          gcc_unreachable ();
        }
 
-      tem = gen_reg_rtx (cmp_op_mode);
+      tem = gen_reg_rtx (cmp_mode);
       emit_insn (gen_rtx_SET (VOIDmode, tem,
-                             gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
+                             gen_rtx_fmt_ee (cmp_code, cmp_mode,
                                              op0, op1)));
 
-      cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
-      op0 = gen_lowpart (cmp_op_mode, tem);
-      op1 = CONST0_RTX (cmp_op_mode);
-      fp_p = !fp_p;
+      cmp_mode = cmp_mode == DImode ? DFmode : DImode;
+      op0 = gen_lowpart (cmp_mode, tem);
+      op1 = CONST0_RTX (cmp_mode);
       local_fast_math = 1;
     }
 
   /* We may be able to use a conditional move directly.
      This avoids emitting spurious compares.  */
   if (signed_comparison_operator (cmp, VOIDmode)
-      && (!fp_p || local_fast_math)
+      && (cmp_mode == DImode || local_fast_math)
       && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
     return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
 
@@ -2732,7 +2759,7 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
       gcc_unreachable ();
     }
 
-  if (!fp_p)
+  if (cmp_mode == DImode)
     {
       if (!reg_or_0_operand (op0, DImode))
        op0 = force_reg (DImode, op0);
@@ -2743,12 +2770,12 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
   /* ??? We mark the branch mode to be CCmode to prevent the compare
      and cmov from being combined, since the compare insn follows IEEE
      rules that the cmov does not.  */
-  if (fp_p && !local_fast_math)
+  if (cmp_mode == DFmode && !local_fast_math)
     cmov_mode = CCmode;
 
-  tem = gen_reg_rtx (cmp_op_mode);
-  emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
-  return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
+  tem = gen_reg_rtx (cmp_mode);
+  emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_mode, op0, op1));
+  return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_mode));
 }
 
 /* Simplify a conditional move of two constants into a setcc with
@@ -2842,7 +2869,7 @@ alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond,
 /* Look up the function X_floating library function name for the
    given operation.  */
 
-struct xfloating_op GTY(())
+struct GTY(()) xfloating_op
 {
   const enum rtx_code code;
   const char *const GTY((skip)) osf_func;
@@ -2979,7 +3006,7 @@ alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
          break;
 
        case VOIDmode:
-         gcc_assert (GET_CODE (operands[i]) == CONST_INT);
+         gcc_assert (CONST_INT_P (operands[i]));
          /* FALLTHRU */
        case DImode:
          reg = gen_rtx_REG (DImode, regno);
@@ -3013,7 +3040,7 @@ alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
   tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
                                        const0_rtx, const0_rtx));
   CALL_INSN_FUNCTION_USAGE (tmp) = usage;
-  CONST_OR_PURE_CALL_P (tmp) = 1;
+  RTL_CONST_CALL_P (tmp) = 1;
 
   tmp = get_insns ();
   end_sequence ();
@@ -3047,7 +3074,7 @@ static rtx
 alpha_emit_xfloating_compare (enum rtx_code *pcode, rtx op0, rtx op1)
 {
   enum rtx_code cmp_code, res_code;
-  rtx func, out, operands[2];
+  rtx func, out, operands[2], note;
 
   /* X_floating library comparison functions return
           -1  unordered
@@ -3087,10 +3114,13 @@ alpha_emit_xfloating_compare (enum rtx_code *pcode, rtx op0, rtx op1)
   operands[1] = op1;
   out = gen_reg_rtx (DImode);
 
-  /* ??? Strange mode for equiv because what's actually returned
-     is -1,0,1, not a proper boolean value.  */
-  alpha_emit_xfloating_libcall (func, out, operands, 2,
-                               gen_rtx_fmt_ee (cmp_code, CCmode, op0, op1));
+  /* 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);
+  alpha_emit_xfloating_libcall (func, out, operands, 2, note);
 
   return out;
 }
@@ -3529,7 +3559,7 @@ alpha_expand_unaligned_store (rtx dst, rtx src,
              emit_insn (gen_insll_le (insl, gen_lowpart (SImode, src), addr));
              break;
            case 8:
-             emit_insn (gen_insql_le (insl, src, addr));
+             emit_insn (gen_insql_le (insl, gen_lowpart (DImode, src), addr));
              break;
            }
        }
@@ -3802,11 +3832,11 @@ alpha_expand_block_move (rtx operands[])
   /* Look for additional alignment information from recorded register info.  */
 
   tmp = XEXP (orig_src, 0);
-  if (GET_CODE (tmp) == REG)
+  if (REG_P (tmp))
     src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
   else if (GET_CODE (tmp) == PLUS
-          && GET_CODE (XEXP (tmp, 0)) == REG
-          && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
+          && REG_P (XEXP (tmp, 0))
+          && CONST_INT_P (XEXP (tmp, 1)))
     {
       unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
       unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
@@ -3823,11 +3853,11 @@ alpha_expand_block_move (rtx operands[])
     }
 
   tmp = XEXP (orig_dst, 0);
-  if (GET_CODE (tmp) == REG)
+  if (REG_P (tmp))
     dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
   else if (GET_CODE (tmp) == PLUS
-          && GET_CODE (XEXP (tmp, 0)) == REG
-          && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
+          && REG_P (XEXP (tmp, 0))
+          && CONST_INT_P (XEXP (tmp, 1)))
     {
       unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
       unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
@@ -4046,11 +4076,11 @@ alpha_expand_block_clear (rtx operands[])
 
   /* Look for stricter alignment.  */
   tmp = XEXP (orig_dst, 0);
-  if (GET_CODE (tmp) == REG)
+  if (REG_P (tmp))
     align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
   else if (GET_CODE (tmp) == PLUS
-          && GET_CODE (XEXP (tmp, 0)) == REG
-          && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
+          && REG_P (XEXP (tmp, 0))
+          && CONST_INT_P (XEXP (tmp, 1)))
     {
       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
@@ -4377,7 +4407,7 @@ emit_unlikely_jump (rtx cond, rtx label)
 
   x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
   x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
-  REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
+  add_reg_note (x, REG_BR_PROB, very_unlikely);
 }
 
 /* A subroutine of the atomic operation splitters.  Emit a load-locked
@@ -4462,7 +4492,12 @@ alpha_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
   emit_load_locked (mode, before, mem);
 
   if (code == NOT)
-    x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
+    {
+      x = gen_rtx_AND (mode, before, val);
+      emit_insn (gen_rtx_SET (VOIDmode, val, x));
+
+      x = gen_rtx_NOT (mode, val);
+    }
   else
     x = gen_rtx_fmt_ee (code, mode, before, val);
   if (after)
@@ -4596,8 +4631,6 @@ 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);
 
-  emit_insn (gen_memory_barrier ());
-
   label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
   emit_label (XEXP (label, 0));
 
@@ -4607,6 +4640,8 @@ alpha_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
 
   x = gen_rtx_EQ (DImode, cond, const0_rtx);
   emit_unlikely_jump (x, label);
+
+  emit_insn (gen_memory_barrier ());
 }
 
 void
@@ -4645,7 +4680,6 @@ alpha_split_lock_test_and_set_12 (enum machine_mode mode, rtx dest, rtx addr,
   mem = gen_rtx_MEM (DImode, align);
   MEM_VOLATILE_P (mem) = 1;
 
-  emit_insn (gen_memory_barrier ());
   label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
   emit_label (XEXP (label, 0));
 
@@ -4669,6 +4703,8 @@ alpha_split_lock_test_and_set_12 (enum machine_mode mode, rtx dest, rtx addr,
 
   x = gen_rtx_EQ (DImode, scratch, const0_rtx);
   emit_unlikely_jump (x, label);
+
+  emit_insn (gen_memory_barrier ());
 }
 \f
 /* Adjust the cost of a scheduling dependency.  Return the new cost of
@@ -4727,7 +4763,7 @@ alpha_multipass_dfa_lookahead (void)
 \f
 /* Machine-specific function data.  */
 
-struct machine_function GTY(())
+struct GTY(()) machine_function
 {
   /* For unicosmk.  */
   /* List of call information words for calls from this function.  */
@@ -5034,7 +5070,7 @@ print_operand (FILE *file, rtx x, int code)
            x = XVECEXP (x, 0, 0);
            lituse = "lituse_tlsldm";
          }
-       else if (GET_CODE (x) == CONST_INT)
+       else if (CONST_INT_P (x))
          lituse = "lituse_jsr";
        else
          {
@@ -5063,7 +5099,7 @@ print_operand (FILE *file, rtx x, int code)
       break;
     case 'r':
       /* If this operand is the constant zero, write it as "$31".  */
-      if (GET_CODE (x) == REG)
+      if (REG_P (x))
        fprintf (file, "%s", reg_names[REGNO (x)]);
       else if (x == CONST0_RTX (GET_MODE (x)))
        fprintf (file, "$31");
@@ -5073,7 +5109,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'R':
       /* Similar, but for floating-point.  */
-      if (GET_CODE (x) == REG)
+      if (REG_P (x))
        fprintf (file, "%s", reg_names[REGNO (x)]);
       else if (x == CONST0_RTX (GET_MODE (x)))
        fprintf (file, "$f31");
@@ -5083,7 +5119,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'N':
       /* Write the 1's complement of a constant.  */
-      if (GET_CODE (x) != CONST_INT)
+      if (!CONST_INT_P (x))
        output_operand_lossage ("invalid %%N value");
 
       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
@@ -5091,7 +5127,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'P':
       /* Write 1 << C, for a constant C.  */
-      if (GET_CODE (x) != CONST_INT)
+      if (!CONST_INT_P (x))
        output_operand_lossage ("invalid %%P value");
 
       fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
@@ -5099,7 +5135,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'h':
       /* Write the high-order 16 bits of a constant, sign-extended.  */
-      if (GET_CODE (x) != CONST_INT)
+      if (!CONST_INT_P (x))
        output_operand_lossage ("invalid %%h value");
 
       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
@@ -5107,7 +5143,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'L':
       /* Write the low-order 16 bits of a constant, sign-extended.  */
-      if (GET_CODE (x) != CONST_INT)
+      if (!CONST_INT_P (x))
        output_operand_lossage ("invalid %%L value");
 
       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
@@ -5136,7 +5172,7 @@ print_operand (FILE *file, rtx x, int code)
          fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
        }
 
-      else if (GET_CODE (x) == CONST_INT)
+      else if (CONST_INT_P (x))
        {
          HOST_WIDE_INT mask = 0, value = INTVAL (x);
 
@@ -5152,7 +5188,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'M':
       /* 'b', 'w', 'l', or 'q' as the value of the constant.  */
-      if (GET_CODE (x) != CONST_INT
+      if (!CONST_INT_P (x)
          || (INTVAL (x) != 8 && INTVAL (x) != 16
              && INTVAL (x) != 32 && INTVAL (x) != 64))
        output_operand_lossage ("invalid %%M value");
@@ -5166,7 +5202,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'U':
       /* Similar, except do it from the mask.  */
-      if (GET_CODE (x) == CONST_INT)
+      if (CONST_INT_P (x))
        {
          HOST_WIDE_INT value = INTVAL (x);
 
@@ -5206,7 +5242,7 @@ print_operand (FILE *file, rtx x, int code)
       /* Write the constant value divided by 8 for little-endian mode or
         (56 - value) / 8 for big-endian mode.  */
 
-      if (GET_CODE (x) != CONST_INT
+      if (!CONST_INT_P (x)
          || (unsigned HOST_WIDE_INT) INTVAL (x) >= (WORDS_BIG_ENDIAN
                                                     ? 56
                                                     : 64)
@@ -5222,7 +5258,7 @@ print_operand (FILE *file, rtx x, int code)
     case 'S':
       /* Same, except compute (64 - c) / 8 */
 
-      if (GET_CODE (x) != CONST_INT
+      if (!CONST_INT_P (x)
          && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
          && (INTVAL (x) & 7) != 8)
        output_operand_lossage ("invalid %%s value");
@@ -5292,14 +5328,14 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'A':
       /* Write "_u" for unaligned access.  */
-      if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
+      if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND)
        fprintf (file, "_u");
       break;
 
     case 0:
-      if (GET_CODE (x) == REG)
+      if (REG_P (x))
        fprintf (file, "%s", reg_names[REGNO (x)]);
-      else if (GET_CODE (x) == MEM)
+      else if (MEM_P (x))
        output_address (XEXP (x, 0));
       else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
        {
@@ -5333,7 +5369,7 @@ print_operand_address (FILE *file, rtx addr)
     addr = XEXP (addr, 0);
 
   if (GET_CODE (addr) == PLUS
-      && GET_CODE (XEXP (addr, 1)) == CONST_INT)
+      && CONST_INT_P (XEXP (addr, 1)))
     {
       offset = INTVAL (XEXP (addr, 1));
       addr = XEXP (addr, 0);
@@ -5446,7 +5482,7 @@ void
 alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
                             int fnofs, int cxtofs, int jmpofs)
 {
-  rtx temp, temp1, addr;
+  rtx addr;
   /* VMS really uses DImode pointers in memory at this point.  */
   enum machine_mode mode = TARGET_ABI_OPEN_VMS ? Pmode : ptr_mode;
 
@@ -5461,31 +5497,9 @@ alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
   addr = memory_address (mode, plus_constant (tramp, cxtofs));
   emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
 
-  /* This has been disabled since the hint only has a 32k range, and in
-     no existing OS is the stack within 32k of the text segment.  */
-  if (0 && jmpofs >= 0)
-    {
-      /* Compute hint value.  */
-      temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
-      temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
-                          OPTAB_WIDEN);
-      temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
-                          build_int_cst (NULL_TREE, 2), NULL_RTX, 1);
-      temp = expand_and (SImode, gen_lowpart (SImode, temp),
-                        GEN_INT (0x3fff), 0);
-
-      /* Merge in the hint.  */
-      addr = memory_address (SImode, plus_constant (tramp, jmpofs));
-      temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
-      temp1 = expand_and (SImode, temp1, GEN_INT (0xffffc000), NULL_RTX);
-      temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
-                           OPTAB_WIDEN);
-      emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
-    }
-
 #ifdef ENABLE_EXECUTE_STACK
   emit_library_call (init_one_libfunc ("__enable_execute_stack"),
-                    0, VOIDmode, 1, tramp, Pmode);
+                    LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
 #endif
 
   if (jmpofs >= 0)
@@ -5727,15 +5741,15 @@ function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
                enum machine_mode mode)
 {
   unsigned int regnum, dummy;
-  enum mode_class class;
+  enum mode_class mclass;
 
   gcc_assert (!valtype || !alpha_return_in_memory (valtype, func));
 
   if (valtype)
     mode = TYPE_MODE (valtype);
 
-  class = GET_MODE_CLASS (mode);
-  switch (class)
+  mclass = GET_MODE_CLASS (mode);
+  switch (mclass)
     {
     case MODE_INT:
       PROMOTE_MODE (mode, dummy, valtype);
@@ -5788,24 +5802,28 @@ alpha_build_builtin_va_list (void)
     return ptr_type_node;
 
   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
-  type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
+  type_decl = build_decl (BUILTINS_LOCATION,
+                         TYPE_DECL, get_identifier ("__va_list_tag"), record);
   TREE_CHAIN (record) = type_decl;
   TYPE_NAME (record) = type_decl;
 
   /* C++? SET_IS_AGGR_TYPE (record, 1); */
 
   /* Dummy field to prevent alignment warnings.  */
-  space = build_decl (FIELD_DECL, NULL_TREE, integer_type_node);
+  space = build_decl (BUILTINS_LOCATION,
+                     FIELD_DECL, NULL_TREE, integer_type_node);
   DECL_FIELD_CONTEXT (space) = record;
   DECL_ARTIFICIAL (space) = 1;
   DECL_IGNORED_P (space) = 1;
 
-  ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
+  ofs = build_decl (BUILTINS_LOCATION,
+                   FIELD_DECL, get_identifier ("__offset"),
                    integer_type_node);
   DECL_FIELD_CONTEXT (ofs) = record;
   TREE_CHAIN (ofs) = space;
 
-  base = build_decl (FIELD_DECL, get_identifier ("__base"),
+  base = build_decl (BUILTINS_LOCATION,
+                    FIELD_DECL, get_identifier ("__base"),
                     ptr_type_node);
   DECL_FIELD_CONTEXT (base) = record;
   TREE_CHAIN (base) = ofs;
@@ -5821,39 +5839,34 @@ alpha_build_builtin_va_list (void)
 /* Helper function for alpha_stdarg_optimize_hook.  Skip over casts
    and constant additions.  */
 
-static tree
+static gimple
 va_list_skip_additions (tree lhs)
 {
-  tree rhs, stmt;
-
-  if (TREE_CODE (lhs) != SSA_NAME)
-    return lhs;
+  gimple stmt;
 
   for (;;)
     {
+      enum tree_code code;
+
       stmt = SSA_NAME_DEF_STMT (lhs);
 
-      if (TREE_CODE (stmt) == PHI_NODE)
+      if (gimple_code (stmt) == GIMPLE_PHI)
        return stmt;
 
-      if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
-         || GIMPLE_STMT_OPERAND (stmt, 0) != lhs)
-       return lhs;
-
-      rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-      if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
-       rhs = TREE_OPERAND (rhs, 0);
+      if (!is_gimple_assign (stmt)
+         || gimple_assign_lhs (stmt) != lhs)
+       return NULL;
 
-      if ((TREE_CODE (rhs) != NOP_EXPR
-          && TREE_CODE (rhs) != CONVERT_EXPR
-          && ((TREE_CODE (rhs) != PLUS_EXPR
-               && TREE_CODE (rhs) != POINTER_PLUS_EXPR)
-              || TREE_CODE (TREE_OPERAND (rhs, 1)) != INTEGER_CST
-              || !host_integerp (TREE_OPERAND (rhs, 1), 1)))
-         || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
-       return rhs;
+      if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
+       return stmt;
+      code = gimple_assign_rhs_code (stmt);
+      if (!CONVERT_EXPR_CODE_P (code)
+         && ((code != PLUS_EXPR && code != POINTER_PLUS_EXPR)
+             || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST
+             || !host_integerp (gimple_assign_rhs2 (stmt), 1)))
+       return stmt;
 
-      lhs = TREE_OPERAND (rhs, 0);
+      lhs = gimple_assign_rhs1 (stmt);
     }
 }
 
@@ -5876,32 +5889,51 @@ va_list_skip_additions (tree lhs)
    current statement.  */
 
 static bool
-alpha_stdarg_optimize_hook (struct stdarg_info *si, const_tree lhs, const_tree rhs)
+alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
 {
-  tree base, offset, arg1, arg2;
+  tree base, offset, rhs;
   int offset_arg = 1;
+  gimple base_stmt;
 
+  if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+      != GIMPLE_SINGLE_RHS)
+    return false;
+
+  rhs = gimple_assign_rhs1 (stmt);
   while (handled_component_p (rhs))
     rhs = TREE_OPERAND (rhs, 0);
   if (TREE_CODE (rhs) != INDIRECT_REF
       || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
     return false;
 
-  lhs = va_list_skip_additions (TREE_OPERAND (rhs, 0));
-  if (lhs == NULL_TREE
-      || TREE_CODE (lhs) != POINTER_PLUS_EXPR)
+  stmt = va_list_skip_additions (TREE_OPERAND (rhs, 0));
+  if (stmt == NULL
+      || !is_gimple_assign (stmt)
+      || gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR)
     return false;
 
-  base = TREE_OPERAND (lhs, 0);
+  base = gimple_assign_rhs1 (stmt);
   if (TREE_CODE (base) == SSA_NAME)
-    base = va_list_skip_additions (base);
+    {
+      base_stmt = va_list_skip_additions (base);
+      if (base_stmt
+         && is_gimple_assign (base_stmt)
+         && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
+       base = gimple_assign_rhs1 (base_stmt);
+    }
 
   if (TREE_CODE (base) != COMPONENT_REF
       || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
     {
-      base = TREE_OPERAND (lhs, 0);
+      base = gimple_assign_rhs2 (stmt);
       if (TREE_CODE (base) == SSA_NAME)
-       base = va_list_skip_additions (base);
+       {
+         base_stmt = va_list_skip_additions (base);
+         if (base_stmt
+             && is_gimple_assign (base_stmt)
+             && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
+           base = gimple_assign_rhs1 (base_stmt);
+       }
 
       if (TREE_CODE (base) != COMPONENT_REF
          || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
@@ -5915,55 +5947,88 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, const_tree lhs, const_tree r
       || !bitmap_bit_p (si->va_list_vars, DECL_UID (base)))
     return false;
 
-  offset = TREE_OPERAND (lhs, offset_arg);
+  offset = gimple_op (stmt, 1 + offset_arg);
   if (TREE_CODE (offset) == SSA_NAME)
-    offset = va_list_skip_additions (offset);
-
-  if (TREE_CODE (offset) == PHI_NODE)
     {
-      HOST_WIDE_INT sub;
-
-      if (PHI_NUM_ARGS (offset) != 2)
-       goto escapes;
+      gimple offset_stmt = va_list_skip_additions (offset);
 
-      arg1 = va_list_skip_additions (PHI_ARG_DEF (offset, 0));
-      arg2 = va_list_skip_additions (PHI_ARG_DEF (offset, 1));
-      if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR)
+      if (offset_stmt
+         && gimple_code (offset_stmt) == GIMPLE_PHI)
        {
-         tree tem = arg1;
-         arg1 = arg2;
-         arg2 = tem;
+         HOST_WIDE_INT sub;
+         gimple arg1_stmt, arg2_stmt;
+         tree arg1, arg2;
+         enum tree_code code1, code2;
 
-         if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR)
+         if (gimple_phi_num_args (offset_stmt) != 2)
+           goto escapes;
+
+         arg1_stmt
+           = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 0));
+         arg2_stmt
+           = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 1));
+         if (arg1_stmt == NULL
+             || !is_gimple_assign (arg1_stmt)
+             || arg2_stmt == NULL
+             || !is_gimple_assign (arg2_stmt))
+           goto escapes;
+
+         code1 = gimple_assign_rhs_code (arg1_stmt);
+         code2 = gimple_assign_rhs_code (arg2_stmt);
+         if (code1 == COMPONENT_REF
+             && (code2 == MINUS_EXPR || code2 == PLUS_EXPR))
+           /* Do nothing.  */;
+         else if (code2 == COMPONENT_REF
+                  && (code1 == MINUS_EXPR || code1 == PLUS_EXPR))
+           {
+             gimple tem = arg1_stmt;
+             code2 = code1;
+             arg1_stmt = arg2_stmt;
+             arg2_stmt = tem;
+           }
+         else
            goto escapes;
-       }
-      if (!host_integerp (TREE_OPERAND (arg2, 1), 0))
-       goto escapes;
 
-      sub = tree_low_cst (TREE_OPERAND (arg2, 1), 0);
-      if (TREE_CODE (arg2) == MINUS_EXPR)
-       sub = -sub;
-      if (sub < -48 || sub > -32)
-       goto escapes;
+         if (!host_integerp (gimple_assign_rhs2 (arg2_stmt), 0))
+           goto escapes;
 
-      arg2 = va_list_skip_additions (TREE_OPERAND (arg2, 0));
-      if (arg1 != arg2)
-       goto escapes;
+         sub = tree_low_cst (gimple_assign_rhs2 (arg2_stmt), 0);
+         if (code2 == MINUS_EXPR)
+           sub = -sub;
+         if (sub < -48 || sub > -32)
+           goto escapes;
 
-      if (TREE_CODE (arg1) == SSA_NAME)
-       arg1 = va_list_skip_additions (arg1);
+         arg1 = gimple_assign_rhs1 (arg1_stmt);
+         arg2 = gimple_assign_rhs1 (arg2_stmt);
+         if (TREE_CODE (arg2) == SSA_NAME)
+           {
+             arg2_stmt = va_list_skip_additions (arg2);
+             if (arg2_stmt == NULL
+                 || !is_gimple_assign (arg2_stmt)
+                 || gimple_assign_rhs_code (arg2_stmt) != COMPONENT_REF)
+               goto escapes;
+             arg2 = gimple_assign_rhs1 (arg2_stmt);
+           }
+         if (arg1 != arg2)
+           goto escapes;
 
-      if (TREE_CODE (arg1) != COMPONENT_REF
-         || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
-         || get_base_address (arg1) != base)
-       goto escapes;
+         if (TREE_CODE (arg1) != COMPONENT_REF
+             || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
+             || get_base_address (arg1) != base)
+           goto escapes;
 
-      /* Need floating point regs.  */
-      cfun->va_list_fpr_size |= 2;
+         /* Need floating point regs.  */
+         cfun->va_list_fpr_size |= 2;
+         return false;
+       }
+      if (offset_stmt
+         && is_gimple_assign (offset_stmt)
+         && gimple_assign_rhs_code (offset_stmt) == COMPONENT_REF)
+       offset = gimple_assign_rhs1 (offset_stmt);
     }
-  else if (TREE_CODE (offset) != COMPONENT_REF
-          || TREE_OPERAND (offset, 1) != va_list_gpr_counter_field
-          || get_base_address (offset) != base)
+  if (TREE_CODE (offset) != COMPONENT_REF
+      || TREE_OPERAND (offset, 1) != va_list_gpr_counter_field
+      || get_base_address (offset) != base)
     goto escapes;
   else
     /* Need general regs.  */
@@ -6101,13 +6166,13 @@ alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
   if (NUM_ARGS < 6)
     offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
   else
-    offset = -6 * UNITS_PER_WORD + current_function_pretend_args_size;
+    offset = -6 * UNITS_PER_WORD + crtl->args.pretend_args_size;
 
   if (TARGET_ABI_OPEN_VMS)
     {
       nextarg = plus_constant (nextarg, offset);
       nextarg = plus_constant (nextarg, NUM_ARGS * UNITS_PER_WORD);
-      t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist,
+      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
                  make_tree (ptr_type_node, nextarg));
       TREE_SIDE_EFFECTS (t) = 1;
 
@@ -6126,31 +6191,32 @@ alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
       t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
       t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
                  size_int (offset));
-      t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (base_field), base_field, t);
+      t = build2 (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
       TREE_SIDE_EFFECTS (t) = 1;
       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
 
       t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD);
-      t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (offset_field),
-                 offset_field, t);
+      t = build2 (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
       TREE_SIDE_EFFECTS (t) = 1;
       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
     }
 }
 
 static tree
-alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
+alpha_gimplify_va_arg_1 (tree type, tree base, tree offset,
+                        gimple_seq *pre_p)
 {
-  tree type_size, ptr_type, addend, t, addr, internal_post;
+  tree type_size, ptr_type, addend, t, addr;
+  gimple_seq internal_post;
 
   /* If the type could not be passed in registers, skip the block
      reserved for the registers.  */
   if (targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
     {
       t = build_int_cst (TREE_TYPE (offset), 6*8);
-      t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (offset), offset,
-                 build2 (MAX_EXPR, TREE_TYPE (offset), offset, t));
-      gimplify_and_add (t, pre_p);
+      gimplify_assign (offset,
+                      build2 (MAX_EXPR, TREE_TYPE (offset), offset, t),
+                      pre_p);
     }
 
   addend = offset;
@@ -6189,7 +6255,7 @@ alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
                 fold_convert (sizetype, addend));
   internal_post = NULL;
   gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
-  append_to_statement_list (internal_post, pre_p);
+  gimple_seq_add_seq (pre_p, internal_post);
 
   /* Update the offset field.  */
   type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
@@ -6202,15 +6268,15 @@ alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
       t = size_binop (MULT_EXPR, t, size_int (8));
     }
   t = fold_convert (TREE_TYPE (offset), t);
-  t = build2 (GIMPLE_MODIFY_STMT, void_type_node, offset,
-             build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t));
-  gimplify_and_add (t, pre_p);
+  gimplify_assign (offset, build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t),
+                  pre_p);
 
   return build_va_arg_indirect_ref (addr);
 }
 
 static tree
-alpha_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
+alpha_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
+                      gimple_seq *post_p)
 {
   tree offset_field, base_field, offset, base, t, r;
   bool indirect;
@@ -6242,9 +6308,8 @@ alpha_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
   r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
 
   /* Stuff the offset temporary back into its field.  */
-  t = build2 (GIMPLE_MODIFY_STMT, void_type_node, offset_field,
-             fold_convert (TREE_TYPE (offset_field), offset));
-  gimplify_and_add (t, pre_p);
+  gimplify_assign (unshare_expr (offset_field),
+                  fold_convert (TREE_TYPE (offset_field), offset), pre_p);
 
   if (indirect)
     r = build_va_arg_indirect_ref (r);
@@ -6310,7 +6375,7 @@ enum alpha_builtin
   ALPHA_BUILTIN_max
 };
 
-static unsigned int const code_for_builtin[ALPHA_BUILTIN_max] = {
+static enum insn_code const code_for_builtin[ALPHA_BUILTIN_max] = {
   CODE_FOR_builtin_cmpbge,
   CODE_FOR_builtin_extbl,
   CODE_FOR_builtin_extwl,
@@ -6535,7 +6600,7 @@ alpha_expand_builtin (tree exp, rtx target,
 
       insn_op = &insn_data[icode].operand[arity + nonvoid];
 
-      op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
+      op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
 
       if (!(*insn_op->predicate) (op[arity], insn_op->mode))
        op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
@@ -6790,7 +6855,7 @@ 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_convert (long_integer_type_node, val);
+  return fold_build1 (VIEW_CONVERT_EXPR, long_integer_type_node, val);
 }
 
 static tree
@@ -7091,7 +7156,7 @@ alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
   /* When outputting a thunk, we don't have valid register life info,
      but assemble_start_function wants to output .frame and .mask
      directives.  */
-  if (current_function_is_thunk)
+  if (cfun->is_thunk)
     {
       *imaskP = 0;
       *fmaskP = 0;
@@ -7114,7 +7179,7 @@ alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
       }
 
   /* We need to restore these for the handler.  */
-  if (current_function_calls_eh_return)
+  if (crtl->calls_eh_return)
     {
       for (i = 0; ; ++i)
        {
@@ -7167,8 +7232,8 @@ alpha_sa_size (void)
 
       alpha_procedure_type
        = (sa_size || get_frame_size() != 0
-          || current_function_outgoing_args_size
-          || current_function_stdarg || current_function_calls_alloca
+          || crtl->outgoing_args_size
+          || cfun->stdarg || cfun->calls_alloca
           || frame_pointer_needed)
          ? PT_STACK : PT_REGISTER;
 
@@ -7201,9 +7266,9 @@ alpha_sa_size (void)
 
       vms_base_regno
        = (frame_pointer_needed
-          || current_function_has_nonlocal_label
+          || cfun->has_nonlocal_label
           || alpha_procedure_type == PT_STACK
-          || current_function_outgoing_args_size)
+          || crtl->outgoing_args_size)
          ? REG_PV : HARD_FRAME_POINTER_REGNUM;
 
       /* If we want to copy PV into FP, we need to find some register
@@ -7248,7 +7313,7 @@ alpha_initial_elimination_offset (unsigned int from,
   HOST_WIDE_INT ret;
 
   ret = alpha_sa_size ();
-  ret += ALPHA_ROUND (current_function_outgoing_args_size);
+  ret += ALPHA_ROUND (crtl->outgoing_args_size);
 
   switch (from)
     {
@@ -7257,8 +7322,8 @@ alpha_initial_elimination_offset (unsigned int from,
 
     case ARG_POINTER_REGNUM:
       ret += (ALPHA_ROUND (get_frame_size ()
-                          + current_function_pretend_args_size)
-             - current_function_pretend_args_size);
+                          + crtl->args.pretend_args_size)
+             - crtl->args.pretend_args_size);
       break;
 
     default:
@@ -7284,7 +7349,7 @@ alpha_using_fp (void)
 
 #if TARGET_ABI_OPEN_VMS
 
-const struct attribute_spec vms_attribute_table[] =
+static const struct attribute_spec vms_attribute_table[] =
 {
   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
   { "overlaid",   0, 0, true,  false, false, NULL },
@@ -7317,18 +7382,18 @@ alpha_does_function_need_gp (void)
     return 0;
 
   /* We need the gp to load the address of __mcount.  */
-  if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
+  if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
     return 1;
 
   /* The code emitted by alpha_output_mi_thunk_osf uses the gp.  */
-  if (current_function_is_thunk)
+  if (cfun->is_thunk)
     return 1;
 
   /* The nonlocal receiver pattern assumes that the gp is valid for
      the nested function.  Reasonable because it's almost always set
      correctly already.  For the cases where that's wrong, make sure
      the nested function loads its gp on entry.  */
-  if (current_function_has_nonlocal_goto)
+  if (crtl->has_nonlocal_goto)
     return 1;
 
   /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
@@ -7412,10 +7477,8 @@ emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias,
          mem = gen_rtx_MEM (DImode, addr);
        }
 
-      REG_NOTES (insn)
-       = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
-                            gen_rtx_SET (VOIDmode, mem, frame_reg),
-                            REG_NOTES (insn));
+      add_reg_note (insn, REG_FRAME_RELATED_EXPR,
+                   gen_rtx_SET (VOIDmode, mem, frame_reg));
     }
 }
 
@@ -7466,23 +7529,23 @@ alpha_expand_prologue (void)
     frame_size = ALPHA_ROUND (sa_size
                              + (alpha_procedure_type == PT_STACK ? 8 : 0)
                              + frame_size
-                             + current_function_pretend_args_size);
+                             + crtl->args.pretend_args_size);
   else if (TARGET_ABI_UNICOSMK)
     /* We have to allocate space for the DSIB if we generate a frame.  */
     frame_size = ALPHA_ROUND (sa_size
                              + (alpha_procedure_type == PT_STACK ? 48 : 0))
                 + ALPHA_ROUND (frame_size
-                               + current_function_outgoing_args_size);
+                               + crtl->outgoing_args_size);
   else
-    frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
+    frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
                  + sa_size
                  + ALPHA_ROUND (frame_size
-                                + current_function_pretend_args_size));
+                                + crtl->args.pretend_args_size));
 
   if (TARGET_ABI_OPEN_VMS)
     reg_offset = 8;
   else
-    reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
+    reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
 
   alpha_sa_mask (&imask, &fmask);
 
@@ -7498,7 +7561,7 @@ alpha_expand_prologue (void)
      the call to mcount ourselves, rather than having the linker do it
      magically in response to -pg.  Since _mcount has special linkage,
      don't represent the call as a call.  */
-  if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
+  if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
     emit_insn (gen_prologue_mcount ());
 
   if (TARGET_ABI_UNICOSMK)
@@ -7593,14 +7656,12 @@ alpha_expand_prologue (void)
          possibly intuit through the loop above.  So we invent this
          note it looks at instead.  */
       RTX_FRAME_RELATED_P (seq) = 1;
-      REG_NOTES (seq)
-        = gen_rtx_EXPR_LIST (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))),
-                            REG_NOTES (seq));
+      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)
@@ -7681,11 +7742,14 @@ alpha_expand_prologue (void)
 
   if (TARGET_ABI_OPEN_VMS)
     {
+      /* Register frame procedures save the fp.  */
       if (alpha_procedure_type == PT_REGISTER)
-       /* Register frame procedures save the fp.
-          ?? Ought to have a dwarf2 save for this.  */
-       emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
-                       hard_frame_pointer_rtx);
+       {
+         rtx insn = emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
+                                    hard_frame_pointer_rtx);
+         add_reg_note (insn, REG_CFA_REGISTER, NULL);
+         RTX_FRAME_RELATED_P (insn) = 1;
+       }
 
       if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
        emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
@@ -7696,14 +7760,14 @@ alpha_expand_prologue (void)
        FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
 
       /* If we have to allocate space for outgoing args, do it now.  */
-      if (current_function_outgoing_args_size != 0)
+      if (crtl->outgoing_args_size != 0)
        {
          rtx seq
            = emit_move_insn (stack_pointer_rtx,
                              plus_constant
                              (hard_frame_pointer_rtx,
                               - (ALPHA_ROUND
-                                 (current_function_outgoing_args_size))));
+                                 (crtl->outgoing_args_size))));
 
          /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
             if ! frame_pointer_needed. Setting the bit will change the CFA
@@ -7715,7 +7779,7 @@ alpha_expand_prologue (void)
               frame_pointer_needed
               => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
             and
-              current_function_outgoing_args_size != 0
+              crtl->outgoing_args_size != 0
               => alpha_procedure_type != PT_NULL,
 
             so when we are not setting the bit here, we are guaranteed to
@@ -7784,6 +7848,17 @@ alpha_start_function (FILE *file, const char *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;
+    }
+#endif
+
   alpha_fnname = fnname;
   sa_size = alpha_sa_size ();
 
@@ -7792,22 +7867,22 @@ alpha_start_function (FILE *file, const char *fnname,
     frame_size = ALPHA_ROUND (sa_size
                              + (alpha_procedure_type == PT_STACK ? 8 : 0)
                              + frame_size
-                             + current_function_pretend_args_size);
+                             + crtl->args.pretend_args_size);
   else if (TARGET_ABI_UNICOSMK)
     frame_size = ALPHA_ROUND (sa_size
                              + (alpha_procedure_type == PT_STACK ? 48 : 0))
                 + ALPHA_ROUND (frame_size
-                             + current_function_outgoing_args_size);
+                             + crtl->outgoing_args_size);
   else
-    frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
+    frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
                  + sa_size
                  + ALPHA_ROUND (frame_size
-                                + current_function_pretend_args_size));
+                                + crtl->args.pretend_args_size));
 
   if (TARGET_ABI_OPEN_VMS)
     reg_offset = 8;
   else
-    reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
+    reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
 
   alpha_sa_mask (&imask, &fmask);
 
@@ -7844,7 +7919,7 @@ alpha_start_function (FILE *file, const char *fnname,
         Otherwise, do it here.  */
       if (TARGET_ABI_OSF
           && ! alpha_function_needs_gp
-         && ! current_function_is_thunk)
+         && ! cfun->is_thunk)
        {
          putc ('$', file);
          assemble_name (file, fnname);
@@ -7877,7 +7952,7 @@ alpha_start_function (FILE *file, const char *fnname,
     }
 
   /* Set up offsets to alpha virtual arg/local debugging pointer.  */
-  alpha_auto_offset = -frame_size + current_function_pretend_args_size;
+  alpha_auto_offset = -frame_size + crtl->args.pretend_args_size;
   alpha_arg_offset = -frame_size + 48;
 
   /* Describe our frame.  If the frame size is larger than an integer,
@@ -7896,7 +7971,7 @@ alpha_start_function (FILE *file, const char *fnname,
             (frame_pointer_needed
              ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
             frame_size >= max_frame_size ? 0 : frame_size,
-            current_function_pretend_args_size);
+            crtl->args.pretend_args_size);
 
   /* Describe which registers were spilled.  */
   if (TARGET_ABI_UNICOSMK)
@@ -7955,17 +8030,11 @@ alpha_output_function_end_prologue (FILE *file)
     fputs ("\t.prologue 0\n", file);
   else if (!flag_inhibit_size_directive)
     fprintf (file, "\t.prologue %d\n",
-            alpha_function_needs_gp || current_function_is_thunk);
+            alpha_function_needs_gp || cfun->is_thunk);
 }
 
 /* Write function epilogue.  */
 
-/* ??? At some point we will want to support full unwind, and so will
-   need to mark the epilogue as well.  At the moment, we just confuse
-   dwarf2out.  */
-#undef FRP
-#define FRP(exp) exp
-
 void
 alpha_expand_epilogue (void)
 {
@@ -7980,8 +8049,9 @@ alpha_expand_epilogue (void)
   HOST_WIDE_INT reg_offset;
   int fp_is_frame_pointer, fp_offset;
   rtx sa_reg, sa_reg_exp = NULL;
-  rtx sp_adj1, sp_adj2, mem;
+  rtx sp_adj1, sp_adj2, mem, reg, insn;
   rtx eh_ofs;
+  rtx cfa_restores = NULL_RTX;
   int i;
 
   sa_size = alpha_sa_size ();
@@ -7991,17 +8061,17 @@ alpha_expand_epilogue (void)
     frame_size = ALPHA_ROUND (sa_size
                              + (alpha_procedure_type == PT_STACK ? 8 : 0)
                              + frame_size
-                             + current_function_pretend_args_size);
+                             + crtl->args.pretend_args_size);
   else if (TARGET_ABI_UNICOSMK)
     frame_size = ALPHA_ROUND (sa_size
                              + (alpha_procedure_type == PT_STACK ? 48 : 0))
                 + ALPHA_ROUND (frame_size
-                             + current_function_outgoing_args_size);
+                             + crtl->outgoing_args_size);
   else
-    frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
+    frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
                  + sa_size
                  + ALPHA_ROUND (frame_size
-                                + current_function_pretend_args_size));
+                                + crtl->args.pretend_args_size));
 
   if (TARGET_ABI_OPEN_VMS)
     {
@@ -8011,7 +8081,7 @@ alpha_expand_epilogue (void)
           reg_offset = 0;
     }
   else
-    reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
+    reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
 
   alpha_sa_mask (&imask, &fmask);
 
@@ -8021,7 +8091,7 @@ alpha_expand_epilogue (void)
   fp_offset = 0;
   sa_reg = stack_pointer_rtx;
 
-  if (current_function_calls_eh_return)
+  if (crtl->calls_eh_return)
     eh_ofs = EH_RETURN_STACKADJ_RTX;
   else
     eh_ofs = NULL_RTX;
@@ -8032,7 +8102,7 @@ alpha_expand_epilogue (void)
       if ((TARGET_ABI_OPEN_VMS
           && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
          || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
-       FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
+       emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
 
       /* Cope with very large offsets to the register save area.  */
       if (reg_offset + sa_size > 0x8000)
@@ -8048,7 +8118,7 @@ alpha_expand_epilogue (void)
          sa_reg = gen_rtx_REG (DImode, 22);
          sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
 
-         FRP (emit_move_insn (sa_reg, sa_reg_exp));
+         emit_move_insn (sa_reg, sa_reg_exp);
        }
 
       /* Restore registers in order, excepting a true frame pointer.  */
@@ -8056,7 +8126,9 @@ alpha_expand_epilogue (void)
       mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
       if (! eh_ofs)
         set_mem_alias_set (mem, alpha_sr_alias_set);
-      FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
+      reg = gen_rtx_REG (DImode, REG_RA);
+      emit_move_insn (reg, mem);
+      cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
 
       reg_offset += 8;
       imask &= ~(1UL << REG_RA);
@@ -8070,7 +8142,10 @@ alpha_expand_epilogue (void)
              {
                mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
                set_mem_alias_set (mem, alpha_sr_alias_set);
-               FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
+               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;
          }
@@ -8080,7 +8155,9 @@ alpha_expand_epilogue (void)
          {
            mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
            set_mem_alias_set (mem, alpha_sr_alias_set);
-           FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
+           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;
          }
     }
@@ -8096,7 +8173,9 @@ alpha_expand_epilogue (void)
            mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
                                                     reg_offset));
            set_mem_alias_set (mem, alpha_sr_alias_set);
-           FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
+           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;
          }
 
@@ -8106,15 +8185,18 @@ alpha_expand_epilogue (void)
            mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
                                                     reg_offset));
            set_mem_alias_set (mem, alpha_sr_alias_set);
-           FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
+           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));
+      mem = gen_rtx_MEM (DImode, plus_constant (hard_frame_pointer_rtx, -8));
       set_mem_alias_set (mem, alpha_sr_alias_set);
-      FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
+      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)
@@ -8132,12 +8214,12 @@ alpha_expand_epilogue (void)
         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 && current_function_calls_alloca))
+         && ! (TARGET_ABI_UNICOSMK && cfun->calls_alloca))
        sp_adj2 = GEN_INT (frame_size);
       else if (TARGET_ABI_UNICOSMK)
        {
          sp_adj1 = gen_rtx_REG (DImode, 23);
-         FRP (emit_move_insn (sp_adj1, hard_frame_pointer_rtx));
+         emit_move_insn (sp_adj1, hard_frame_pointer_rtx);
          sp_adj2 = const0_rtx;
        }
       else if (frame_size < 0x40007fffL)
@@ -8150,21 +8232,20 @@ alpha_expand_epilogue (void)
          else
            {
              sp_adj1 = gen_rtx_REG (DImode, 23);
-             FRP (emit_move_insn (sp_adj1, sp_adj2));
+             emit_move_insn (sp_adj1, sp_adj2);
            }
          sp_adj2 = GEN_INT (low);
        }
       else
        {
          rtx tmp = gen_rtx_REG (DImode, 23);
-         FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size,
-                                              3, false));
+         sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3, false);
          if (!sp_adj2)
            {
              /* We can't drop new things to memory this late, afaik,
                 so build it up by pieces.  */
-             FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
-                                                       -(frame_size < 0)));
+             sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
+                                                  -(frame_size < 0));
              gcc_assert (sp_adj2);
            }
        }
@@ -8178,46 +8259,58 @@ alpha_expand_epilogue (void)
          mem = gen_rtx_MEM (DImode,
                             plus_constant (hard_frame_pointer_rtx, -16));
          set_mem_alias_set (mem, alpha_sr_alias_set);
-         FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
+         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);
-         FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
+         emit_move_insn (hard_frame_pointer_rtx, mem);
+         cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
+                                        hard_frame_pointer_rtx, cfa_restores);
        }
       else if (TARGET_ABI_OPEN_VMS)
        {
          emit_insn (gen_blockage ());
-         FRP (emit_move_insn (hard_frame_pointer_rtx,
-                              gen_rtx_REG (DImode, vms_save_fp_regno)));
+         emit_move_insn (hard_frame_pointer_rtx,
+                         gen_rtx_REG (DImode, vms_save_fp_regno));
+         cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
+                                        hard_frame_pointer_rtx, cfa_restores);
        }
 
       /* Restore the stack pointer.  */
       emit_insn (gen_blockage ());
       if (sp_adj2 == const0_rtx)
-       FRP (emit_move_insn (stack_pointer_rtx, sp_adj1));
+       insn = emit_move_insn (stack_pointer_rtx, sp_adj1);
       else
-       FRP (emit_move_insn (stack_pointer_rtx,
-                            gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
+       insn = emit_move_insn (stack_pointer_rtx,
+                              gen_rtx_PLUS (DImode, sp_adj1, sp_adj2));
+      REG_NOTES (insn) = cfa_restores;
+      add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx);
+      RTX_FRAME_RELATED_P (insn) = 1;
     }
   else
     {
+      gcc_assert (cfa_restores == NULL);
+
       if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
         {
           emit_insn (gen_blockage ());
-          FRP (emit_move_insn (hard_frame_pointer_rtx,
-                              gen_rtx_REG (DImode, vms_save_fp_regno)));
+          insn = emit_move_insn (hard_frame_pointer_rtx,
+                                gen_rtx_REG (DImode, vms_save_fp_regno));
+         add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
+         RTX_FRAME_RELATED_P (insn) = 1;
         }
       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 ());
-         FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
-                                     hard_frame_pointer_rtx, constm1_rtx)));
+         emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
+                                hard_frame_pointer_rtx, constm1_rtx));
         }
     }
 }
@@ -8235,9 +8328,14 @@ alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
   insn = get_last_insn ();
   if (!INSN_P (insn))
     insn = prev_active_insn (insn);
-  if (GET_CODE (insn) == CALL_INSN)
+  if (CALL_P (insn))
     output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL);
 
+#if TARGET_ABI_OSF
+  if (cfun->is_thunk)
+    free_after_compilation (cfun);
+#endif
+
 #if TARGET_ABI_OPEN_VMS
   alpha_write_linkage (file, fnname, decl);
 #endif
@@ -8275,7 +8373,9 @@ alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
                           tree function)
 {
   HOST_WIDE_INT hi, lo;
-  rtx this, insn, funexp;
+  rtx this_rtx, insn, funexp;
+
+  gcc_assert (cfun->is_thunk);
 
   /* We always require a valid GP.  */
   emit_insn (gen_prologue_ldgp ());
@@ -8284,9 +8384,9 @@ alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
   /* Find the "this" pointer.  If the function returns a structure,
      the structure return pointer is in $16.  */
   if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
-    this = gen_rtx_REG (Pmode, 17);
+    this_rtx = gen_rtx_REG (Pmode, 17);
   else
-    this = gen_rtx_REG (Pmode, 16);
+    this_rtx = gen_rtx_REG (Pmode, 16);
 
   /* Add DELTA.  When possible we use ldah+lda.  Otherwise load the
      entire constant for the add.  */
@@ -8295,15 +8395,15 @@ alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
   if (hi + lo == delta)
     {
       if (hi)
-       emit_insn (gen_adddi3 (this, this, GEN_INT (hi)));
+       emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (hi)));
       if (lo)
-       emit_insn (gen_adddi3 (this, this, GEN_INT (lo)));
+       emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (lo)));
     }
   else
     {
       rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
                                           delta, -(delta < 0));
-      emit_insn (gen_adddi3 (this, this, tmp));
+      emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
     }
 
   /* Add a delta stored in the vtable at VCALL_OFFSET.  */
@@ -8312,7 +8412,7 @@ alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
       rtx tmp, tmp2;
 
       tmp = gen_rtx_REG (Pmode, 0);
-      emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
+      emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
 
       lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
       hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
@@ -8334,7 +8434,7 @@ alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
        tmp2 = tmp;
       emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));
 
-      emit_insn (gen_adddi3 (this, this, tmp));
+      emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
     }
 
   /* Generate a tail call to the target function.  */
@@ -8604,7 +8704,7 @@ alpha_handle_trap_shadows (void)
 
   for (i = get_insns (); i ; i = NEXT_INSN (i))
     {
-      if (GET_CODE (i) == NOTE)
+      if (NOTE_P (i))
        {
          switch (NOTE_KIND (i))
            {
@@ -8630,7 +8730,7 @@ alpha_handle_trap_shadows (void)
        {
          if (alpha_tp == ALPHA_TP_FUNC)
            {
-             if (GET_CODE (i) == JUMP_INSN
+             if (JUMP_P (i)
                  && GET_CODE (PATTERN (i)) == RETURN)
                goto close_shadow;
            }
@@ -8708,7 +8808,7 @@ alpha_handle_trap_shadows (void)
        }
 
       if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
-         && GET_CODE (i) == INSN
+         && NONJUMP_INSN_P (i)
          && GET_CODE (PATTERN (i)) != USE
          && GET_CODE (PATTERN (i)) != CLOBBER
          && get_attr_trap (i) == TRAP_YES)
@@ -8922,7 +9022,7 @@ alphaev4_next_group (rtx insn, int *pin_use, int *plen)
       len += 4;
 
       /* Haifa doesn't do well scheduling branches.  */
-      if (GET_CODE (insn) == JUMP_INSN)
+      if (JUMP_P (insn))
        goto next_and_done;
 
     next:
@@ -9053,7 +9153,7 @@ alphaev5_next_group (rtx insn, int *pin_use, int *plen)
       /* Haifa doesn't do well scheduling branches.  */
       /* ??? If this is predicted not-taken, slotting continues, except
         that no more IBR, FBR, or JSR insns may be slotted.  */
-      if (GET_CODE (insn) == JUMP_INSN)
+      if (JUMP_P (insn))
        goto next_and_done;
 
     next:
@@ -9161,7 +9261,7 @@ alpha_align_insns (unsigned int max_align,
 
   ofs = prev_in_use = 0;
   i = get_insns ();
-  if (GET_CODE (i) == NOTE)
+  if (NOTE_P (i))
     i = next_nonnote_insn (i);
 
   ldgp = alpha_function_needs_gp ? 8 : 0;
@@ -9171,7 +9271,7 @@ alpha_align_insns (unsigned int max_align,
       next = (*next_group) (i, &in_use, &len);
 
       /* When we see a label, resync alignment etc.  */
-      if (GET_CODE (i) == CODE_LABEL)
+      if (LABEL_P (i))
        {
          unsigned int new_align = 1 << label_to_alignment (i);
 
@@ -9208,12 +9308,12 @@ alpha_align_insns (unsigned int max_align,
          rtx prev, where;
 
          where = prev = prev_nonnote_insn (i);
-         if (!where || GET_CODE (where) != CODE_LABEL)
+         if (!where || !LABEL_P (where))
            where = i;
 
          /* Can't realign between a call and its gp reload.  */
          if (! (TARGET_EXPLICIT_RELOCS
-                && prev && GET_CODE (prev) == CALL_INSN))
+                && prev && CALL_P (prev)))
            {
              emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
              align = 1 << new_log_align;
@@ -9241,13 +9341,13 @@ alpha_align_insns (unsigned int max_align,
          where = prev_nonnote_insn (i);
          if (where)
            {
-             if (GET_CODE (where) == CODE_LABEL)
+             if (LABEL_P (where))
                {
                  rtx where2 = prev_nonnote_insn (where);
-                 if (where2 && GET_CODE (where2) == JUMP_INSN)
+                 if (where2 && JUMP_P (where2))
                    where = where2;
                }
-             else if (GET_CODE (where) == INSN)
+             else if (NONJUMP_INSN_P (where))
                where = i;
            }
          else
@@ -9264,12 +9364,66 @@ alpha_align_insns (unsigned int max_align,
       i = next;
     }
 }
+
+/* Insert an unop between a noreturn function call and GP load.  */
+
+static void
+alpha_pad_noreturn (void)
+{
+  rtx insn, next;
+
+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    {
+      if (!CALL_P (insn)
+         || !find_reg_note (insn, REG_NORETURN, NULL_RTX))
+        continue;
+
+      next = next_active_insn (insn);
+
+      if (next)
+       {
+         rtx pat = PATTERN (next);
+
+         if (GET_CODE (pat) == SET
+             && GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE
+             && XINT (SET_SRC (pat), 1) == UNSPECV_LDGP1)
+           emit_insn_after (gen_unop (), insn);
+       }
+    }
+}
 \f
 /* Machine dependent reorg pass.  */
 
 static void
 alpha_reorg (void)
 {
+  /* Workaround for a linker error that triggers when an
+     exception handler immediatelly follows a noreturn function.
+
+     The instruction stream from an object file:
+
+  54:   00 40 5b 6b     jsr     ra,(t12),58 <__func+0x58>
+  58:   00 00 ba 27     ldah    gp,0(ra)
+  5c:   00 00 bd 23     lda     gp,0(gp)
+  60:   00 00 7d a7     ldq     t12,0(gp)
+  64:   00 40 5b 6b     jsr     ra,(t12),68 <__func+0x68>
+
+     was converted in the final link pass to:
+
+   fdb24:       a0 03 40 d3     bsr     ra,fe9a8 <_called_func+0x8>
+   fdb28:       00 00 fe 2f     unop
+   fdb2c:       00 00 fe 2f     unop
+   fdb30:       30 82 7d a7     ldq     t12,-32208(gp)
+   fdb34:       00 40 5b 6b     jsr     ra,(t12),fdb38 <__func+0x68>
+
+     GP load instructions were wrongly cleared by the linker relaxation
+     pass.  This workaround prevents removal of GP loads by inserting
+     an unop instruction between a 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 ();
 
@@ -9382,7 +9536,7 @@ alpha_elf_section_type_flags (tree decl, const char *name, int reloc)
 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
 enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
 
-struct alpha_links GTY(())
+struct GTY(()) alpha_links
 {
   int num;
   rtx linkage;
@@ -9390,7 +9544,7 @@ struct alpha_links GTY(())
   enum reloc_kind rkind;
 };
 
-struct alpha_funcs GTY(())
+struct GTY(()) alpha_funcs
 {
   int num;
   splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
@@ -9508,7 +9662,7 @@ alpha_need_linkage (const char *name, int is_local)
   /* Construct a SYMBOL_REF for us to call.  */
   {
     size_t name_len = strlen (name);
-    char *linksym = alloca (name_len + 6);
+    char *linksym = XALLOCAVEC (char, name_len + 6);
     linksym[0] = '$';
     memcpy (linksym + 1, name, name_len);
     memcpy (linksym + 1 + name_len, "..lk", 5);
@@ -9575,7 +9729,7 @@ alpha_use_linkage (rtx linkage, tree cfundecl, int lflag, int rflag)
 
       sprintf (buf, "$%d..%s..lk", cfaf->num, name);
       buflen = strlen (buf);
-      linksym = alloca (buflen + 1);
+      linksym = XALLOCAVEC (char, buflen + 1);
       memcpy (linksym, buf, buflen + 1);
 
       al->linkage = gen_rtx_SYMBOL_REF
@@ -9793,12 +9947,12 @@ unicosmk_initial_elimination_offset (int from, int to)
   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 (current_function_outgoing_args_size)
+    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()
-                          + current_function_outgoing_args_size));
+                          + crtl->outgoing_args_size));
   else
     gcc_unreachable ();
 }
@@ -10071,7 +10225,7 @@ unicosmk_ssib_name (void)
   int len;
 
   x = DECL_RTL (cfun->decl);
-  gcc_assert (GET_CODE (x) == MEM);
+  gcc_assert (MEM_P (x));
   x = XEXP (x, 0);
   gcc_assert (GET_CODE (x) == SYMBOL_REF);
   fnname = XSTR (x, 0);
@@ -10140,18 +10294,15 @@ unicosmk_gen_dsib (unsigned long *imaskP)
       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.  */
-
-      FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
-                                  hard_frame_pointer_rtx, const1_rtx)));
+      emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
+                             hard_frame_pointer_rtx, const1_rtx));
     }
 }
 
@@ -10621,6 +10772,9 @@ alpha_init_libfuncs (void)
 #undef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
 
+#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
@@ -10670,15 +10824,13 @@ alpha_init_libfuncs (void)
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS alpha_rtx_costs
 #undef TARGET_ADDRESS_COST
-#define TARGET_ADDRESS_COST hook_int_rtx_0
+#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
 
 #undef TARGET_MACHINE_DEPENDENT_REORG
 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
 
-#undef TARGET_PROMOTE_FUNCTION_ARGS
-#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
-#undef TARGET_PROMOTE_FUNCTION_RETURN
-#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
+#undef TARGET_PROMOTE_FUNCTION_MODE
+#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
 #undef TARGET_PROMOTE_PROTOTYPES
 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false
 #undef TARGET_RETURN_IN_MEMORY
@@ -10729,6 +10881,9 @@ alpha_init_libfuncs (void)
 #define TARGET_MANGLE_TYPE alpha_mangle_type
 #endif
 
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P alpha_legitimate_address_p
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 \f