OSDN Git Service

* config/alpha/osf5.h (TARGET_LD_BUGGY_LDGP): New.
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / alpha.h
index 39b5abf..739a177 100644 (file)
@@ -1,5 +1,6 @@
 /* Definitions of target machine for GNU compiler, for DEC Alpha.
-   Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 This file is part of GNU CC.
@@ -20,17 +21,27 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 
+/* For C++ we need to ensure that __LANGUAGE_C_PLUS_PLUS is defined independent
+   of the source file extension.  */
+#define CPLUSPLUS_CPP_SPEC "\
+-D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus \
+%(cpp) \
+"
+
 /* Write out the correct language type definition for the header files.  
    Unless we have assembler language, write out the symbols for C.  */
 #define CPP_SPEC "\
-%{!.S: -D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}}  \
-%{.S:  -D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \
-%{.cc: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
-%{.cxx:        -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
-%{.C:  -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
-%{.m:  -D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C} \
-%{mieee:-D_IEEE_FP} \
-%{mieee-with-inexact:-D_IEEE_FP -D_IEEE_FP_INEXACT}"
+%{!undef:\
+%{.S:-D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY }}\
+%{.m:-D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C }\
+%{!.S:%{!.cc:%{!.cxx:%{!.cpp:%{!.cp:%{!.c++:%{!.C:%{!.m:-D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C }}}}}}}}}\
+%{mieee:-D_IEEE_FP }\
+%{mieee-with-inexact:-D_IEEE_FP -D_IEEE_FP_INEXACT }}\
+%(cpp_cpu) %(cpp_subtarget)"
+
+#ifndef CPP_SUBTARGET_SPEC
+#define CPP_SUBTARGET_SPEC ""
+#endif
 
 /* Set the spec to use for signed char.  The default tests the above macro
    but DEC's compiler can't handle the conditional in a "constant"
@@ -39,11 +50,7 @@ Boston, MA 02111-1307, USA.  */
 #define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
 
 #define WORD_SWITCH_TAKES_ARG(STR)             \
- (!strcmp (STR, "rpath") || !strcmp (STR, "include")   \
-  || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
-  || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
-  || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \
-  || !strcmp (STR, "isystem"))
+ (!strcmp (STR, "rpath") || DEFAULT_WORD_SWITCH_TAKES_ARG(STR))
 
 /* Print subsidiary information on the compiler version in use.  */
 #define TARGET_VERSION
@@ -91,73 +98,78 @@ extern enum alpha_fp_trap_mode alpha_fptm;
 
 /* This means that floating-point support exists in the target implementation
    of the Alpha architecture.  This is usually the default.  */
-
-#define MASK_FP                1
+#define MASK_FP                (1 << 0)
 #define TARGET_FP      (target_flags & MASK_FP)
 
 /* This means that floating-point registers are allowed to be used.  Note
    that Alpha implementations without FP operations are required to
    provide the FP registers.  */
 
-#define MASK_FPREGS    2
+#define MASK_FPREGS    (1 << 1)
 #define TARGET_FPREGS  (target_flags & MASK_FPREGS)
 
 /* This means that gas is used to process the assembler file.  */
 
-#define MASK_GAS 4
+#define MASK_GAS       (1 << 2)
 #define TARGET_GAS     (target_flags & MASK_GAS)
 
 /* This means that we should mark procedures as IEEE conformant. */
 
-#define MASK_IEEE_CONFORMANT 8
+#define MASK_IEEE_CONFORMANT (1 << 3)
 #define TARGET_IEEE_CONFORMANT (target_flags & MASK_IEEE_CONFORMANT)
 
 /* This means we should be IEEE-compliant except for inexact.  */
 
-#define MASK_IEEE      16
+#define MASK_IEEE      (1 << 4)
 #define TARGET_IEEE    (target_flags & MASK_IEEE)
 
 /* This means we should be fully IEEE-compliant.  */
 
-#define MASK_IEEE_WITH_INEXACT 32
+#define MASK_IEEE_WITH_INEXACT (1 << 5)
 #define TARGET_IEEE_WITH_INEXACT (target_flags & MASK_IEEE_WITH_INEXACT)
 
 /* This means we must construct all constants rather than emitting
    them as literal data.  */
 
-#define MASK_BUILD_CONSTANTS 128
+#define MASK_BUILD_CONSTANTS (1 << 6)
 #define TARGET_BUILD_CONSTANTS (target_flags & MASK_BUILD_CONSTANTS)
 
 /* This means we handle floating points in VAX F- (float)
    or G- (double) Format.  */
 
-#define MASK_FLOAT_VAX 512
+#define MASK_FLOAT_VAX (1 << 7)
 #define TARGET_FLOAT_VAX (target_flags & MASK_FLOAT_VAX)
 
 /* This means that the processor has byte and half word loads and stores
    (the BWX extension).  */
 
-#define MASK_BWX 1024
+#define MASK_BWX       (1 << 8)
 #define TARGET_BWX     (target_flags & MASK_BWX)
 
-/* This means that the processor has the CIX extension.  */
-#define MASK_CIX 2048
-#define TARGET_CIX     (target_flags & MASK_CIX)
-
 /* This means that the processor has the MAX extension.  */
-#define MASK_MAX 4096
+#define MASK_MAX       (1 << 9)
 #define TARGET_MAX     (target_flags & MASK_MAX)
 
-/* This means that the processor is an EV5, EV56, or PCA56.  This is defined
-   only in TARGET_CPU_DEFAULT.  */
-#define MASK_CPU_EV5 8192
+/* This means that the processor has the FIX extension.  */
+#define MASK_FIX       (1 << 10)
+#define TARGET_FIX     (target_flags & MASK_FIX)
+
+/* This means that the processor has the CIX extension.  */
+#define MASK_CIX       (1 << 11)
+#define TARGET_CIX     (target_flags & MASK_CIX)
+
+/* This means that the processor is an EV5, EV56, or PCA56.
+   Unlike alpha_cpu this is not affected by -mtune= setting.  */
+#define MASK_CPU_EV5   (1 << 28)
+#define TARGET_CPU_EV5 (target_flags & MASK_CPU_EV5)
 
 /* Likewise for EV6.  */
-#define MASK_CPU_EV6 16384
+#define MASK_CPU_EV6   (1 << 29)
+#define TARGET_CPU_EV6 (target_flags & MASK_CPU_EV6)
 
 /* This means we support the .arch directive in the assembler.  Only
    defined in TARGET_CPU_DEFAULT.  */
-#define MASK_SUPPORT_ARCH 32768
+#define MASK_SUPPORT_ARCH (1 << 30)
 #define TARGET_SUPPORT_ARCH    (target_flags & MASK_SUPPORT_ARCH)
 
 /* These are for target os support and cannot be changed at runtime.  */
@@ -171,7 +183,18 @@ extern enum alpha_fp_trap_mode alpha_fptm;
 #ifndef TARGET_AS_CAN_SUBTRACT_LABELS
 #define TARGET_AS_CAN_SUBTRACT_LABELS TARGET_GAS
 #endif
-
+#ifndef TARGET_CAN_FAULT_IN_PROLOGUE
+#define TARGET_CAN_FAULT_IN_PROLOGUE 0
+#endif
+#ifndef TARGET_HAS_XFLOATING_LIBS
+#define TARGET_HAS_XFLOATING_LIBS 0
+#endif
+#ifndef TARGET_PROFILING_NEEDS_GP
+#define TARGET_PROFILING_NEEDS_GP 0
+#endif
+#ifndef TARGET_LD_BUGGY_LDGP
+#define TARGET_LD_BUGGY_LDGP 0
+#endif
 
 /* Macro to define tables used to set the flags.
    This is a list in braces of pairs in braces,
@@ -179,26 +202,35 @@ extern enum alpha_fp_trap_mode alpha_fptm;
    where VALUE is the bits to set or minus the bits to clear.
    An empty string NAME is used to identify the default VALUE.  */
 
-#define TARGET_SWITCHES                                \
-  { {"no-soft-float", MASK_FP},                        \
-    {"soft-float", - MASK_FP},                 \
-    {"fp-regs", MASK_FPREGS},                  \
-    {"no-fp-regs", - (MASK_FP|MASK_FPREGS)},   \
-    {"alpha-as", -MASK_GAS},                   \
-    {"gas", MASK_GAS},                         \
-    {"ieee-conformant", MASK_IEEE_CONFORMANT}, \
-    {"ieee", MASK_IEEE|MASK_IEEE_CONFORMANT},  \
-    {"ieee-with-inexact", MASK_IEEE_WITH_INEXACT|MASK_IEEE_CONFORMANT}, \
-    {"build-constants", MASK_BUILD_CONSTANTS},  \
-    {"float-vax", MASK_FLOAT_VAX},             \
-    {"float-ieee", -MASK_FLOAT_VAX},           \
-    {"bwx", MASK_BWX},                         \
-    {"no-bwx", -MASK_BWX},                     \
-    {"cix", MASK_CIX},                         \
-    {"no-cix", -MASK_CIX},                     \
-    {"max", MASK_MAX},                         \
-    {"no-max", -MASK_MAX},                     \
-    {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT} }
+#define TARGET_SWITCHES                                                        \
+  { {"no-soft-float", MASK_FP, N_("Use hardware fp")},                 \
+    {"soft-float", - MASK_FP, N_("Do not use hardware fp")},           \
+    {"fp-regs", MASK_FPREGS, N_("Use fp registers")},                  \
+    {"no-fp-regs", - (MASK_FP|MASK_FPREGS),                            \
+     N_("Do not use fp registers")},                                   \
+    {"alpha-as", -MASK_GAS, N_("Do not assume GAS")},                  \
+    {"gas", MASK_GAS, N_("Assume GAS")},                               \
+    {"ieee-conformant", MASK_IEEE_CONFORMANT,                          \
+     N_("Request IEEE-conformant math library routines (OSF/1)")},     \
+    {"ieee", MASK_IEEE|MASK_IEEE_CONFORMANT,                           \
+     N_("Emit IEEE-conformant code, without inexact exceptions")},     \
+    {"ieee-with-inexact", MASK_IEEE_WITH_INEXACT|MASK_IEEE_CONFORMANT, \
+     N_("Emit IEEE-conformant code, with inexact exceptions")},                \
+    {"build-constants", MASK_BUILD_CONSTANTS,                          \
+     N_("Do not emit complex integer constants to read-only memory")}, \
+    {"float-vax", MASK_FLOAT_VAX, N_("Use VAX fp")},                   \
+    {"float-ieee", -MASK_FLOAT_VAX, N_("Do not use VAX fp")},          \
+    {"bwx", MASK_BWX, N_("Emit code for the byte/word ISA extension")},        \
+    {"no-bwx", -MASK_BWX, ""},                                         \
+    {"max", MASK_MAX,                                                  \
+     N_("Emit code for the motion video ISA extension")},              \
+    {"no-max", -MASK_MAX, ""},                                         \
+    {"fix", MASK_FIX,                                                  \
+     N_("Emit code for the fp move and sqrt ISA extension")},          \
+    {"no-fix", -MASK_FIX, ""},                                         \
+    {"cix", MASK_CIX, N_("Emit code for the counting ISA extension")}, \
+    {"no-cix", -MASK_CIX, ""},                                         \
+    {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT, ""} }
 
 #define TARGET_DEFAULT MASK_FP|MASK_FPREGS
 
@@ -223,21 +255,122 @@ extern enum alpha_fp_trap_mode alpha_fptm;
        extern char *m88k_short_data;
        #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } }  */
 
-extern char *alpha_cpu_string;  /* For -mcpu= */
-extern char *alpha_fprm_string;        /* For -mfp-rounding-mode=[n|m|c|d] */
-extern char *alpha_fptm_string;        /* For -mfp-trap-mode=[n|u|su|sui]  */
-extern char *alpha_tp_string;  /* For -mtrap-precision=[p|f|i] */
-extern char *alpha_mlat_string;        /* For -mmemory-latency= */
-
-#define TARGET_OPTIONS                         \
-{                                              \
-  {"cpu=",             &alpha_cpu_string},     \
-  {"fp-rounding-mode=",        &alpha_fprm_string},    \
-  {"fp-trap-mode=",    &alpha_fptm_string},    \
-  {"trap-precision=",  &alpha_tp_string},      \
-  {"memory-latency=",  &alpha_mlat_string},    \
+extern const char *alpha_cpu_string;   /* For -mcpu= */
+extern const char *alpha_tune_string;  /* For -mtune= */
+extern const char *alpha_fprm_string;  /* For -mfp-rounding-mode=[n|m|c|d] */
+extern const char *alpha_fptm_string;  /* For -mfp-trap-mode=[n|u|su|sui]  */
+extern const char *alpha_tp_string;    /* For -mtrap-precision=[p|f|i] */
+extern const char *alpha_mlat_string;  /* For -mmemory-latency= */
+
+#define TARGET_OPTIONS                                 \
+{                                                      \
+  {"cpu=",             &alpha_cpu_string,              \
+   N_("Use features of and schedule given CPU")},      \
+  {"tune=",            &alpha_tune_string,             \
+   N_("Schedule given CPU")},                          \
+  {"fp-rounding-mode=",        &alpha_fprm_string,             \
+   N_("Control the generated fp rounding mode")},      \
+  {"fp-trap-mode=",    &alpha_fptm_string,             \
+   N_("Control the IEEE trap mode")},                  \
+  {"trap-precision=",  &alpha_tp_string,               \
+   N_("Control the precision given to fp exceptions")},        \
+  {"memory-latency=",  &alpha_mlat_string,             \
+   N_("Tune expected memory latency")},                        \
 }
 
+/* Attempt to describe CPU characteristics to the preprocessor.  */
+
+/* Corresponding to amask... */
+#define CPP_AM_BWX_SPEC        "-D__alpha_bwx__ -Acpu=bwx"
+#define CPP_AM_MAX_SPEC        "-D__alpha_max__ -Acpu=max"
+#define CPP_AM_FIX_SPEC        "-D__alpha_fix__ -Acpu=fix"
+#define CPP_AM_CIX_SPEC        "-D__alpha_cix__ -Acpu=cix"
+
+/* Corresponding to implver... */
+#define CPP_IM_EV4_SPEC        "-D__alpha_ev4__ -Acpu=ev4"
+#define CPP_IM_EV5_SPEC        "-D__alpha_ev5__ -Acpu=ev5"
+#define CPP_IM_EV6_SPEC        "-D__alpha_ev6__ -Acpu=ev6"
+
+/* Common combinations.  */
+#define CPP_CPU_EV4_SPEC       "%(cpp_im_ev4)"
+#define CPP_CPU_EV5_SPEC       "%(cpp_im_ev5)"
+#define CPP_CPU_EV56_SPEC      "%(cpp_im_ev5) %(cpp_am_bwx)"
+#define CPP_CPU_PCA56_SPEC     "%(cpp_im_ev5) %(cpp_am_bwx) %(cpp_am_max)"
+#define CPP_CPU_EV6_SPEC \
+  "%(cpp_im_ev6) %(cpp_am_bwx) %(cpp_am_max) %(cpp_am_fix)"
+#define CPP_CPU_EV67_SPEC \
+  "%(cpp_im_ev6) %(cpp_am_bwx) %(cpp_am_max) %(cpp_am_fix) %(cpp_am_cix)"
+
+#ifndef CPP_CPU_DEFAULT_SPEC
+# if TARGET_CPU_DEFAULT & MASK_CPU_EV6
+#  if TARGET_CPU_DEFAULT & MASK_CIX
+#    define CPP_CPU_DEFAULT_SPEC       CPP_CPU_EV67_SPEC
+#  else
+#    define CPP_CPU_DEFAULT_SPEC       CPP_CPU_EV6_SPEC
+#  endif
+# else
+#  if TARGET_CPU_DEFAULT & MASK_CPU_EV5
+#   if TARGET_CPU_DEFAULT & MASK_MAX
+#    define CPP_CPU_DEFAULT_SPEC       CPP_CPU_PCA56_SPEC
+#   else
+#    if TARGET_CPU_DEFAULT & MASK_BWX
+#     define CPP_CPU_DEFAULT_SPEC      CPP_CPU_EV56_SPEC
+#    else
+#     define CPP_CPU_DEFAULT_SPEC      CPP_CPU_EV5_SPEC
+#    endif
+#   endif
+#  else
+#   define CPP_CPU_DEFAULT_SPEC                CPP_CPU_EV4_SPEC
+#  endif
+# endif
+#endif /* CPP_CPU_DEFAULT_SPEC */
+
+#ifndef CPP_CPU_SPEC
+#define CPP_CPU_SPEC "\
+%{!undef:-Acpu=alpha -Amachine=alpha -D__alpha -D__alpha__ \
+%{mcpu=ev4|mcpu=21064:%(cpp_cpu_ev4) }\
+%{mcpu=ev5|mcpu=21164:%(cpp_cpu_ev5) }\
+%{mcpu=ev56|mcpu=21164a:%(cpp_cpu_ev56) }\
+%{mcpu=pca56|mcpu=21164pc|mcpu=21164PC:%(cpp_cpu_pca56) }\
+%{mcpu=ev6|mcpu=21264:%(cpp_cpu_ev6) }\
+%{mcpu=ev67|mcpu=21264a:%(cpp_cpu_ev67) }\
+%{!mcpu*:%(cpp_cpu_default) }}"
+#endif
+
+/* This macro defines names of additional specifications to put in the
+   specs that can be used in various specifications like CC1_SPEC.  Its
+   definition is an initializer with a subgrouping for each command option.
+
+   Each subgrouping contains a string constant, that defines the
+   specification name, and a string constant that used by the GNU CC driver
+   program.
+
+   Do not define this macro if it does not need to do anything.  */
+
+#ifndef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS
+#endif
+
+#define EXTRA_SPECS                            \
+  { "cpp_am_bwx", CPP_AM_BWX_SPEC },           \
+  { "cpp_am_max", CPP_AM_MAX_SPEC },           \
+  { "cpp_am_fix", CPP_AM_FIX_SPEC },           \
+  { "cpp_am_cix", CPP_AM_CIX_SPEC },           \
+  { "cpp_im_ev4", CPP_IM_EV4_SPEC },           \
+  { "cpp_im_ev5", CPP_IM_EV5_SPEC },           \
+  { "cpp_im_ev6", CPP_IM_EV6_SPEC },           \
+  { "cpp_cpu_ev4", CPP_CPU_EV4_SPEC },         \
+  { "cpp_cpu_ev5", CPP_CPU_EV5_SPEC },         \
+  { "cpp_cpu_ev56", CPP_CPU_EV56_SPEC },       \
+  { "cpp_cpu_pca56", CPP_CPU_PCA56_SPEC },     \
+  { "cpp_cpu_ev6", CPP_CPU_EV6_SPEC },         \
+  { "cpp_cpu_ev67", CPP_CPU_EV67_SPEC },       \
+  { "cpp_cpu_default", CPP_CPU_DEFAULT_SPEC }, \
+  { "cpp_cpu", CPP_CPU_SPEC },                 \
+  { "cpp_subtarget", CPP_SUBTARGET_SPEC },     \
+  SUBTARGET_EXTRA_SPECS
+
+
 /* Sometimes certain combinations of command options do not make sense
    on a particular target machine.  You can define a macro
    `OVERRIDE_OPTIONS' to take account of this.  This macro, if
@@ -247,7 +380,6 @@ extern char *alpha_mlat_string;     /* For -mmemory-latency= */
    On the Alpha, it is used to translate target-option strings into
    numeric values.  */
 
-extern void override_options ();
 #define OVERRIDE_OPTIONS override_options ()
 
 
@@ -269,23 +401,6 @@ extern void override_options ();
 /* Define to enable software floating point emulation. */
 #define REAL_ARITHMETIC
 
-/* The following #defines are used when compiling the routines in
-   libgcc1.c.  Since the Alpha calling conventions require single
-   precision floats to be passed in the floating-point registers
-   (rather than in the general registers) we have to build the
-   libgcc1.c routines in such a way that they know the actual types
-   of their formal arguments and the actual types of their return
-   values.  Otherwise, gcc will generate calls to the libgcc1.c
-   routines, passing arguments in the floating-point registers,
-   but the libgcc1.c routines will expect their arguments on the
-   stack (where the Alpha calling conventions require structs &
-   unions to be passed).  */
-
-#define FLOAT_VALUE_TYPE       double
-#define INTIFY(FLOATVAL)       (FLOATVAL)
-#define FLOATIFY(INTVAL)       (INTVAL)
-#define FLOAT_ARG_TYPE         double
-
 /* Define the size of `int'.  The default is the same as the word size.  */
 #define INT_TYPE_SIZE 32
 
@@ -371,7 +486,7 @@ extern void override_options ();
 #define STACK_BOUNDARY 64
 
 /* Allocation boundary (in *bits*) for the code of a function.  */
-#define FUNCTION_BOUNDARY 64
+#define FUNCTION_BOUNDARY 32
 
 /* Alignment of field after `int : 0' in a structure.  */
 #define EMPTY_FIELD_BOUNDARY 64
@@ -382,32 +497,12 @@ extern void override_options ();
 /* A bitfield declared as `int' forces `int' alignment for the struct.  */
 #define PCC_BITFIELD_TYPE_MATTERS 1
 
-/* Align loop starts for optimal branching.  
-
-   ??? Kludge this and the next macro for the moment by not doing anything if
-   we don't optimize and also if we are writing ECOFF symbols to work around
-   a bug in DEC's assembler. */
-/* Aligning past 2**3 wastes insn cache lines, and doesn't buy much 
-   issue-wise on average anyway.  */
-
-#define LOOP_ALIGN(LABEL) \
-  (optimize > 0 && write_symbols != SDB_DEBUG ? 3 : 0)
-
-/* This is how to align an instruction for optimal branching.
-   On Alpha we'll get better performance by aligning on a quadword
-   boundary.  */
-/* Aligning past 2**3 wastes insn cache lines, and doesn't buy much 
-   issue-wise on average anyway.  */
-
-#define ALIGN_LABEL_AFTER_BARRIER(FILE)        \
-  (optimize > 0 && write_symbols != SDB_DEBUG ? 3 : 0)
-
 /* No data type wants to be aligned rounder than this.  */
-#define BIGGEST_ALIGNMENT 64
+#define BIGGEST_ALIGNMENT 128
 
 /* For atomic access to objects, must have at least 32-bit alignment
    unless the machine has byte operations.  */
-#define MINIMUM_ATOMIC_ALIGNMENT (TARGET_BWX ? 8 : 32)
+#define MINIMUM_ATOMIC_ALIGNMENT ((unsigned int) (TARGET_BWX ? 8 : 32))
 
 /* Align all constants and variables to at least a word boundary so
    we can pick up pieces of them faster.  */
@@ -429,7 +524,7 @@ extern void override_options ();
 
    On the Alpha, they trap.  */
 
-#define SLOW_UNALIGNED_ACCESS 1
+#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 1
 \f
 /* Standard register usage.  */
 
@@ -480,11 +575,11 @@ extern void override_options ();
    listed once, even those in FIXED_REGISTERS.
 
    We allocate in the following order:
-   $f1                 (nonsaved floating-point register)
-   $f10-$f15           (likewise)
+   $f10-$f15           (nonsaved floating-point register)
    $f22-$f30           (likewise)
    $f21-$f16           (likewise, but input args)
    $f0                 (nonsaved, but return value)
+   $f1                 (nonsaved, but immediate before saved)
    $f2-$f9             (saved floating-point registers)
    $1-$8               (nonsaved integer registers)
    $22-$25             (likewise)
@@ -499,11 +594,10 @@ extern void override_options ();
    $30, $31, $f31      (stack pointer and always zero/ap & fp)  */
 
 #define REG_ALLOC_ORDER                \
-  {33,                                 \
-   42, 43, 44, 45, 46, 47,             \
+  {42, 43, 44, 45, 46, 47,             \
    54, 55, 56, 57, 58, 59, 60, 61, 62, \
    53, 52, 51, 50, 49, 48,             \
-   32,                                 \
+   32, 33,                             \
    34, 35, 36, 37, 38, 39, 40, 41,     \
    1, 2, 3, 4, 5, 6, 7, 8,             \
    22, 23, 24, 25,                     \
@@ -528,18 +622,23 @@ extern void override_options ();
 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
    On Alpha, the integer registers can hold any mode.  The floating-point
    registers can hold 32-bit and 64-bit integers as well, but not 16-bit
-   or 8-bit values.  If we only allowed the larger integers into FP registers,
-   we'd have to say that QImode and SImode aren't tiable, which is a
-   pain.  So say all registers can hold everything and see how that works.  */
+   or 8-bit values.  */
+
+#define HARD_REGNO_MODE_OK(REGNO, MODE)                                \
+  ((REGNO) >= 32 && (REGNO) <= 62                                      \
+   ? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4  \
+   : 1)
 
-#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
+/* A C expression that is nonzero if a value of mode
+   MODE1 is accessible in mode MODE2 without copying.
 
-/* Value is 1 if it is a good idea to tie two pseudo registers
-   when one has mode MODE1 and one has mode MODE2.
-   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
-   for any hard reg, then this must be 0 for correct output.  */
+   This asymmetric test is true when MODE1 could be put
+   in an FP register but MODE2 could not.  */
 
-#define MODES_TIEABLE_P(MODE1, MODE2) 1
+#define MODES_TIEABLE_P(MODE1, MODE2)                          \
+  (HARD_REGNO_MODE_OK (32, (MODE1))                            \
+   ? HARD_REGNO_MODE_OK (32, (MODE2))                          \
+   : 1)
 
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
@@ -596,7 +695,7 @@ extern void override_options ();
    For any two classes, it is very desirable that there be another
    class that represents their union.  */
    
-enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
+enum reg_class { NO_REGS, PV_REG, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
                 LIM_REG_CLASSES };
 
 #define N_REG_CLASSES (int) LIM_REG_CLASSES
@@ -604,22 +703,24 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
 /* Give names of register classes as strings for dump file.   */
 
 #define REG_CLASS_NAMES                                \
- {"NO_REGS", "GENERAL_REGS", "FLOAT_REGS", "ALL_REGS" }
+ {"NO_REGS", "PV_REG", "GENERAL_REGS", "FLOAT_REGS", "ALL_REGS" }
 
 /* Define which registers fit in which classes.
    This is an initializer for a vector of HARD_REG_SET
    of length N_REG_CLASSES.  */
 
 #define REG_CLASS_CONTENTS     \
-  { {0, 0}, {~0, 0x80000000}, {0, 0x7fffffff}, {~0, ~0} }
+  { {0, 0}, {0x08000000, 0}, {~0, 0x80000000}, {0, 0x7fffffff}, {~0, ~0} }
 
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
    or could index an array.  */
 
-#define REGNO_REG_CLASS(REGNO) \
- ((REGNO) >= 32 && (REGNO) <= 62 ? FLOAT_REGS : GENERAL_REGS)
+#define REGNO_REG_CLASS(REGNO)                 \
+ ((REGNO) == 27 ? PV_REG                       \
+  : (REGNO) >= 32 && (REGNO) <= 62 ? FLOAT_REGS        \
+  : GENERAL_REGS)
 
 /* The class value for index registers, and the one for base regs.  */
 #define INDEX_REG_CLASS NO_REGS
@@ -628,7 +729,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
 /* Get reg_class from a letter such as appears in the machine description.  */
 
 #define REG_CLASS_FROM_LETTER(C)       \
- ((C) == 'f' ? FLOAT_REGS : NO_REGS)
+ ((C) == 'c' ? PV_REG : (C) == 'f' ? FLOAT_REGS : NO_REGS)
 
 /* Define this macro to change register usage conditional on target flags.  */
 /* #define CONDITIONAL_REGISTER_USAGE  */
@@ -679,12 +780,17 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
 
    For the Alpha, `Q' means that this is a memory operand but not a
    reference to an unaligned location.
+
    `R' is a SYMBOL_REF that has SYMBOL_REF_FLAG set or is the current
-   function.  */
+   function.
+
+   'S' is a 6-bit constant (valid for a shift insn).  */
 
 #define EXTRA_CONSTRAINT(OP, C)                                \
-  ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) != AND \
-   : (C) == 'R' ? current_file_function_operand (OP, Pmode)    \
+  ((C) == 'Q' ? normal_memory_operand (OP, VOIDmode)                   \
+   : (C) == 'R' ? current_file_function_operand (OP, Pmode)            \
+   : (C) == 'S' ? (GET_CODE (OP) == CONST_INT                          \
+                  && (unsigned HOST_WIDE_INT) INTVAL (OP) < 64)        \
    : 0)
 
 /* Given an rtx X being reloaded into a reg required to be
@@ -707,48 +813,17 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
    We also cannot load an unaligned address or a paradoxical SUBREG into an
    FP register.   */
 
-#define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,IN)                    \
-(((GET_CODE (IN) == MEM                                                \
-   || (GET_CODE (IN) == REG && REGNO (IN) >= FIRST_PSEUDO_REGISTER)    \
-   || (GET_CODE (IN) == SUBREG                                         \
-       && (GET_CODE (SUBREG_REG (IN)) == MEM                           \
-          || (GET_CODE (SUBREG_REG (IN)) == REG                        \
-              && REGNO (SUBREG_REG (IN)) >= FIRST_PSEUDO_REGISTER))))  \
-  && (((CLASS) == FLOAT_REGS                                           \
-       && ((MODE) == SImode || (MODE) == HImode || (MODE) == QImode))  \
-      || (((MODE) == QImode || (MODE) == HImode)                       \
-         && ! TARGET_BWX && unaligned_memory_operand (IN, MODE)))) \
- ? GENERAL_REGS                                                                \
- : ((CLASS) == FLOAT_REGS && GET_CODE (IN) == MEM                      \
-    && GET_CODE (XEXP (IN, 0)) == AND) ? GENERAL_REGS                  \
- : ((CLASS) == FLOAT_REGS && GET_CODE (IN) == SUBREG                   \
-    && (GET_MODE_SIZE (GET_MODE (IN))                                  \
-       > GET_MODE_SIZE (GET_MODE (SUBREG_REG (IN))))) ? GENERAL_REGS   \
- : NO_REGS)
-
-#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,OUT)                  \
-(((GET_CODE (OUT) == MEM                                               \
-   || (GET_CODE (OUT) == REG && REGNO (OUT) >= FIRST_PSEUDO_REGISTER)  \
-   || (GET_CODE (OUT) == SUBREG                                                \
-       && (GET_CODE (SUBREG_REG (OUT)) == MEM                          \
-          || (GET_CODE (SUBREG_REG (OUT)) == REG                       \
-              && REGNO (SUBREG_REG (OUT)) >= FIRST_PSEUDO_REGISTER)))) \
-  && ((((MODE) == HImode || (MODE) == QImode)                          \
-       && (! TARGET_BWX || (CLASS) == FLOAT_REGS))                     \
-      || ((MODE) == SImode && (CLASS) == FLOAT_REGS)))                 \
- ? GENERAL_REGS                                                                \
- : ((CLASS) == FLOAT_REGS && GET_CODE (OUT) == MEM                     \
-    && GET_CODE (XEXP (OUT, 0)) == AND) ? GENERAL_REGS                 \
- : ((CLASS) == FLOAT_REGS && GET_CODE (OUT) == SUBREG                  \
-    && (GET_MODE_SIZE (GET_MODE (OUT))                                 \
-       > GET_MODE_SIZE (GET_MODE (SUBREG_REG (OUT))))) ? GENERAL_REGS  \
- : NO_REGS)
+#define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,IN) \
+  secondary_reload_class((CLASS), (MODE), (IN), 1)
+
+#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,OUT) \
+  secondary_reload_class((CLASS), (MODE), (OUT), 0)
 
 /* If we are copying between general and FP registers, we need a memory
-   location unless the CIX extension is available.  */
+   location unless the FIX extension is available.  */
 
 #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
- (! TARGET_CIX && (CLASS1) != (CLASS2))
+ (! TARGET_FIX && (CLASS1) != (CLASS2))
 
 /* Specify the mode to be used for memory when a secondary memory
    location is needed.  If MODE is floating-point, use it.  Otherwise,
@@ -767,9 +842,14 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
  ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
 
 /* If defined, gives a class of registers that cannot be used as the
-   operand of a SUBREG that changes the size of the object.  */
+   operand of a SUBREG that changes the mode of the object illegally.  */
+
+#define CLASS_CANNOT_CHANGE_MODE       FLOAT_REGS
+
+/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.  */
 
-#define CLASS_CANNOT_CHANGE_SIZE       FLOAT_REGS
+#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
+  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
 
 /* Define the cost of moving between registers of various classes.  Moving
    between FLOAT_REGS and anything else except float regs is expensive. 
@@ -778,10 +858,10 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
    reduce the impact of not being able to allocate a pseudo to a
    hard register.  */
 
-#define REGISTER_MOVE_COST(CLASS1, CLASS2)             \
+#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)       \
   (((CLASS1) == FLOAT_REGS) == ((CLASS2) == FLOAT_REGS)        \
    ? 2                                                 \
-   : TARGET_CIX ? 3 : 4+2*alpha_memory_latency)
+   : TARGET_FIX ? 3 : 4+2*alpha_memory_latency)
 
 /* A C expressions returning the cost of moving data of MODE from a register to
    or from memory.
@@ -829,7 +909,7 @@ extern int alpha_memory_latency;
 /* Define this if the maximum size of all the outgoing args is to be
    accumulated and pushed during the prologue.  The amount can be
    found in the variable current_function_outgoing_args_size.  */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
 
 /* Offset of first parameter from the argument pointer register value.  */
 
@@ -876,6 +956,8 @@ extern int alpha_memory_latency;
                + (ALPHA_ROUND (get_frame_size ()                       \
                               + current_function_pretend_args_size)    \
                   - current_function_pretend_args_size));              \
+  else                                                                 \
+    abort ();                                                          \
 }
 
 /* Define this if stack space is still allocated for a parameter passed
@@ -900,25 +982,24 @@ extern int alpha_memory_latency;
    $f0 for floating-point functions.  */
 
 #define FUNCTION_VALUE(VALTYPE, FUNC)  \
-  gen_rtx (REG,                                                        \
-          ((INTEGRAL_TYPE_P (VALTYPE)                          \
-            && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)       \
-           || POINTER_TYPE_P (VALTYPE))                        \
-          ? word_mode : TYPE_MODE (VALTYPE),                   \
-          ((TARGET_FPREGS                                      \
-            && (TREE_CODE (VALTYPE) == REAL_TYPE               \
-                || TREE_CODE (VALTYPE) == COMPLEX_TYPE))       \
-           ? 32 : 0))
+  gen_rtx_REG (((INTEGRAL_TYPE_P (VALTYPE)                     \
+                && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)   \
+               || POINTER_TYPE_P (VALTYPE))                    \
+              ? word_mode : TYPE_MODE (VALTYPE),               \
+              ((TARGET_FPREGS                                  \
+                && (TREE_CODE (VALTYPE) == REAL_TYPE           \
+                    || TREE_CODE (VALTYPE) == COMPLEX_TYPE))   \
+               ? 32 : 0))
 
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
 
 #define LIBCALL_VALUE(MODE)    \
-   gen_rtx (REG, MODE,                                         \
-           (TARGET_FPREGS                                      \
-            && (GET_MODE_CLASS (MODE) == MODE_FLOAT            \
-                || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
-            ? 32 : 0))
+   gen_rtx_REG (MODE,                                          \
+               (TARGET_FPREGS                                  \
+                && (GET_MODE_CLASS (MODE) == MODE_FLOAT        \
+                    || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
+                ? 32 : 0))
 
 /* The definition of this macro implies that there are cases where
    a scalar value cannot be returned in registers.
@@ -928,6 +1009,8 @@ extern int alpha_memory_latency;
 
 #define RETURN_IN_MEMORY(TYPE) \
   (TYPE_MODE (TYPE) == BLKmode \
+   || TYPE_MODE (TYPE) == TFmode \
+   || TYPE_MODE (TYPE) == TCmode \
    || (TREE_CODE (TYPE) == INTEGER_TYPE && TYPE_PRECISION (TYPE) > 64))
 
 /* 1 if N is a possible register number for a function value
@@ -964,9 +1047,9 @@ extern int alpha_memory_latency;
    for the Alpha.  */
 
 #define ALPHA_ARG_SIZE(MODE, TYPE, NAMED)                              \
-((MODE) != BLKmode                                                     \
? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD      \
: (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
+  ((MODE) == TFmode || (MODE) == TCmode ? 1                            \
  : (((MODE) == BLKmode ? int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE)) \
     + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
 
 /* Update the data in CUM to advance over an argument
    of mode MODE and data type TYPE.
@@ -995,13 +1078,16 @@ extern int alpha_memory_latency;
    and the rest are pushed.  */
 
 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)   \
-((CUM) < 6 && ! MUST_PASS_IN_STACK (MODE, TYPE)        \
- ? gen_rtx(REG, (MODE),                                \
-          (CUM) + 16 + ((TARGET_FPREGS         \
-                         && (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT  \
-                             || GET_MODE_CLASS (MODE) == MODE_FLOAT)) \
-                        * 32))                 \
- : 0)
+  function_arg((CUM), (MODE), (TYPE), (NAMED))
+
+/* A C expression that indicates when an argument must be passed by
+   reference.  If nonzero for an argument, a copy of that argument is
+   made in memory and a pointer to the argument is passed instead of
+   the argument itself.  The pointer is passed in whatever way is
+   appropriate for passing a pointer to that type. */
+
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
+  ((MODE) == TFmode || (MODE) == TCmode)
 
 /* Specify the padding direction of arguments.
 
@@ -1046,79 +1132,94 @@ extern int alpha_memory_latency;
    class, but it isn't worth doing anything more efficient in this rare
    case.  */
    
-
 #define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL)      \
 { if ((CUM) < 6)                                                       \
     {                                                                  \
       if (! (NO_RTL))                                                  \
        {                                                               \
+         rtx tmp; int set = get_varargs_alias_set ();                  \
+         tmp = gen_rtx_MEM (BLKmode,                                   \
+                            plus_constant (virtual_incoming_args_rtx,  \
+                                           ((CUM) + 6)* UNITS_PER_WORD)); \
+         MEM_ALIAS_SET (tmp) = set;                                    \
          move_block_from_reg                                           \
-           (16 + CUM,                                                  \
-            gen_rtx (MEM, BLKmode,                                     \
-                     plus_constant (virtual_incoming_args_rtx,         \
-                                    ((CUM) + 6)* UNITS_PER_WORD)),     \
+           (16 + CUM, tmp,                                             \
             6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD);                  \
+                                                                       \
+         tmp = gen_rtx_MEM (BLKmode,                                   \
+                            plus_constant (virtual_incoming_args_rtx,  \
+                                           (CUM) * UNITS_PER_WORD));   \
+         MEM_ALIAS_SET (tmp) = set;                                    \
          move_block_from_reg                                           \
-           (16 + (TARGET_FPREGS ? 32 : 0) + CUM,                       \
-            gen_rtx (MEM, BLKmode,                                     \
-                     plus_constant (virtual_incoming_args_rtx,         \
-                                    (CUM) * UNITS_PER_WORD)),          \
+           (16 + (TARGET_FPREGS ? 32 : 0) + CUM, tmp,                  \
             6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD);                  \
-          emit_insn (gen_blockage ());                                 \
         }                                                              \
       PRETEND_SIZE = 12 * UNITS_PER_WORD;                              \
     }                                                                  \
 }
 
+/* We do not allow indirect calls to be optimized into sibling calls, nor
+   can we allow a call to a function in a different compilation unit to
+   be optimized into a sibcall.  Except if the function is known not to
+   return, in which case our caller doesn't care what the gp is.  */
+#define FUNCTION_OK_FOR_SIBCALL(DECL)                  \
+  (DECL                                                        \
+   && ((TREE_ASM_WRITTEN (DECL) && !flag_pic)          \
+       || ! TREE_PUBLIC (DECL)))
+
 /* Try to output insns to set TARGET equal to the constant C if it can be
    done in less than N insns.  Do all computations in MODE.  Returns the place
    where the output has been placed if it can be done and the insns have been
    emitted.  If it would take more than N insns, zero is returned and no
    insns and emitted.  */
-extern struct rtx_def *alpha_emit_set_const ();
-extern struct rtx_def *alpha_emit_set_long_const ();
-extern struct rtx_def *alpha_emit_conditional_move ();
-
-/* Generate necessary RTL for __builtin_saveregs().
-   ARGLIST is the argument list; see expr.c.  */
-extern struct rtx_def *alpha_builtin_saveregs ();
-#define EXPAND_BUILTIN_SAVEREGS(ARGLIST) alpha_builtin_saveregs (ARGLIST)
 
 /* Define the information needed to generate branch and scc insns.  This is
    stored from the compare operation.  Note that we can't use "rtx" here
    since it hasn't been defined!  */
 
-extern struct rtx_def *alpha_compare_op0, *alpha_compare_op1;
-extern int alpha_compare_fp_p;
+struct alpha_compare
+{
+  struct rtx_def *op0, *op1;
+  int fp_p;
+};
 
-/* Make (or fake) .linkage entry for function call.
+extern struct alpha_compare alpha_compare;
+
+/* Machine specific function data.  */
+
+struct machine_function
+{
+  /* If non-null, this rtx holds the return address for the function.  */
+  struct rtx_def *ra_rtx;
+
+  /* If non-null, this rtx holds a saved copy of the GP for the function.  */
+  struct rtx_def *gp_save_rtx;
+};
 
+/* Make (or fake) .linkage entry for function call.
    IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.  */
-extern void alpha_need_linkage ();
 
 /* This macro defines the start of an assembly comment.  */
 
 #define ASM_COMMENT_START " #"
 
-/* This macro produces the initial definition of a function name.  On the
-   Alpha, we need to save the function name for the prologue and epilogue.  */
+/* This macro produces the initial definition of a function.  */
 
-extern char *alpha_function_name;
+#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
+  alpha_start_function(FILE,NAME,DECL);
 
-#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL)      \
-{                                                      \
-   alpha_function_name = NAME;                         \
-}
+/* This macro closes up a function definition for the assembler.  */
+
+#define ASM_DECLARE_FUNCTION_SIZE(FILE,NAME,DECL) \
+  alpha_end_function(FILE,NAME,DECL)
    
-/* This macro generates the assembly code for function entry.
-   FILE is a stdio stream to output the code to.
-   SIZE is an int: how many units of temporary storage to allocate.
-   Refer to the array `regs_ever_live' to determine which registers
-   to save; `regs_ever_live[I]' is nonzero if register number I
-   is ever used in the function.  This macro is responsible for
-   knowing which registers should not be saved even if used.  */
+/* This macro notes the end of the prologue.  */
 
-#define FUNCTION_PROLOGUE(FILE, SIZE)  output_prolog (FILE, SIZE)
+#define FUNCTION_END_PROLOGUE(FILE)  output_end_prologue (FILE)
+
+/* Output any profiling code before the prologue.  */
+
+#define PROFILE_BEFORE_PROLOGUE 1
 
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  Under OSF/1, profiling is enabled
@@ -1169,18 +1270,9 @@ extern char *alpha_function_name;
 
 #define EXIT_IGNORE_STACK 1
 
-/* This macro generates the assembly code for function exit,
-   on machines that need it.  If FUNCTION_EPILOGUE is not defined
-   then individual return instructions are generated for each
-   return statement.  Args are same as for FUNCTION_PROLOGUE.
-
-   The function epilogue should not depend on the current stack pointer!
-   It should use the frame pointer only.  This is mandatory because
-   of alloca; we also take advantage of it to omit stack adjustments
-   before returning.  */
-
-#define FUNCTION_EPILOGUE(FILE, SIZE)  output_epilog (FILE, SIZE)
+/* Define registers used by the epilogue and return instruction.  */
 
+#define EPILOGUE_USES(REGNO)   ((REGNO) == 26)
 \f
 /* Output assembler code for a block containing the constant parts
    of a trampoline, leaving space for the variable parts.
@@ -1192,13 +1284,13 @@ extern char *alpha_function_name;
    aligned to FUNCTION_BOUNDARY, which is 64 bits.  */
 
 #define TRAMPOLINE_TEMPLATE(FILE)              \
-{                                              \
+do {                                           \
   fprintf (FILE, "\tldq $1,24($27)\n");                \
   fprintf (FILE, "\tldq $27,16($27)\n");       \
   fprintf (FILE, "\tjmp $31,($27),0\n");       \
   fprintf (FILE, "\tnop\n");                   \
   fprintf (FILE, "\t.quad 0,0\n");             \
-}
+} while (0)
 
 /* Section in which to place the trampoline.  On Alpha, instructions
    may only be placed in a text segment.  */
@@ -1211,85 +1303,36 @@ extern char *alpha_function_name;
 
 /* Emit RTL insns to initialize the variable parts of a trampoline.
    FNADDR is an RTX for the address of the function's pure code.
-   CXT is an RTX for the static chain value for the function.  We assume
-   here that a function will be called many more times than its address
-   is taken (e.g., it might be passed to qsort), so we take the trouble 
-   to initialize the "hint" field in the JMP insn.  Note that the hint
-   field is PC (new) + 4 * bits 13:0.  */
-
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)                      \
-{                                                                      \
-  rtx _temp, _temp1, _addr;                                            \
-                                                                       \
-  _addr = memory_address (Pmode, plus_constant ((TRAMP), 16));         \
-  emit_move_insn (gen_rtx (MEM, Pmode, _addr), (FNADDR));              \
-  _addr = memory_address (Pmode, plus_constant ((TRAMP), 24));         \
-  emit_move_insn (gen_rtx (MEM, Pmode, _addr), (CXT));                 \
-                                                                       \
-  _temp = force_operand (plus_constant ((TRAMP), 12), NULL_RTX);       \
-  _temp = expand_binop (DImode, sub_optab, (FNADDR), _temp, _temp, 1,  \
-                       OPTAB_WIDEN);                                   \
-  _temp = expand_shift (RSHIFT_EXPR, Pmode, _temp,                     \
-                       build_int_2 (2, 0), NULL_RTX, 1);               \
-  _temp = expand_and (gen_lowpart (SImode, _temp),                     \
-                     GEN_INT (0x3fff), 0);                             \
-                                                                       \
-  _addr = memory_address (SImode, plus_constant ((TRAMP), 8));         \
-  _temp1 = force_reg (SImode, gen_rtx (MEM, SImode, _addr));           \
-  _temp1 = expand_and (_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);               \
-                                                                       \
-  emit_library_call (gen_rtx (SYMBOL_REF, Pmode,                       \
-                             "__enable_execute_stack"),                \
-                    0, VOIDmode, 1,_addr, Pmode);                      \
-                                                                       \
-  emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,                       \
-                     gen_rtvec (1, const0_rtx), 0));                   \
-}
+   CXT is an RTX for the static chain value for the function.  */
 
-/* Attempt to turn on access permissions for the stack.  */
-
-#define TRANSFER_FROM_TRAMPOLINE                                       \
-                                                                       \
-void                                                                   \
-__enable_execute_stack (addr)                                          \
-     void *addr;                                                       \
-{                                                                      \
-  long size = getpagesize ();                                          \
-  long mask = ~(size-1);                                               \
-  char *page = (char *) (((long) addr) & mask);                                \
-  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-                                                                       \
-  /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */                                \
-  if (mprotect (page, end - page, 7) < 0)                              \
-    perror ("mprotect of trampoline code");                            \
-}
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
+  alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 16, 24, 8)
 
 /* A C expression whose value is RTL representing the value of the return
    address for the frame COUNT steps up from the current frame.
    FRAMEADDR is the frame pointer of the COUNT frame, or the frame pointer of
-   the COUNT-1 frame if RETURN_ADDR_IN_PREVIOUS_FRAME} is defined.  */
+   the COUNT-1 frame if RETURN_ADDR_IN_PREVIOUS_FRAME is defined.  */
 
 #define RETURN_ADDR_RTX  alpha_return_addr
-extern struct rtx_def *alpha_return_addr ();
-
-/* Initialize data used by insn expanders.  This is called from insn_emit,
-   once for every function before code is generated.  */
 
-#define INIT_EXPANDERS  alpha_init_expanders ()
-extern void alpha_init_expanders ();
+/* Before the prologue, RA lives in $26. */
+#define INCOMING_RETURN_ADDR_RTX  gen_rtx_REG (Pmode, 26)
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (26)
 
+/* Describe how we implement __builtin_eh_return.  */
+#define EH_RETURN_DATA_REGNO(N)        ((N) < 4 ? (N) + 16 : INVALID_REGNUM)
+#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 28)
+#define EH_RETURN_HANDLER_RTX \
+  gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx, \
+                                    current_function_outgoing_args_size))
 \f
 /* Addressing modes, and classification of registers for them.  */
 
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT */
+/* #define HAVE_POST_DECREMENT */
 
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT */
+/* #define HAVE_PRE_INCREMENT */
 
 /* Macros to check register numbers against specific register classes.  */
 
@@ -1340,18 +1383,32 @@ extern void alpha_init_expanders ();
 /* Nonzero if X is a hard reg that can be used as an index
    or if it is a pseudo reg.  */
 #define REG_OK_FOR_INDEX_P(X) 0
+
 /* Nonzero if X is a hard reg that can be used as a base reg
    or if it is a pseudo reg.  */
 #define REG_OK_FOR_BASE_P(X)  \
   (REGNO (X) < 32 || REGNO (X) == 63 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
 
+/* ??? Nonzero if X is the frame pointer, or some virtual register
+   that may eliminate to the frame pointer.  These will be allowed to
+   have offsets greater than 32K.  This is done because register
+   elimination offsets will change the hi/lo split, and if we split
+   before reload, we will require additional instructions.   */
+#define REG_OK_FP_BASE_P(X)                    \
+  (REGNO (X) == 31 || REGNO (X) == 63          \
+   || (REGNO (X) >= FIRST_PSEUDO_REGISTER      \
+       && REGNO (X) < LAST_VIRTUAL_REGISTER))
+
 #else
 
 /* Nonzero if X is a hard reg that can be used as an index.  */
 #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+
 /* Nonzero if X is a hard reg that can be used as a base reg.  */
 #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
 
+#define REG_OK_FP_BASE_P(X) 0
+
 #endif
 \f
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
@@ -1366,16 +1423,37 @@ extern void alpha_init_expanders ();
 
    First define the basic valid address.  */
 
-#define GO_IF_LEGITIMATE_SIMPLE_ADDRESS(MODE, X, ADDR) \
-{ if (REG_P (X) && REG_OK_FOR_BASE_P (X))      \
-    goto ADDR;                                 \
-  if (CONSTANT_ADDRESS_P (X))                  \
-    goto ADDR;                                 \
-  if (GET_CODE (X) == PLUS                     \
-      && REG_P (XEXP (X, 0))                   \
-      && REG_OK_FOR_BASE_P (XEXP (X, 0))       \
-      && CONSTANT_ADDRESS_P (XEXP (X, 1)))     \
-    goto ADDR;                                 \
+#define GO_IF_LEGITIMATE_SIMPLE_ADDRESS(MODE, X, ADDR)                 \
+{                                                                      \
+  rtx tmp = (X);                                                       \
+  if (GET_CODE (tmp) == SUBREG                                         \
+      && (GET_MODE_SIZE (GET_MODE (tmp))                               \
+         < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tmp)))))               \
+    tmp = SUBREG_REG (tmp);                                            \
+  if (REG_P (tmp) && REG_OK_FOR_BASE_P (tmp))                          \
+    goto ADDR;                                                         \
+  if (CONSTANT_ADDRESS_P (X))                                          \
+    goto ADDR;                                                         \
+  if (GET_CODE (X) == PLUS)                                            \
+    {                                                                  \
+      tmp = XEXP (X, 0);                                               \
+      if (GET_CODE (tmp) == SUBREG                                     \
+          && (GET_MODE_SIZE (GET_MODE (tmp))                           \
+             < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tmp)))))           \
+        tmp = SUBREG_REG (tmp);                                                \
+      if (REG_P (tmp))                                                 \
+       {                                                               \
+         if (REG_OK_FP_BASE_P (tmp)                                    \
+             && GET_CODE (XEXP (X, 1)) == CONST_INT)                   \
+           goto ADDR;                                                  \
+         if (REG_OK_FOR_BASE_P (tmp)                                   \
+             && CONSTANT_ADDRESS_P (XEXP (X, 1)))                      \
+           goto ADDR;                                                  \
+       }                                                               \
+      else if (GET_CODE (tmp) == ADDRESSOF                             \
+              && CONSTANT_ADDRESS_P (XEXP (X, 1)))                     \
+       goto ADDR;                                                      \
+    }                                                                  \
 }
 
 /* Now accept the simple address, or, for DImode only, an AND of a simple
@@ -1477,6 +1555,18 @@ extern void alpha_init_expanders ();
    
 #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)    \
 do {                                                                   \
+  /* 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)                          \
+    {                                                                  \
+      push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,  \
+                  BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,        \
+                  OPNUM, TYPE);                                        \
+      goto WIN;                                                                \
+    }                                                                  \
   if (GET_CODE (X) == PLUS                                             \
       && GET_CODE (XEXP (X, 0)) == REG                                 \
       && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER                   \
@@ -1500,7 +1590,7 @@ do {                                                                      \
                                      GEN_INT (high)),                  \
                        GEN_INT (low));                                 \
                                                                        \
-      push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR,      \
+      push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,  \
                   BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,        \
                   OPNUM, TYPE);                                        \
       goto WIN;                                                                \
@@ -1559,9 +1649,11 @@ do {                                                                     \
 
 #define MOVE_MAX 8
 
-/* Controls how many units are moved by expr.c before resorting to movstr.
-   Without byte/word accesses, we want no more than one; with, several single
-   byte accesses are better.   */
+/* If a memory-to-memory move would take MOVE_RATIO or more simple
+   move-instruction pairs, we will do a movstr or libcall instead.
+
+   Without byte/word accesses, we want no more than four instructions;
+   with, several single byte accesses are better.   */
 
 #define MOVE_RATIO  (TARGET_BWX ? 7 : 2)
 
@@ -1602,7 +1694,8 @@ do {                                                                      \
 
 /* Define the value returned by a floating-point comparison instruction.  */
 
-#define FLOAT_STORE_FLAG_VALUE (TARGET_FLOAT_VAX ? 0.5 : 2.0)
+#define FLOAT_STORE_FLAG_VALUE(MODE) \
+  REAL_VALUE_ATOF ((TARGET_FLOAT_VAX ? "0.5" : "2.0"), (MODE))
 
 /* Canonicalize a comparison from one we don't have to one we do have.  */
 
@@ -1649,13 +1742,15 @@ do {                                                                    \
    few bits. */
 #define SHIFT_COUNT_TRUNCATED 1
 
-/* Use atexit for static constructors/destructors, instead of defining
-   our own exit function.  */
-#define HAVE_ATEXIT
-
 /* The EV4 is dual issue; EV5/EV6 are quad issue.  */
 #define ISSUE_RATE  (alpha_cpu == PROCESSOR_EV4 ? 2 : 4)
 
+/* Describe the fact that MULTI instructions are multiple instructions
+   and so to assume they don't pair with anything.  */
+#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \
+  if (recog_memoized (INSN) < 0 || get_attr_type (INSN) == TYPE_MULTI)    \
+     (CAN_ISSUE_MORE) = 0
+
 /* Compute the cost of computing a constant rtl expression RTX
    whose rtx-code is CODE.  The body of this macro is a portion
    of a switch statement.  If the code is computed here,
@@ -1672,7 +1767,9 @@ do {                                                                      \
     if (INTVAL (RTX) >= 0 && INTVAL (RTX) < 256)               \
       return 0;                                                        \
   case CONST_DOUBLE:                                           \
-    if (((OUTER_CODE) == PLUS && add_operand (RTX, VOIDmode))  \
+    if ((RTX) == CONST0_RTX (GET_MODE (RTX)))                  \
+      return 0;                                                        \
+    else if (((OUTER_CODE) == PLUS && add_operand (RTX, VOIDmode)) \
        || ((OUTER_CODE) == AND && and_operand (RTX, VOIDmode))) \
       return 0;                                                        \
     else if (add_operand (RTX, VOIDmode) || and_operand (RTX, VOIDmode)) \
@@ -1687,7 +1784,9 @@ do {                                                                      \
     case PROCESSOR_EV4:                                                \
       return COSTS_N_INSNS (3);                                        \
     case PROCESSOR_EV5:                                                \
+    case PROCESSOR_EV6:                                                \
       return COSTS_N_INSNS (2);                                        \
+    default: abort();                                          \
     }
     
 /* Provide the costs of a rtl expression.  This is in the body of a
@@ -1701,7 +1800,9 @@ do {                                                                      \
         case PROCESSOR_EV4:                            \
           return COSTS_N_INSNS (6);                    \
         case PROCESSOR_EV5:                            \
+        case PROCESSOR_EV6:                            \
           return COSTS_N_INSNS (4);                    \
+       default: abort();                               \
        }                                               \
     else if (GET_CODE (XEXP (X, 0)) == MULT            \
             && const48_operand (XEXP (XEXP (X, 0), 1), VOIDmode)) \
@@ -1722,19 +1823,37 @@ do {                                                                    \
           return COSTS_N_INSNS (12);                   \
         else                                           \
           return COSTS_N_INSNS (8);                    \
+      case PROCESSOR_EV6:                              \
+       if (FLOAT_MODE_P (GET_MODE (X)))                \
+         return COSTS_N_INSNS (4);                     \
+       else                                            \
+         return COSTS_N_INSNS (7);                     \
+      default: abort();                                        \
       }                                                        \
   case ASHIFT:                                         \
     if (GET_CODE (XEXP (X, 1)) == CONST_INT            \
        && INTVAL (XEXP (X, 1)) <= 3)                   \
       break;                                           \
     /* ... fall through ... */                         \
-  case ASHIFTRT:  case LSHIFTRT:  case IF_THEN_ELSE:   \
+  case ASHIFTRT:  case LSHIFTRT:                       \
+    switch (alpha_cpu)                                 \
+      {                                                        \
+      case PROCESSOR_EV4:                              \
+        return COSTS_N_INSNS (2);                      \
+      case PROCESSOR_EV5:                              \
+      case PROCESSOR_EV6:                              \
+        return COSTS_N_INSNS (1);                      \
+      default: abort();                                        \
+      }                                                        \
+  case IF_THEN_ELSE:                                   \
     switch (alpha_cpu)                                 \
       {                                                        \
       case PROCESSOR_EV4:                              \
+      case PROCESSOR_EV6:                              \
         return COSTS_N_INSNS (2);                      \
       case PROCESSOR_EV5:                              \
         return COSTS_N_INSNS (1);                      \
+      default: abort();                                        \
       }                                                        \
   case DIV:  case UDIV:  case MOD:  case UMOD:         \
     switch (alpha_cpu)                                 \
@@ -1752,15 +1871,25 @@ do {                                                                    \
         else if (GET_MODE (X) == DFmode)               \
           return COSTS_N_INSNS (22);                   \
         else                                           \
-          return COSTS_N_INSNS (70);   /* EV5 ??? */   \
+          return COSTS_N_INSNS (70);   /* ??? */       \
+      case PROCESSOR_EV6:                              \
+       if (GET_MODE (X) == SFmode)                     \
+         return COSTS_N_INSNS (12);                    \
+        else if (GET_MODE (X) == DFmode)               \
+          return COSTS_N_INSNS (15);                   \
+        else                                           \
+          return COSTS_N_INSNS (70);   /* ??? */       \
+      default: abort();                                        \
       }                                                        \
   case MEM:                                            \
     switch (alpha_cpu)                                 \
       {                                                        \
       case PROCESSOR_EV4:                              \
+      case PROCESSOR_EV6:                              \
         return COSTS_N_INSNS (3);                      \
       case PROCESSOR_EV5:                              \
         return COSTS_N_INSNS (2);                      \
+      default: abort();                                        \
       }                                                        \
   case NEG:  case ABS:                                 \
     if (! FLOAT_MODE_P (GET_MODE (X)))                 \
@@ -1773,7 +1902,9 @@ do {                                                                      \
       case PROCESSOR_EV4:                              \
         return COSTS_N_INSNS (6);                      \
       case PROCESSOR_EV5:                              \
+      case PROCESSOR_EV6:                              \
         return COSTS_N_INSNS (4);                      \
+      default: abort();                                        \
       }
 \f
 /* Control the assembler format that we output.  */
@@ -1788,15 +1919,15 @@ do {                                                                    \
 
 #define ASM_APP_OFF ""
 
-#define TEXT_SECTION_ASM_OP ".text"
+#define TEXT_SECTION_ASM_OP "\t.text"
 
 /* Output before read-only data.  */
 
-#define READONLY_DATA_SECTION_ASM_OP ".rdata"
+#define READONLY_DATA_SECTION_ASM_OP "\t.rdata"
 
 /* Output before writable data.  */
 
-#define DATA_SECTION_ASM_OP ".data"
+#define DATA_SECTION_ASM_OP "\t.data"
 
 /* Define an extra section for read-only data, a routine to enter it, and
    indicate that it is for read-only data.
@@ -1888,33 +2019,34 @@ literal_section ()                                              \
    This is suitable for output with `assemble_name'.  */
 
 #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)  \
-  sprintf (LABEL, "*$%s%d", PREFIX, NUM)
+  sprintf ((LABEL), "*$%s%ld", (PREFIX), (long)(NUM))
 
 /* Check a floating-point value for validity for a particular machine mode.  */
 
 #define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \
   ((OVERFLOW) = check_float_value (MODE, &D, OVERFLOW))
 
+/* This is how to output an assembler line defining a `long double'
+   constant.  */
+
+#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE)                             \
+  do {                                                                 \
+    long t[4];                                                         \
+    REAL_VALUE_TO_TARGET_LONG_DOUBLE ((VALUE), t);                     \
+    fprintf (FILE, "\t.quad 0x%lx%08lx,0x%lx%08lx\n",                  \
+            t[1] & 0xffffffff, t[0] & 0xffffffff,                      \
+            t[3] & 0xffffffff, t[2] & 0xffffffff);                     \
+  } while (0)
+
 /* This is how to output an assembler line defining a `double' constant.  */
 
 #define ASM_OUTPUT_DOUBLE(FILE,VALUE)                                  \
-  {                                                                    \
-    if (REAL_VALUE_ISINF (VALUE)                                       \
-        || REAL_VALUE_ISNAN (VALUE)                                    \
-       || REAL_VALUE_MINUS_ZERO (VALUE))                               \
-      {                                                                        \
-       long t[2];                                                      \
-       REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t);                       \
-       fprintf (FILE, "\t.quad 0x%lx%08lx\n",                          \
-               t[1] & 0xffffffff, t[0] & 0xffffffff);                  \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-       char str[30];                                                   \
-       REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str);                    \
-       fprintf (FILE, "\t.%c_floating %s\n", (TARGET_FLOAT_VAX)?'g':'t', str);                 \
-      }                                                                        \
-  }
+  do {                                                                 \
+    long t[2];                                                         \
+    REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t);                          \
+    fprintf (FILE, "\t.quad 0x%lx%08lx\n",                             \
+            t[1] & 0xffffffff, t[0] & 0xffffffff);                     \
+  } while (0)
 
 /* This is how to output an assembler line defining a `float' constant.  */
 
@@ -1923,7 +2055,7 @@ literal_section ()                                                \
     long t;                                                    \
     REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t);                  \
     fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff);         \
-} while (0)
+  } while (0)
   
 /* This is how to output an assembler line defining an `int' constant.  */
 
@@ -1943,12 +2075,12 @@ literal_section ()                                              \
 
 #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
   fprintf (FILE, "\t.word %d\n",               \
-    (GET_CODE (VALUE) == CONST_INT             \
+    (int)(GET_CODE (VALUE) == CONST_INT                \
      ? INTVAL (VALUE) & 0xffff : (abort (), 0)))
 
 #define ASM_OUTPUT_CHAR(FILE,VALUE)            \
   fprintf (FILE, "\t.byte %d\n",               \
-    (GET_CODE (VALUE) == CONST_INT             \
+    (int)(GET_CODE (VALUE) == CONST_INT                \
      ? INTVAL (VALUE) & 0xff : (abort (), 0)))
 
 /* We use the default ASCII-output routine, except that we don't write more
@@ -1957,12 +2089,12 @@ literal_section ()                                              \
 #define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
   do {                                                                       \
     FILE *_hide_asm_out_file = (MYFILE);                                     \
-    unsigned char *_hide_p = (unsigned char *) (MYSTRING);                   \
+    const unsigned char *_hide_p = (const unsigned char *) (MYSTRING);       \
     int _hide_thissize = (MYLENGTH);                                         \
     int _size_so_far = 0;                                                    \
     {                                                                        \
       FILE *asm_out_file = _hide_asm_out_file;                               \
-      unsigned char *p = _hide_p;                                            \
+      const unsigned char *p = _hide_p;                                              \
       int thissize = _hide_thissize;                                         \
       int i;                                                                 \
       fprintf (asm_out_file, "\t.ascii \"");                                 \
@@ -1996,6 +2128,11 @@ literal_section ()                                               \
   }                                                                          \
   while (0)
 
+/* To get unaligned data, we have to turn off auto alignment.  */
+#define UNALIGNED_SHORT_ASM_OP         "\t.align 0\n\t.word\t"
+#define UNALIGNED_INT_ASM_OP           "\t.align 0\n\t.long\t"
+#define UNALIGNED_DOUBLE_INT_ASM_OP    "\t.align 0\n\t.quad\t"
+
 /* This is how to output an insn to push a register on the stack.
    It need not be very fast code.  */
 
@@ -2015,7 +2152,7 @@ literal_section ()                                                \
 /* This is how to output an assembler line for a numeric constant byte.  */
 
 #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
-  fprintf (FILE, "\t.byte 0x%x\n", (VALUE) & 0xff)
+  fprintf (FILE, "\t.byte 0x%x\n", (int) ((VALUE) & 0xff))
 
 /* This is how to output an element of a case-vector that is absolute.
    (Alpha does not use such vectors, but we must define this macro anyway.)  */
@@ -2073,26 +2210,27 @@ literal_section ()                                              \
 
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
-
+/* ??? This is only used with the v2 ABI, and alpha.c makes assumptions
+   about current_function_is_thunk that are not valid with the v3 ABI.  */
+#if 0
 #define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)       \
 do {                                                                   \
-  char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (FUNCTION)); \
+  const char *fn_name = XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0);       \
+  int reg;                                                             \
+                                                                       \
+  if (! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT)                                \
+    fprintf (FILE, "\tldgp $29,0($27)\n");                             \
                                                                        \
-  fprintf (FILE, "\t.ent ");                                           \
-  assemble_name (FILE, alpha_function_name);                           \
-  fputc ('\n', FILE);                                                  \
-  ASM_OUTPUT_LABEL (FILE, alpha_function_name);                                \
-  fprintf (FILE, "\tldgp $29,0($27)\n");                               \
-  fputc ('$', FILE);                                                   \
-  assemble_name (FILE, alpha_function_name);                           \
-  fprintf (FILE, "..ng:\n");                                           \
-  fprintf (FILE, "\t.frame $30,0,$26,0\n");                            \
-  fprintf (FILE, "\t.prologue 1\n");                                   \
+  /* Mark end of prologue.  */                                         \
+  output_end_prologue (FILE);                                          \
                                                                        \
   /* Rely on the assembler to macro expand a large delta.  */          \
-  fprintf (FILE, "\tlda $16,%ld($16)\n", (long)(DELTA));               \
+  fprintf (FILE, "\t.set at\n");                                       \
+  reg = aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION))) ? 17 : 16;        \
+  fprintf (FILE, "\tlda $%d,%ld($%d)\n", reg, (long)(DELTA), reg);     \
                                                                        \
-  if (current_file_function_operand (XEXP (DECL_RTL (FUNCTION), 0)))   \
+  if (current_file_function_operand (XEXP (DECL_RTL (FUNCTION), 0),    \
+                                    VOIDmode))                         \
     {                                                                  \
       fprintf (FILE, "\tbr $31,$");                                    \
       assemble_name (FILE, fn_name);                                   \
@@ -2100,19 +2238,15 @@ do {                                                                    \
     }                                                                  \
   else                                                                 \
     {                                                                  \
-      fprintf (FILE, "\tlda $27,");                                    \
-      assemble_name (FILE, fn_name);                                   \
-      fprintf (FILE, "\n\tjmp $31,($27),");                            \
+      fprintf (FILE, "\tjmp $31,");                                    \
       assemble_name (FILE, fn_name);                                   \
       fputc ('\n', FILE);                                              \
     }                                                                  \
-                                                                       \
-  fprintf (FILE, "\t.end ");                                           \
-  assemble_name (FILE, alpha_function_name);                           \
-  fputc ('\n', FILE);                                                  \
+  fprintf (FILE, "\t.set noat\n");                                     \
 } while (0)
-
+#endif
 \f
+
 /* Define results of standard character escape sequences.  */
 #define TARGET_BELL 007
 #define TARGET_BS 010
@@ -2129,9 +2263,9 @@ do {                                                                      \
 #define PRINT_OPERAND(FILE, X, CODE)  print_operand (FILE, X, CODE)
 
 /* Determine which codes are valid without a following integer.  These must
-   not be alphabetic (the characters are chosen so that
-   PRINT_OPERAND_PUNCT_VALID_P translates into a simple range change when
-   using ASCII).
+   not be alphabetic.
+
+   ~    Generates the name of the current function.
 
    &   Generates fp-rounding mode suffix: nothing for normal, 'c' for
        chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
@@ -2140,6 +2274,13 @@ do {                                                                     \
    '   Generates trap-mode suffix for instructions that accept the
         su suffix only (cmpt et al).
 
+   `    Generates trap-mode suffix for instructions that accept the
+       v and sv suffix.  The only instruction that needs this is cvtql.
+
+   (   Generates trap-mode suffix for instructions that accept the
+       v, sv, and svi suffix.  The only instruction that needs this
+       is cvttq.
+
    )    Generates trap-mode suffix for instructions that accept the
        u, su, and sui suffix.  This is the bulk of the IEEE floating
        point instructions (addt et al).
@@ -2155,64 +2296,67 @@ do {                                                                    \
    */
 
 #define PRINT_OPERAND_PUNCT_VALID_P(CODE)                              \
-  ((CODE) == '&' || (CODE) == '\'' || (CODE) == ')' || (CODE) == '+'   \
-   || (CODE) == ',' || (CODE) == '-')
+  ((CODE) == '&' || (CODE) == '`' || (CODE) == '\'' || (CODE) == '('   \
+   || (CODE) == ')' || (CODE) == '+' || (CODE) == ',' || (CODE) == '-' \
+   || (CODE) == '~')
 \f
 /* Print a memory address as an operand to reference that memory location.  */
 
-#define PRINT_OPERAND_ADDRESS(FILE, ADDR)              \
-{ rtx addr = (ADDR);                                   \
-  int basereg = 31;                                    \
-  HOST_WIDE_INT offset = 0;                            \
-                                                       \
-  if (GET_CODE (addr) == AND)                          \
-    addr = XEXP (addr, 0);                             \
-                                                       \
-  if (GET_CODE (addr) == REG)                          \
-    basereg = REGNO (addr);                            \
-  else if (GET_CODE (addr) == CONST_INT)               \
-    offset = INTVAL (addr);                            \
-  else if (GET_CODE (addr) == PLUS                     \
-          && GET_CODE (XEXP (addr, 0)) == REG          \
-          && GET_CODE (XEXP (addr, 1)) == CONST_INT)   \
-    basereg = REGNO (XEXP (addr, 0)), offset = INTVAL (XEXP (addr, 1)); \
-  else                                                 \
-    abort ();                                          \
-                                                       \
-  fprintf (FILE, "%d($%d)", offset, basereg);          \
-}
+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
+  print_operand_address((FILE), (ADDR))
+
 /* Define the codes that are matched by predicates in alpha.c.  */
 
-#define PREDICATE_CODES \
-  {"reg_or_0_operand", {SUBREG, REG, CONST_INT}},      \
-  {"reg_or_6bit_operand", {SUBREG, REG, CONST_INT}},   \
-  {"reg_or_8bit_operand", {SUBREG, REG, CONST_INT}},   \
-  {"cint8_operand", {CONST_INT}},                       \
-  {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}},   \
-  {"add_operand", {SUBREG, REG, CONST_INT}},           \
-  {"sext_add_operand", {SUBREG, REG, CONST_INT}},      \
-  {"const48_operand", {CONST_INT}},                    \
-  {"and_operand", {SUBREG, REG, CONST_INT}},           \
-  {"or_operand", {SUBREG, REG, CONST_INT}},            \
-  {"mode_mask_operand", {CONST_INT}},                  \
-  {"mul8_operand", {CONST_INT}},                       \
-  {"mode_width_operand", {CONST_INT}},                 \
-  {"reg_or_fp0_operand", {SUBREG, REG, CONST_DOUBLE}}, \
-  {"alpha_comparison_operator", {EQ, LE, LT, LEU, LTU}}, \
-  {"alpha_swapped_comparison_operator", {EQ, GE, GT, GEU, GTU}}, \
-  {"signed_comparison_operator", {EQ, NE, LE, LT, GE, GT}}, \
-  {"divmod_operator", {DIV, MOD, UDIV, UMOD}},         \
-  {"fp0_operand", {CONST_DOUBLE}},                     \
-  {"current_file_function_operand", {SYMBOL_REF}},     \
-  {"call_operand", {REG, SYMBOL_REF}},                 \
-  {"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE,        \
-                    SYMBOL_REF, CONST, LABEL_REF}},    \
-  {"some_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
-                   SYMBOL_REF, CONST, LABEL_REF}},     \
-  {"aligned_memory_operand", {MEM}},                   \
-  {"unaligned_memory_operand", {MEM}},                 \
-  {"reg_or_unaligned_mem_operand", {SUBREG, REG, MEM}},        \
-  {"any_memory_operand", {MEM}},
+#define PREDICATE_CODES                                                \
+  {"reg_or_0_operand", {SUBREG, REG, CONST_INT}},                      \
+  {"reg_or_6bit_operand", {SUBREG, REG, CONST_INT}},                   \
+  {"reg_or_8bit_operand", {SUBREG, REG, CONST_INT}},                   \
+  {"cint8_operand", {CONST_INT}},                                      \
+  {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}},                   \
+  {"add_operand", {SUBREG, REG, CONST_INT}},                           \
+  {"sext_add_operand", {SUBREG, REG, CONST_INT}},                      \
+  {"const48_operand", {CONST_INT}},                                    \
+  {"and_operand", {SUBREG, REG, CONST_INT}},                           \
+  {"or_operand", {SUBREG, REG, CONST_INT}},                            \
+  {"mode_mask_operand", {CONST_INT}},                                  \
+  {"mul8_operand", {CONST_INT}},                                       \
+  {"mode_width_operand", {CONST_INT}},                                 \
+  {"reg_or_fp0_operand", {SUBREG, REG, CONST_DOUBLE}},                 \
+  {"alpha_comparison_operator", {EQ, LE, LT, LEU, LTU}},               \
+  {"alpha_zero_comparison_operator", {EQ, NE, LE, LT, LEU, LTU}},      \
+  {"alpha_swapped_comparison_operator", {EQ, GE, GT, GEU, GTU}},       \
+  {"signed_comparison_operator", {EQ, NE, LE, LT, GE, GT}},            \
+  {"alpha_fp_comparison_operator", {EQ, LE, LT, UNORDERED}},           \
+  {"divmod_operator", {DIV, MOD, UDIV, UMOD}},                         \
+  {"fp0_operand", {CONST_DOUBLE}},                                     \
+  {"current_file_function_operand", {SYMBOL_REF}},                     \
+  {"call_operand", {REG, SYMBOL_REF}},                                 \
+  {"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE,                \
+                    SYMBOL_REF, CONST, LABEL_REF}},                    \
+  {"some_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE,         \
+                   SYMBOL_REF, CONST, LABEL_REF}},                     \
+  {"some_ni_operand", {SUBREG, REG, MEM}},                             \
+  {"aligned_memory_operand", {MEM}},                                   \
+  {"unaligned_memory_operand", {MEM}},                                 \
+  {"reg_or_unaligned_mem_operand", {SUBREG, REG, MEM}},                        \
+  {"any_memory_operand", {MEM}},                                       \
+  {"hard_fp_register_operand", {SUBREG, REG}},                         \
+  {"hard_int_register_operand", {SUBREG, REG}},                                \
+  {"reg_not_elim_operand", {SUBREG, REG}},                             \
+  {"reg_no_subreg_operand", {REG}},                                    \
+  {"addition_operation", {PLUS}},
+\f
+/* Define the `__builtin_va_list' type for the ABI.  */
+#define BUILD_VA_LIST_TYPE(VALIST) \
+  (VALIST) = alpha_build_va_list ()
+
+/* Implement `va_start' for varargs and stdarg.  */
+#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
+  alpha_va_start (stdarg, valist, nextarg)
+
+/* Implement `va_arg'.  */
+#define EXPAND_BUILTIN_VA_ARG(valist, type) \
+  alpha_va_arg (valist, type)
 \f
 /* Tell collect that the object format is ECOFF.  */
 #define OBJECT_FORMAT_COFF
@@ -2254,14 +2398,14 @@ extern long alpha_auto_offset;
 
 #define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE)                           \
   alpha_output_lineno (STREAM, LINE)
-extern void alpha_output_lineno ();
 
 #define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME)                       \
   alpha_output_filename (STREAM, NAME)
-extern void alpha_output_filename ();
 
-/* mips-tfile.c limits us to strings of one page.  */
-#define DBX_CONTIN_LENGTH 4000
+/* mips-tfile.c limits us to strings of one page.  We must underestimate this
+   number, because the real length runs past this up to the next
+   continuation point.  This is really a dbxout.c bug.  */
+#define DBX_CONTIN_LENGTH 3000
 
 /* By default, turn on GDB extensions.  */
 #define DEFAULT_GDB_EXTENSIONS 1
@@ -2274,9 +2418,9 @@ extern void alpha_output_filename ();
    that the ALPHA assembler does not choke.  The mips-tfile program
    will correctly put the stab into the object file.  */
 
-#define ASM_STABS_OP   ((TARGET_GAS) ? ".stabs" : " #.stabs")
-#define ASM_STABN_OP   ((TARGET_GAS) ? ".stabn" : " #.stabn")
-#define ASM_STABD_OP   ((TARGET_GAS) ? ".stabd" : " #.stabd")
+#define ASM_STABS_OP   ((TARGET_GAS) ? "\t.stabs\t" : " #.stabs\t")
+#define ASM_STABN_OP   ((TARGET_GAS) ? "\t.stabn\t" : " #.stabn\t")
+#define ASM_STABD_OP   ((TARGET_GAS) ? "\t.stabd\t" : " #.stabd\t")
 
 /* Forward references to tags are allowed.  */
 #define SDB_ALLOW_FORWARD_REFERENCES
@@ -2336,7 +2480,7 @@ do {                                                      \
 
 #define PUT_SDB_FUNCTION_END(LINE)
 
-#define PUT_SDB_EPILOGUE_END(NAME)
+#define PUT_SDB_EPILOGUE_END(NAME) ((void)(NAME))
 
 /* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for
    mips-tdump.c to print them out.
@@ -2358,10 +2502,8 @@ do {                                                     \
 
 #define ALIGN_SYMTABLE_OFFSET(OFFSET) (((OFFSET) + 7) & ~7)
 
-/* The linker will stick __main into the .init section.  */
-#define HAS_INIT_SECTION
-#define LD_INIT_SWITCH "-init"
-#define LD_FINI_SWITCH "-fini"
-
 /* The system headers under Alpha systems are generally C++-aware.  */
 #define NO_IMPLICIT_EXTERN_C
+
+/* Generate calls to memcpy, etc., not bcopy, etc. */
+#define TARGET_MEM_FUNCTIONS 1