summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config/alpha
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2002-02-01 18:16:02 +0000
committerobrien <obrien@FreeBSD.org>2002-02-01 18:16:02 +0000
commit170a7bc58bce2fa9766618d7cff7509373d25502 (patch)
treef341c432846517ab5d7a08e6f998ec6ef0834518 /contrib/gcc/config/alpha
parentb50e6bc8e50f2345eff2267c2dd9d57792b5d524 (diff)
parentc9ab9ae440a8066b2c2b85b157b1fdadcf09916a (diff)
downloadFreeBSD-src-170a7bc58bce2fa9766618d7cff7509373d25502.zip
FreeBSD-src-170a7bc58bce2fa9766618d7cff7509373d25502.tar.gz
This commit was generated by cvs2svn to compensate for changes in r90075,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/gcc/config/alpha')
-rw-r--r--contrib/gcc/config/alpha/alpha-interix.h83
-rw-r--r--contrib/gcc/config/alpha/alpha-protos.h187
-rw-r--r--contrib/gcc/config/alpha/alpha.h1102
-rw-r--r--contrib/gcc/config/alpha/alpha.md5095
-rw-r--r--contrib/gcc/config/alpha/alpha32.h37
-rw-r--r--contrib/gcc/config/alpha/crtfastmath.c46
-rw-r--r--contrib/gcc/config/alpha/lib1funcs.asm21
-rw-r--r--contrib/gcc/config/alpha/linux-elf.h5
-rw-r--r--contrib/gcc/config/alpha/linux.h80
-rw-r--r--contrib/gcc/config/alpha/netbsd.h80
-rw-r--r--contrib/gcc/config/alpha/openbsd.h6
-rw-r--r--contrib/gcc/config/alpha/osf.h94
-rw-r--r--contrib/gcc/config/alpha/osf2or3.h4
-rw-r--r--contrib/gcc/config/alpha/osf5.h54
-rw-r--r--contrib/gcc/config/alpha/qrnnd.asm163
-rw-r--r--contrib/gcc/config/alpha/t-alpha2
-rw-r--r--contrib/gcc/config/alpha/t-crtfm4
-rw-r--r--contrib/gcc/config/alpha/t-ieee6
-rw-r--r--contrib/gcc/config/alpha/t-interix11
-rw-r--r--contrib/gcc/config/alpha/t-osf422
-rw-r--r--contrib/gcc/config/alpha/t-unicosmk2
-rw-r--r--contrib/gcc/config/alpha/t-vms24
-rw-r--r--contrib/gcc/config/alpha/t-vms648
-rw-r--r--contrib/gcc/config/alpha/unicosmk.h626
-rw-r--r--contrib/gcc/config/alpha/va_list.h5
-rw-r--r--contrib/gcc/config/alpha/vms-cc.c379
-rw-r--r--contrib/gcc/config/alpha/vms-crt0-64.c99
-rw-r--r--contrib/gcc/config/alpha/vms-crt0.c71
-rw-r--r--contrib/gcc/config/alpha/vms-dwarf2.asm82
-rw-r--r--contrib/gcc/config/alpha/vms-dwarf2eh.asm37
-rw-r--r--contrib/gcc/config/alpha/vms-ld.c777
-rw-r--r--contrib/gcc/config/alpha/vms-psxcrt0-64.c128
-rw-r--r--contrib/gcc/config/alpha/vms-psxcrt0.c99
-rw-r--r--contrib/gcc/config/alpha/vms.h358
-rw-r--r--contrib/gcc/config/alpha/vms64.h32
-rw-r--r--contrib/gcc/config/alpha/vms_tramp.asm52
-rw-r--r--contrib/gcc/config/alpha/vxworks.h4
-rw-r--r--contrib/gcc/config/alpha/x-vms22
-rw-r--r--contrib/gcc/config/alpha/xm-alpha-interix.h8
-rw-r--r--contrib/gcc/config/alpha/xm-vms.h66
-rw-r--r--contrib/gcc/config/alpha/xm-vms64.h29
41 files changed, 7179 insertions, 2831 deletions
diff --git a/contrib/gcc/config/alpha/alpha-interix.h b/contrib/gcc/config/alpha/alpha-interix.h
index 668fe93..4dc2186 100644
--- a/contrib/gcc/config/alpha/alpha-interix.h
+++ b/contrib/gcc/config/alpha/alpha-interix.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha
running Windows/NT.
- Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1999, 2000 Free Software Foundation, Inc.
Donn Terry, Softway Systems, Inc.
From code
@@ -33,13 +33,13 @@ Boston, MA 02111-1307, USA. */
-D__alpha -D__alpha__\
-D__stdcall= \
-D__cdecl= \
- -Asystem(unix) -Asystem(interix) -Asystem(interix) -Acpu(alpha) -Amachine(alpha)"
+ -Asystem=unix -Asystem=interix -Acpu=alpha -Amachine=alpha"
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC "\
-remap \
%{posix:-D_POSIX_SOURCE} \
--idirafter %$INTERIX_ROOT/usr/include"
+-isystem %$INTERIX_ROOT/usr/include"
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (alpha Interix)");
@@ -62,12 +62,6 @@ Boston, MA 02111-1307, USA. */
#undef PUT_SDB_BLOCK_START
#undef PUT_SDB_BLOCK_END
-/* the following are OSF linker (not gld) specific... we don't want them */
-#undef HAS_INIT_SECTION
-#undef LD_INIT_SWITCH
-#undef LD_FINI_SWITCH
-
-
/* The following are needed for C++, but also needed for profiling */
/* Support const sections and the ctors and dtors sections for g++.
@@ -80,7 +74,7 @@ Boston, MA 02111-1307, USA. */
#define USE_CONST_SECTION 1
-#define CONST_SECTION_ASM_OP ".rdata"
+#define CONST_SECTION_ASM_OP "\t.rdata"
/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
@@ -97,8 +91,8 @@ Boston, MA 02111-1307, USA. */
errors unless the .ctors and .dtors sections are marked as writable
via the SHF_WRITE attribute.) */
-#define CTORS_SECTION_ASM_OP ".ctors"
-#define DTORS_SECTION_ASM_OP ".dtors"
+#define CTORS_SECTION_ASM_OP "\t.ctors"
+#define DTORS_SECTION_ASM_OP "\t.dtors"
/* A default list of other sections which we might be "in" at any given
time. For targets that use additional sections (e.g. .tdesc) you
@@ -106,7 +100,7 @@ Boston, MA 02111-1307, USA. */
includes this file. */
#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_const, in_ctors, in_dtors
+#define EXTRA_SECTIONS in_const
/* A default list of extra section function definitions. For targets
that use additional sections (e.g. .tdesc) you should override this
@@ -114,15 +108,11 @@ Boston, MA 02111-1307, USA. */
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
- CONST_SECTION_FUNCTION \
- CTORS_SECTION_FUNCTION \
- DTORS_SECTION_FUNCTION
+ CONST_SECTION_FUNCTION
#undef READONLY_DATA_SECTION
#define READONLY_DATA_SECTION() const_section ()
-extern void text_section ();
-
#define CONST_SECTION_FUNCTION \
void \
const_section () \
@@ -136,55 +126,11 @@ const_section () \
} \
}
-#define CTORS_SECTION_FUNCTION \
-void \
-ctors_section () \
-{ \
- if (in_section != in_ctors) \
- { \
- fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \
- in_section = in_ctors; \
- } \
-}
-
-#define DTORS_SECTION_FUNCTION \
-void \
-dtors_section () \
-{ \
- if (in_section != in_dtors) \
- { \
- fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \
- in_section = in_dtors; \
- } \
-}
-
-#define INT_ASM_OP ".long"
-
-/* A C statement (sans semicolon) to output an element in the table of
- global constructors. */
-#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
- do { \
- ctors_section (); \
- fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
- assemble_name (FILE, NAME); \
- fprintf (FILE, "\n"); \
- } while (0)
-
-/* A C statement (sans semicolon) to output an element in the table of
- global destructors. */
-#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
- do { \
- dtors_section (); \
- fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
- assemble_name (FILE, NAME); \
- fprintf (FILE, "\n"); \
- } while (0)
-
/* The linker will take care of this, and having them causes problems with
- ld -r (specifically -rU). */
+ ld -r (specifically -rU). */
#define CTOR_LISTS_DEFINED_EXTERNALLY 1
-#define SET_ASM_OP ".set"
+#define SET_ASM_OP "\t.set\t"
/* Output a definition (implements alias) */
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
do \
@@ -209,10 +155,11 @@ while (0)
#define PCC_BITFIELD_TYPE_TEST TYPE_NATIVE(rec)
#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
-/* DWARF2 Unwinding doesn't work with exception handling yet. */
+/* DWARF2 Unwinding doesn't work with exception handling yet. */
#undef DWARF2_UNWIND_INFO
+#define DWARF2_UNWIND_INFO 0
-/* Don't assume anything about the header files. */
+/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
/* The definition of this macro implies that there are cases where
@@ -220,7 +167,7 @@ while (0)
On NT (according to the spec) anything except strings/array that fits
in 64 bits is returned in the registers (this appears to differ from
- the rest of the Alpha family). */
+ the rest of the Alpha family). */
#undef RETURN_IN_MEMORY
#define RETURN_IN_MEMORY(TYPE) \
@@ -240,7 +187,7 @@ while (0)
}
/* The current Interix assembler (consistent with the DEC documentation)
- uses a=b NOT .set a,b; .set is for assembler options. */
+ uses a=b NOT .set a,b; .set is for assembler options. */
#undef ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL
#define ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL(FILE, SY, HI, LO) \
do { \
diff --git a/contrib/gcc/config/alpha/alpha-protos.h b/contrib/gcc/config/alpha/alpha-protos.h
new file mode 100644
index 0000000..2ff0350
--- /dev/null
+++ b/contrib/gcc/config/alpha/alpha-protos.h
@@ -0,0 +1,187 @@
+/* Prototypes for alpha.c functions used in the md file & elsewhere.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+extern int alpha_next_sequence_number;
+
+extern void literal_section PARAMS ((void));
+extern void override_options PARAMS ((void));
+extern int zap_mask PARAMS ((HOST_WIDE_INT));
+extern int direct_return PARAMS ((void));
+
+extern int alpha_sa_size PARAMS ((void));
+extern int alpha_pv_save_size PARAMS ((void));
+extern int alpha_using_fp PARAMS ((void));
+extern void alpha_write_verstamp PARAMS ((FILE *));
+extern void alpha_expand_prologue PARAMS ((void));
+extern void alpha_expand_epilogue PARAMS ((void));
+extern void alpha_output_filename PARAMS ((FILE *, const char *));
+extern void alpha_output_lineno PARAMS ((FILE *, int));
+
+#ifdef RTX_CODE
+extern int reg_or_0_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_6bit_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_8bit_operand PARAMS ((rtx, enum machine_mode));
+extern int cint8_operand PARAMS ((rtx, enum machine_mode));
+extern int add_operand PARAMS ((rtx, enum machine_mode));
+extern int sext_add_operand PARAMS ((rtx, enum machine_mode));
+extern int const48_operand PARAMS ((rtx, enum machine_mode));
+extern int and_operand PARAMS ((rtx, enum machine_mode));
+extern int or_operand PARAMS ((rtx, enum machine_mode));
+extern int mode_width_operand PARAMS ((rtx, enum machine_mode));
+extern int mode_mask_operand PARAMS ((rtx, enum machine_mode));
+extern int mul8_operand PARAMS ((rtx, enum machine_mode));
+extern int fp0_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_fp0_operand PARAMS ((rtx, enum machine_mode));
+extern int hard_fp_register_operand PARAMS ((rtx, enum machine_mode));
+extern int hard_int_register_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode));
+extern int some_operand PARAMS ((rtx, enum machine_mode));
+extern int some_ni_operand PARAMS ((rtx, enum machine_mode));
+extern int input_operand PARAMS ((rtx, enum machine_mode));
+extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
+extern int direct_call_operand PARAMS ((rtx, enum machine_mode));
+extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
+extern int small_symbolic_operand PARAMS ((rtx, enum machine_mode));
+extern int some_small_symbolic_mem_operand PARAMS ((rtx, enum machine_mode));
+extern int global_symbolic_operand PARAMS ((rtx, enum machine_mode));
+extern int call_operand PARAMS ((rtx, enum machine_mode));
+extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
+extern int alpha_comparison_operator PARAMS ((rtx, enum machine_mode));
+extern int alpha_zero_comparison_operator PARAMS ((rtx, enum machine_mode));
+extern int alpha_swapped_comparison_operator PARAMS ((rtx, enum machine_mode));
+extern int signed_comparison_operator PARAMS ((rtx, enum machine_mode));
+extern int alpha_fp_comparison_operator PARAMS ((rtx, enum machine_mode));
+extern int divmod_operator PARAMS ((rtx, enum machine_mode));
+extern int aligned_memory_operand PARAMS ((rtx, enum machine_mode));
+extern int unaligned_memory_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_unaligned_mem_operand PARAMS ((rtx, enum machine_mode));
+extern int any_memory_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_not_elim_operand PARAMS ((rtx, enum machine_mode));
+extern int normal_memory_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_no_subreg_operand PARAMS ((rtx, enum machine_mode));
+extern int addition_operation PARAMS ((rtx, enum machine_mode));
+
+extern bool alpha_const_ok_for_letter_p PARAMS ((HOST_WIDE_INT, int));
+extern bool alpha_const_double_ok_for_letter_p PARAMS ((rtx, int));
+extern bool alpha_extra_constraint PARAMS ((rtx, int));
+
+extern rtx alpha_tablejump_addr_vec PARAMS ((rtx));
+extern rtx alpha_tablejump_best_label PARAMS ((rtx));
+
+extern bool alpha_legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
+extern rtx alpha_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
+extern rtx alpha_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
+ int, int, int));
+
+extern rtx split_small_symbolic_mem_operand PARAMS ((rtx));
+
+extern void get_aligned_mem PARAMS ((rtx, rtx *, rtx *));
+extern rtx get_unaligned_address PARAMS ((rtx, int));
+extern enum reg_class alpha_preferred_reload_class PARAMS ((rtx,
+ enum reg_class));
+extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
+ enum machine_mode,
+ rtx, int));
+
+extern void alpha_set_memflags PARAMS ((rtx, rtx));
+extern rtx alpha_emit_set_const PARAMS ((rtx, enum machine_mode,
+ HOST_WIDE_INT, int));
+extern rtx alpha_emit_set_long_const PARAMS ((rtx, HOST_WIDE_INT,
+ HOST_WIDE_INT));
+extern bool alpha_expand_mov PARAMS ((enum machine_mode, rtx *));
+extern bool alpha_expand_mov_nobwx PARAMS ((enum machine_mode, rtx *));
+extern void alpha_emit_floatuns PARAMS ((rtx[]));
+extern rtx alpha_emit_conditional_branch PARAMS ((enum rtx_code));
+extern rtx alpha_emit_setcc PARAMS ((enum rtx_code));
+extern rtx alpha_emit_conditional_move PARAMS ((rtx, enum machine_mode));
+extern int alpha_split_conditional_move PARAMS ((enum rtx_code, rtx, rtx,
+ rtx, rtx));
+extern void alpha_emit_xfloating_arith PARAMS ((enum rtx_code, rtx[]));
+extern void alpha_emit_xfloating_cvt PARAMS ((enum rtx_code, rtx[]));
+extern void alpha_split_tfmode_pair PARAMS ((rtx[]));
+extern void alpha_split_tfmode_frobsign PARAMS ((rtx[],
+ rtx (*)(rtx, rtx, rtx)));
+extern void alpha_expand_unaligned_load PARAMS ((rtx, rtx, HOST_WIDE_INT,
+ HOST_WIDE_INT, int));
+extern void alpha_expand_unaligned_store PARAMS ((rtx, rtx, HOST_WIDE_INT,
+ HOST_WIDE_INT));
+extern int alpha_expand_block_move PARAMS ((rtx []));
+extern int alpha_expand_block_clear PARAMS ((rtx []));
+extern rtx alpha_return_addr PARAMS ((int, rtx));
+extern rtx alpha_gp_save_rtx PARAMS ((void));
+extern void print_operand PARAMS ((FILE *, rtx, int));
+extern void print_operand_address PARAMS ((FILE *, rtx));
+extern void alpha_initialize_trampoline PARAMS ((rtx, rtx, rtx, int, int, int));
+extern void alpha_reorg PARAMS ((rtx));
+#endif /* RTX_CODE */
+
+#ifdef REAL_VALUE_TYPE
+extern int check_float_value PARAMS ((enum machine_mode,
+ REAL_VALUE_TYPE *, int));
+#endif
+
+#if TARGET_ABI_OPEN_VMS
+#ifdef HAVE_MACHINE_MODES
+extern enum avms_arg_type alpha_arg_type PARAMS ((enum machine_mode));
+#endif
+#ifdef RTX_CODE
+extern rtx alpha_arg_info_reg_val PARAMS ((CUMULATIVE_ARGS));
+#endif
+#ifdef BUFSIZ
+extern void alpha_write_linkage PARAMS ((FILE *));
+#endif
+#endif /* TARGET_ABI_OPEN_VMS */
+
+#ifdef RTX_CODE
+extern rtx alpha_need_linkage PARAMS ((const char *, int));
+#endif
+
+#ifdef TREE_CODE
+extern tree alpha_build_va_list PARAMS ((void));
+#ifdef RTX_CODE
+extern void alpha_va_start PARAMS ((int, tree, rtx));
+extern rtx alpha_va_arg PARAMS ((tree, tree));
+extern rtx function_arg PARAMS ((CUMULATIVE_ARGS, enum machine_mode,
+ tree, int));
+#endif
+extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
+extern void alpha_end_function PARAMS ((FILE *, const char *, tree));
+extern void alpha_encode_section_info PARAMS ((tree));
+#endif /* TREE CODE */
+
+#ifdef RTX_CODE
+extern rtx unicosmk_add_call_info_word PARAMS ((rtx));
+#endif
+
+#if TARGET_ABI_UNICOSMK
+#ifdef RTX_CODE
+extern void unicosmk_defer_case_vector PARAMS ((rtx, rtx));
+#endif
+#ifdef TREE_CODE
+extern void unicosmk_unique_section PARAMS ((tree, int));
+#endif
+extern void unicosmk_add_extern PARAMS ((const char *));
+extern void unicosmk_output_align PARAMS ((FILE *, int));
+extern char * unicosmk_text_section PARAMS ((void));
+extern char * unicosmk_data_section PARAMS ((void));
+extern void unicosmk_asm_file_start PARAMS ((FILE *));
+extern void unicosmk_asm_file_end PARAMS ((FILE *));
+extern void unicosmk_output_common PARAMS ((FILE *, const char *, int, int));
+#endif /* TARGET_ABI_UNICOSMK */
diff --git a/contrib/gcc/config/alpha/alpha.h b/contrib/gcc/config/alpha/alpha.h
index e9c3f6d..dd8d820 100644
--- a/contrib/gcc/config/alpha/alpha.h
+++ b/contrib/gcc/config/alpha/alpha.h
@@ -1,5 +1,6 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha.
- Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
@@ -20,14 +21,20 @@ 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 "\
%{!undef:\
%{.S:-D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY }}\
-%{.cc|.cxx|.C:-D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus }\
%{.m:-D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C }\
-%{!.S:%{!.cc:%{!.cxx:%{!.C:%{!.m:-D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_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)"
@@ -43,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
@@ -68,20 +71,20 @@ enum alpha_trap_precision
{
ALPHA_TP_PROG, /* No precision (default). */
ALPHA_TP_FUNC, /* Trap contained within originating function. */
- ALPHA_TP_INSN /* Instruction accuracy and code is resumption safe. */
+ ALPHA_TP_INSN /* Instruction accuracy and code is resumption safe. */
};
enum alpha_fp_rounding_mode
{
ALPHA_FPRM_NORM, /* Normal rounding mode. */
ALPHA_FPRM_MINF, /* Round towards minus-infinity. */
- ALPHA_FPRM_CHOP, /* Chopped rounding mode (towards 0). */
+ ALPHA_FPRM_CHOP, /* Chopped rounding mode (towards 0). */
ALPHA_FPRM_DYN /* Dynamic rounding mode. */
};
enum alpha_fp_trap_mode
{
- ALPHA_FPTM_N, /* Normal trap mode. */
+ ALPHA_FPTM_N, /* Normal trap mode. */
ALPHA_FPTM_U, /* Underflow traps enabled. */
ALPHA_FPTM_SU, /* Software completion, w/underflow traps */
ALPHA_FPTM_SUI /* Software completion, w/underflow & inexact traps */
@@ -110,7 +113,7 @@ extern enum alpha_fp_trap_mode alpha_fptm;
#define MASK_GAS (1 << 2)
#define TARGET_GAS (target_flags & MASK_GAS)
-/* This means that we should mark procedures as IEEE conformant. */
+/* This means that we should mark procedures as IEEE conformant. */
#define MASK_IEEE_CONFORMANT (1 << 3)
#define TARGET_IEEE_CONFORMANT (target_flags & MASK_IEEE_CONFORMANT)
@@ -155,12 +158,22 @@ extern enum alpha_fp_trap_mode alpha_fptm;
#define MASK_CIX (1 << 11)
#define TARGET_CIX (target_flags & MASK_CIX)
-/* This means that the processor is an EV5, EV56, or PCA56. This is defined
- only in TARGET_CPU_DEFAULT. */
+/* This means use !literal style explicit relocations. */
+#define MASK_EXPLICIT_RELOCS (1 << 12)
+#define TARGET_EXPLICIT_RELOCS (target_flags & MASK_EXPLICIT_RELOCS)
+
+/* This means use 16-bit relocations to .sdata/.sbss. */
+#define MASK_SMALL_DATA (1 << 13)
+#define TARGET_SMALL_DATA (target_flags & MASK_SMALL_DATA)
+
+/* 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 (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. */
@@ -168,19 +181,34 @@ extern enum alpha_fp_trap_mode alpha_fptm;
#define TARGET_SUPPORT_ARCH (target_flags & MASK_SUPPORT_ARCH)
/* These are for target os support and cannot be changed at runtime. */
-#ifndef TARGET_WINDOWS_NT
-#define TARGET_WINDOWS_NT 0
-#endif
-#ifndef TARGET_OPEN_VMS
-#define TARGET_OPEN_VMS 0
-#endif
+#define TARGET_ABI_WINDOWS_NT 0
+#define TARGET_ABI_OPEN_VMS 0
+#define TARGET_ABI_UNICOSMK 0
+#define TARGET_ABI_OSF (!TARGET_ABI_WINDOWS_NT \
+ && !TARGET_ABI_OPEN_VMS \
+ && !TARGET_ABI_UNICOSMK)
#ifndef TARGET_AS_CAN_SUBTRACT_LABELS
#define TARGET_AS_CAN_SUBTRACT_LABELS TARGET_GAS
#endif
+#ifndef TARGET_AS_SLASH_BEFORE_SUFFIX
+#define TARGET_AS_SLASH_BEFORE_SUFFIX 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
+#ifndef TARGET_FIXUP_EV5_PREFETCH
+#define TARGET_FIXUP_EV5_PREFETCH 0
+#endif
/* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces,
@@ -189,31 +217,42 @@ extern enum alpha_fp_trap_mode alpha_fptm;
An empty string NAME is used to identify the default VALUE. */
#define TARGET_SWITCHES \
- { {"no-soft-float", MASK_FP, "Use hardware fp"}, \
- {"soft-float", - MASK_FP, "Do not use hardware fp"}, \
- {"fp-regs", MASK_FPREGS, "Use fp registers"}, \
- {"no-fp-regs", - (MASK_FP|MASK_FPREGS), "Do not use fp registers"}, \
- {"alpha-as", -MASK_GAS, "Do not assume GAS"}, \
- {"gas", MASK_GAS, "Assume GAS"}, \
+ { {"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, \
- "Request IEEE-conformant math library routines (OSF/1)"}, \
+ N_("Request IEEE-conformant math library routines (OSF/1)")}, \
{"ieee", MASK_IEEE|MASK_IEEE_CONFORMANT, \
- "Emit IEEE-conformant code, without inexact exceptions"}, \
+ N_("Emit IEEE-conformant code, without inexact exceptions")}, \
{"ieee-with-inexact", MASK_IEEE_WITH_INEXACT|MASK_IEEE_CONFORMANT, \
- "Emit IEEE-conformant code, with inexact exceptions"}, \
+ N_("Emit IEEE-conformant code, with inexact exceptions")}, \
{"build-constants", MASK_BUILD_CONSTANTS, \
- "Do not emit complex integer constants to read-only memory"}, \
- {"float-vax", MASK_FLOAT_VAX, "Use VAX fp"}, \
- {"float-ieee", -MASK_FLOAT_VAX, "Do not use VAX fp"}, \
- {"bwx", MASK_BWX, "Emit code for the byte/word ISA extension"}, \
+ 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, "Emit code for the motion video ISA extension"}, \
+ {"max", MASK_MAX, \
+ N_("Emit code for the motion video ISA extension")}, \
{"no-max", -MASK_MAX, ""}, \
- {"fix", MASK_FIX, "Emit code for the fp move and sqrt ISA extension"}, \
+ {"fix", MASK_FIX, \
+ N_("Emit code for the fp move and sqrt ISA extension")}, \
{"no-fix", -MASK_FIX, ""}, \
- {"cix", MASK_CIX, "Emit code for the counting ISA extension"}, \
+ {"cix", MASK_CIX, N_("Emit code for the counting ISA extension")}, \
{"no-cix", -MASK_CIX, ""}, \
- {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT, ""} }
+ {"explicit-relocs", MASK_EXPLICIT_RELOCS, \
+ N_("Emit code using explicit relocation directives")}, \
+ {"no-explicit-relocs", -MASK_EXPLICIT_RELOCS, ""}, \
+ {"small-data", MASK_SMALL_DATA, \
+ N_("Emit 16-bit relocations to the small data areas")}, \
+ {"large-data", -MASK_SMALL_DATA, \
+ N_("Emit 32-bit relocations to the small data areas")}, \
+ {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT \
+ | TARGET_DEFAULT_EXPLICIT_RELOCS, ""} }
#define TARGET_DEFAULT MASK_FP|MASK_FPREGS
@@ -221,24 +260,16 @@ extern enum alpha_fp_trap_mode alpha_fptm;
#define TARGET_CPU_DEFAULT 0
#endif
-/* This macro is similar to `TARGET_SWITCHES' but defines names of
- command options that have values. Its definition is an initializer
- with a subgrouping for each command option.
-
- Each subgrouping contains a string constant, that defines the fixed
- part of the option name, and the address of a variable. The
- variable, type `char *', is set to the variable part of the given
- option if the fixed part matches. The actual option name is made
- by appending `-m' to the specified name.
-
- Here is an example which defines `-mshort-data-NUMBER'. If the
- given option is `-mshort-data-512', the variable `m88k_short_data'
- will be set to the string `"512"'.
-
- extern char *m88k_short_data;
- #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */
+#ifndef TARGET_DEFAULT_EXPLICIT_RELOCS
+#ifdef HAVE_AS_EXPLICIT_RELOCS
+#define TARGET_DEFAULT_EXPLICIT_RELOCS MASK_EXPLICIT_RELOCS
+#else
+#define TARGET_DEFAULT_EXPLICIT_RELOCS 0
+#endif
+#endif
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] */
@@ -247,40 +278,49 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
#define TARGET_OPTIONS \
{ \
{"cpu=", &alpha_cpu_string, \
- "Generate code for a given CPU"}, \
+ N_("Use features of and schedule given CPU")}, \
+ {"tune=", &alpha_tune_string, \
+ N_("Schedule given CPU")}, \
{"fp-rounding-mode=", &alpha_fprm_string, \
- "Control the generated fp rounding mode"}, \
+ N_("Control the generated fp rounding mode")}, \
{"fp-trap-mode=", &alpha_fptm_string, \
- "Control the IEEE trap mode"}, \
+ N_("Control the IEEE trap mode")}, \
{"trap-precision=", &alpha_tp_string, \
- "Control the precision given to fp exceptions"}, \
+ N_("Control the precision given to fp exceptions")}, \
{"memory-latency=", &alpha_mlat_string, \
- "Tune expected memory latency"}, \
+ 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 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)"
+/* 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_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
-# define CPP_CPU_DEFAULT_SPEC CPP_CPU_EV6_SPEC
+# 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
@@ -300,12 +340,13 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
#ifndef CPP_CPU_SPEC
#define CPP_CPU_SPEC "\
-%{!undef:-Acpu(alpha) -Amachine(alpha) -D__alpha -D__alpha__ \
+%{!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
@@ -336,6 +377,7 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
{ "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 }, \
@@ -351,7 +393,6 @@ extern const 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 ()
@@ -360,36 +401,23 @@ extern void override_options ();
On the Alpha, we use this to disable the floating-point registers when
they don't exist. */
-#define CONDITIONAL_REGISTER_USAGE \
- if (! TARGET_FPREGS) \
- for (i = 32; i < 63; i++) \
- fixed_regs[i] = call_used_regs[i] = 1;
+#define CONDITIONAL_REGISTER_USAGE \
+{ \
+ int i; \
+ if (! TARGET_FPREGS) \
+ for (i = 32; i < 63; i++) \
+ fixed_regs[i] = call_used_regs[i] = 1; \
+}
+
/* Show we can debug even without a frame pointer. */
#define CAN_DEBUG_WITHOUT_FP
/* target machine storage layout */
-/* Define to enable software floating point emulation. */
+/* 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
@@ -449,7 +477,7 @@ extern void override_options ();
numbered.
For Alpha we can decide arbitrarily since there are no machine instructions
- for them. Might as well be consistent with bytes. */
+ for them. Might as well be consistent with bytes. */
#define WORDS_BIG_ENDIAN 0
/* number of bits in an addressable storage unit */
@@ -475,7 +503,7 @@ extern void override_options ();
#define STACK_BOUNDARY 64
/* Allocation boundary (in *bits*) for the code of a function. */
-#define FUNCTION_BOUNDARY 256
+#define FUNCTION_BOUNDARY 32
/* Alignment of field after `int : 0' in a structure. */
#define EMPTY_FIELD_BOUNDARY 64
@@ -486,28 +514,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. */
-
-#define LOOP_ALIGN(LABEL) \
- (optimize > 0 && write_symbols != SDB_DEBUG ? 4 : 0)
-
-/* This is how to align an instruction for optimal branching. On
- Alpha we'll get better performance by aligning on an octaword
- boundary. */
-
-#define LABEL_ALIGN_AFTER_BARRIER(FILE) \
- (optimize > 0 && write_symbols != SDB_DEBUG ? 4 : 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. */
@@ -529,7 +541,7 @@ extern void override_options ();
On the Alpha, they trap. */
-#define SLOW_UNALIGNED_ACCESS 1
+#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 1
/* Standard register usage. */
@@ -675,6 +687,18 @@ extern void override_options ();
doesn't seem to specify this. */
#define STATIC_CHAIN_REGNUM 1
+/* The register number of the register used to address a table of
+ static data addresses in memory. */
+#define PIC_OFFSET_TABLE_REGNUM 29
+
+/* Define this macro if the register defined by `PIC_OFFSET_TABLE_REGNUM'
+ is clobbered by calls. */
+/* ??? It is and it isn't. It's required to be valid for a given
+ function when the function returns. It isn't clobbered by
+ current_file functions. Moreover, we do not expose the ldgp
+ until after reload, so we're probably safe. */
+/* #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED */
+
/* Register in which address to store a structure value
arrives in the function. On the Alpha, the address is passed
as a hidden argument. */
@@ -700,30 +724,44 @@ 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,
- LIM_REG_CLASSES };
+enum reg_class {
+ NO_REGS, R24_REG, R25_REG, R27_REG,
+ GENERAL_REGS, FLOAT_REGS, ALL_REGS,
+ LIM_REG_CLASSES
+};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
-/* Give names of register classes as strings for dump file. */
+/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
- {"NO_REGS", "GENERAL_REGS", "FLOAT_REGS", "ALL_REGS" }
+ {"NO_REGS", "R24_REG", "R25_REG", "R27_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} }
+#define REG_CLASS_CONTENTS \
+{ {0x00000000, 0x00000000}, /* NO_REGS */ \
+ {0x01000000, 0x00000000}, /* R24_REG */ \
+ {0x02000000, 0x00000000}, /* R25_REG */ \
+ {0x08000000, 0x00000000}, /* R27_REG */ \
+ {0xffffffff, 0x80000000}, /* GENERAL_REGS */ \
+ {0x00000000, 0x7fffffff}, /* FLOAT_REGS */ \
+ {0xffffffff, 0xffffffff} }
/* 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) == 24 ? R24_REG \
+ : (REGNO) == 25 ? R25_REG \
+ : (REGNO) == 27 ? R27_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
@@ -732,7 +770,11 @@ 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) == 'a' ? R24_REG \
+ : (C) == 'b' ? R25_REG \
+ : (C) == 'c' ? R27_REG \
+ : (C) == 'f' ? FLOAT_REGS \
+ : NO_REGS)
/* Define this macro to change register usage conditional on target flags. */
/* #define CONDITIONAL_REGISTER_USAGE */
@@ -753,17 +795,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
`O' is used for negated 8-bit constants.
`P' is used for the constants 1, 2 and 3. */
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'I' ? (unsigned HOST_WIDE_INT) (VALUE) < 0x100 \
- : (C) == 'J' ? (VALUE) == 0 \
- : (C) == 'K' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000 \
- : (C) == 'L' ? (((VALUE) & 0xffff) == 0 \
- && (((VALUE)) >> 31 == -1 || (VALUE) >> 31 == 0)) \
- : (C) == 'M' ? zap_mask (VALUE) \
- : (C) == 'N' ? (unsigned HOST_WIDE_INT) (~ (VALUE)) < 0x100 \
- : (C) == 'O' ? (unsigned HOST_WIDE_INT) (- (VALUE)) < 0x100 \
- : (C) == 'P' ? (VALUE) == 1 || (VALUE) == 2 || (VALUE) == 3 \
- : 0)
+#define CONST_OK_FOR_LETTER_P alpha_const_ok_for_letter_p
/* Similar, but for floating or large integer constants, and defining letters
G and H. Here VALUE is the CONST_DOUBLE rtx itself.
@@ -771,13 +803,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
For Alpha, `G' is the floating-point constant zero. `H' is a CONST_DOUBLE
that is the operand of a ZAP insn. */
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
- && (VALUE) == CONST0_RTX (GET_MODE (VALUE))) \
- : (C) == 'H' ? (GET_MODE (VALUE) == VOIDmode \
- && zap_mask (CONST_DOUBLE_LOW (VALUE)) \
- && zap_mask (CONST_DOUBLE_HIGH (VALUE))) \
- : 0)
+#define CONST_DOUBLE_OK_FOR_LETTER_P alpha_const_double_ok_for_letter_p
/* Optional extra constraints for this machine.
@@ -787,78 +813,40 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
`R' is a SYMBOL_REF that has SYMBOL_REF_FLAG set or is the current
function.
- 'S' is a 6-bit constant (valid for a shift insn). */
+ 'S' is a 6-bit constant (valid for a shift insn).
+
+ 'T' is a HIGH.
-#define EXTRA_CONSTRAINT(OP, C) \
- ((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)
-extern int normal_memory_operand ();
+ 'U' is a symbolic operand. */
+
+#define EXTRA_CONSTRAINT alpha_extra_constraint
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
In general this is just CLASS; but on some machines
- in some cases it is preferable to use a more restrictive class.
-
- On the Alpha, all constants except zero go into a floating-point
- register via memory. */
+ in some cases it is preferable to use a more restrictive class. */
-#define PREFERRED_RELOAD_CLASS(X, CLASS) \
- (CONSTANT_P (X) && (X) != const0_rtx && (X) != CONST0_RTX (GET_MODE (X)) \
- ? ((CLASS) == FLOAT_REGS || (CLASS) == NO_REGS ? NO_REGS : GENERAL_REGS)\
- : (CLASS))
+#define PREFERRED_RELOAD_CLASS alpha_preferred_reload_class
/* Loading and storing HImode or QImode values to and from memory
usually requires a scratch register. The exceptions are loading
QImode and HImode from an aligned address to a general register
unless byte instructions are permitted.
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 && ! aligned_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)
+ FP register. */
+
+#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 FIX extension is available. */
#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
- (! TARGET_FIX && (CLASS1) != (CLASS2))
+ (! TARGET_FIX && (((CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS) \
+ || ((CLASS2) == FLOAT_REGS && (CLASS1) != FLOAT_REGS)))
/* Specify the mode to be used for memory when a secondary memory
location is needed. If MODE is floating-point, use it. Otherwise,
@@ -877,9 +865,14 @@ extern int normal_memory_operand ();
((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
-#define CLASS_CANNOT_CHANGE_SIZE FLOAT_REGS
+/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
+
+#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.
@@ -888,7 +881,7 @@ extern int normal_memory_operand ();
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_FIX ? 3 : 4+2*alpha_memory_latency)
@@ -903,11 +896,6 @@ extern int alpha_memory_latency;
/* Provide the cost of a branch. Exact meaning under development. */
#define BRANCH_COST 5
-
-/* Adjust the cost of dependencies. */
-
-#define ADJUST_COST(INSN,LINK,DEP,COST) \
- (COST) = alpha_adjust_cost (INSN, LINK, DEP, COST)
/* Stack layout; function entry, exit and calling. */
@@ -939,7 +927,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. */
@@ -950,7 +938,7 @@ extern int alpha_memory_latency;
We have two registers that can be eliminated on the Alpha. First, the
frame pointer register can often be eliminated in favor of the stack
pointer register. Secondly, the argument pointer register can always be
- eliminated; it is replaced with either the stack or frame pointer. */
+ eliminated; it is replaced with either the stack or frame pointer. */
/* This is an array of structures. Each structure initializes one pair
of eliminable registers. The "from" register number is given first,
@@ -986,6 +974,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
@@ -1009,25 +999,25 @@ extern int alpha_memory_latency;
On Alpha the value is found in $0 for integer functions and
$f0 for floating-point functions. */
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
gen_rtx_REG (((INTEGRAL_TYPE_P (VALTYPE) \
- && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
- || POINTER_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) == REAL_TYPE \
|| TREE_CODE (VALTYPE) == COMPLEX_TYPE)) \
- ? 32 : 0))
+ ? 32 : 0))
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
-#define LIBCALL_VALUE(MODE) \
+#define LIBCALL_VALUE(MODE) \
gen_rtx_REG (MODE, \
- (TARGET_FPREGS \
- && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ (TARGET_FPREGS \
+ && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
- ? 32 : 0))
+ ? 32 : 0))
/* The definition of this macro implies that there are cases where
a scalar value cannot be returned in registers.
@@ -1037,6 +1027,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
@@ -1073,9 +1065,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.
@@ -1104,13 +1096,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.
@@ -1155,59 +1150,61 @@ 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)); \
+ set_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)); \
+ set_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_branch ();
-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;
-
-/* Define the information needed to modify the epilogue for EH. */
+struct alpha_compare
+{
+ struct rtx_def *op0, *op1;
+ int fp_p;
+};
-extern struct rtx_def *alpha_eh_epilogue_sp_ofs;
+extern struct alpha_compare alpha_compare;
/* 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. */
@@ -1217,19 +1214,12 @@ extern void alpha_need_linkage ();
#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
alpha_start_function(FILE,NAME,DECL);
-extern void alpha_start_function ();
/* This macro closes up a function definition for the assembler. */
#define ASM_DECLARE_FUNCTION_SIZE(FILE,NAME,DECL) \
alpha_end_function(FILE,NAME,DECL)
-extern void alpha_end_function ();
-/* This macro notes the end of the prologue. */
-
-#define FUNCTION_END_PROLOGUE(FILE) output_end_prologue (FILE)
-extern void output_end_prologue ();
-
/* Output any profiling code before the prologue. */
#define PROFILE_BEFORE_PROLOGUE 1
@@ -1242,7 +1232,7 @@ extern void output_end_prologue ();
/* Output assembler code to FILE to initialize this source file's
basic block profiling info, if that has not already been done.
- This assumes that __bb_init_func doesn't garble a1-a5. */
+ This assumes that __bb_init_func doesn't garble a1-a5. */
#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \
do { \
@@ -1282,6 +1272,10 @@ extern void output_end_prologue ();
No definition is equivalent to always zero. */
#define EXIT_IGNORE_STACK 1
+
+/* Define registers used by the epilogue and return instruction. */
+
+#define EPILOGUE_USES(REGNO) ((REGNO) == 26)
/* Output assembler code for a block containing the constant parts
of a trampoline, leaving space for the variable parts.
@@ -1289,8 +1283,7 @@ extern void output_end_prologue ();
The trampoline should set the static chain pointer to value placed
into the trampoline and should branch to the specified routine.
Note that $27 has been set to the address of the trampoline, so we can
- use it for addressability of the two data items. Trampolines are always
- aligned to FUNCTION_BOUNDARY, which is 64 bits. */
+ use it for addressability of the two data items. */
#define TRAMPOLINE_TEMPLATE(FILE) \
do { \
@@ -1310,13 +1303,16 @@ do { \
#define TRAMPOLINE_SIZE 32
+/* The alignment of a trampoline, in bits. */
+
+#define TRAMPOLINE_ALIGNMENT 64
+
/* 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. */
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 16, 24, 8)
-extern void alpha_initialize_trampoline ();
/* A C expression whose value is RTL representing the value of the return
address for the frame COUNT steps up from the current frame.
@@ -1324,16 +1320,17 @@ extern void alpha_initialize_trampoline ();
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 ();
-/* Before the prologue, RA lives in $26. */
+/* Before the prologue, RA lives in $26. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 26)
-
-/* 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 ();
+#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))
/* Addressing modes, and classification of registers for them. */
@@ -1387,220 +1384,77 @@ extern void alpha_init_expanders ();
After reload, it makes no difference, since pseudo regs have
been eliminated by then. */
-#ifndef REG_OK_STRICT
-
/* 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) \
+#define NONSTRICT_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) \
+ before reload, we will require additional instructions. */
+#define NONSTRICT_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
+#define STRICT_REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+#ifdef REG_OK_STRICT
+#define REG_OK_FOR_BASE_P(X) STRICT_REG_OK_FOR_BASE_P (X)
+#else
+#define REG_OK_FOR_BASE_P(X) NONSTRICT_REG_OK_FOR_BASE_P (X)
#endif
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address.
-
- For Alpha, we have either a constant address or the sum of a register
- and a constant address, or just a register. For DImode, any of those
- forms can be surrounded with an AND that clear the low-order three bits;
- this is an "unaligned" access.
-
- First define the basic valid address. */
-
-#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; \
- } \
- } \
-}
-
-/* Now accept the simple address, or, for DImode only, an AND of a simple
- address that turns off the low three bits. */
+/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a
+ valid memory address for an instruction. */
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ GO_IF_LEGITIMATE_SIMPLE_ADDRESS (MODE, X, ADDR); \
- if ((MODE) == DImode \
- && GET_CODE (X) == AND \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && INTVAL (XEXP (X, 1)) == -8) \
- GO_IF_LEGITIMATE_SIMPLE_ADDRESS (MODE, XEXP (X, 0), ADDR); \
-}
+#ifdef REG_OK_STRICT
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
+do { \
+ if (alpha_legitimate_address_p (MODE, X, 1)) \
+ goto WIN; \
+} while (0)
+#else
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
+do { \
+ if (alpha_legitimate_address_p (MODE, X, 0)) \
+ goto WIN; \
+} while (0)
+#endif
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address.
- This macro is used in only one place: `memory_address' in explow.c.
-
- OLDX is the address as it was before break_out_memory_refs was called.
- In some cases it is useful to look at this to decide what needs to be done.
-
- MODE and WIN are passed so that this macro can use
- GO_IF_LEGITIMATE_ADDRESS.
-
- It is always safe for this macro to do nothing. It exists to recognize
- opportunities to optimize the output.
-
- For the Alpha, there are three cases we handle:
-
- (1) If the address is (plus reg const_int) and the CONST_INT is not a
- valid offset, compute the high part of the constant and add it to the
- register. Then our address is (plus temp low-part-const).
- (2) If the address is (const (plus FOO const_int)), find the low-order
- part of the CONST_INT. Then load FOO plus any high-order part of the
- CONST_INT into a register. Our address is (plus reg low-part-const).
- This is done to reduce the number of GOT entries.
- (3) If we have a (plus reg const), emit the load as in (2), then add
- the two registers, and finally generate (plus reg low-part-const) as
- our address. */
+ This macro is used in only one place: `memory_address' in explow.c. */
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && ! CONSTANT_ADDRESS_P (XEXP (X, 1))) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
- HOST_WIDE_INT lowpart = (val & 0xffff) - 2 * (val & 0x8000); \
- HOST_WIDE_INT highpart = val - lowpart; \
- rtx high = GEN_INT (highpart); \
- rtx temp = expand_binop (Pmode, add_optab, XEXP (x, 0), \
- high, NULL_RTX, 1, OPTAB_LIB_WIDEN); \
- \
- (X) = plus_constant (temp, lowpart); \
- goto WIN; \
- } \
- else if (GET_CODE (X) == CONST \
- && GET_CODE (XEXP (X, 0)) == PLUS \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (XEXP (X, 0), 1)); \
- HOST_WIDE_INT lowpart = (val & 0xffff) - 2 * (val & 0x8000); \
- HOST_WIDE_INT highpart = val - lowpart; \
- rtx high = XEXP (XEXP (X, 0), 0); \
- \
- if (highpart) \
- high = plus_constant (high, highpart); \
- \
- (X) = plus_constant (force_reg (Pmode, high), lowpart); \
- goto WIN; \
- } \
- else if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
- && 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) \
+do { \
+ rtx new_x = alpha_legitimize_address (X, NULL_RTX, MODE); \
+ if (new_x) \
{ \
- HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (X, 1), 0), 1)); \
- HOST_WIDE_INT lowpart = (val & 0xffff) - 2 * (val & 0x8000); \
- HOST_WIDE_INT highpart = val - lowpart; \
- rtx high = XEXP (XEXP (XEXP (X, 1), 0), 0); \
- \
- if (highpart) \
- high = plus_constant (high, highpart); \
- \
- high = expand_binop (Pmode, add_optab, XEXP (X, 0), \
- force_reg (Pmode, high), \
- high, 1, OPTAB_LIB_WIDEN); \
- (X) = plus_constant (high, lowpart); \
+ X = new_x; \
goto WIN; \
} \
-}
+} while (0)
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
- macro is used in only one place: `find_reloads_address' in reload.c.
-
- For the Alpha, we wish to handle large displacements off a base
- register by splitting the addend across an ldah and the mem insn.
- This cuts number of extra insns needed from 3 to 1. */
+ macro is used in only one place: `find_reloads_address' in reload.c. */
-#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_PTR, \
- 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 \
- && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE) \
- && GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
- HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; \
- HOST_WIDE_INT high \
- = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000; \
- \
- /* Check for 32-bit overflow. */ \
- if (high + low != val) \
- break; \
- \
- /* Reload the high part into a base reg; leave the low part \
- in the mem directly. */ \
- \
- X = gen_rtx_PLUS (GET_MODE (X), \
- gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0), \
- GEN_INT (high)), \
- GEN_INT (low)); \
- \
- push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR, \
- BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
- OPNUM, TYPE); \
- goto WIN; \
- } \
+#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_L,WIN) \
+do { \
+ rtx new_x = alpha_legitimize_reload_address (X, MODE, OPNUM, TYPE, IND_L); \
+ if (new_x) \
+ { \
+ X = new_x; \
+ goto WIN; \
+ } \
} while (0)
/* Go to LABEL if ADDR (a legitimate address expression)
@@ -1616,7 +1470,7 @@ do { \
#define ADDRESS_COST(X) 0
-/* Machine-dependent reorg pass. */
+/* Machine-dependent reorg pass. */
#define MACHINE_DEPENDENT_REORG(X) alpha_reorg(X)
/* Specify the machine mode that this machine uses
@@ -1633,12 +1487,6 @@ do { \
but we should try to find some better way sometime. */
#define CASE_VECTOR_PC_RELATIVE 1
-/* Specify the tree operation to be used to convert reals to integers. */
-#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
-
-/* This is the kind of divide that is easiest to do in the general case. */
-#define EASY_DIV_EXPR TRUNC_DIV_EXPR
-
/* Define this as 1 if `char' should by default be signed; else as 0. */
#define DEFAULT_SIGNED_CHAR 1
@@ -1659,7 +1507,7 @@ do { \
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. */
+ with, several single byte accesses are better. */
#define MOVE_RATIO (TARGET_BWX ? 7 : 2)
@@ -1700,7 +1548,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. */
@@ -1727,7 +1576,7 @@ do { \
between pointers and any other objects of this machine mode. */
#define Pmode DImode
-/* Mode of a function address in a call instruction (for indexing purposes). */
+/* Mode of a function address in a call instruction (for indexing purposes). */
#define FUNCTION_MODE Pmode
@@ -1744,22 +1593,9 @@ do { \
#define NO_FUNCTION_CSE
/* Define this to be nonzero if shift instructions ignore all but the low-order
- few bits. */
+ 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,
@@ -1843,7 +1679,7 @@ do { \
if (GET_CODE (XEXP (X, 1)) == CONST_INT \
&& INTVAL (XEXP (X, 1)) <= 3) \
break; \
- /* ... fall through ... */ \
+ /* ... fall through ... */ \
case ASHIFTRT: case LSHIFTRT: \
switch (alpha_cpu) \
{ \
@@ -1903,7 +1739,7 @@ do { \
case NEG: case ABS: \
if (! FLOAT_MODE_P (GET_MODE (X))) \
break; \
- /* ... fall through ... */ \
+ /* ... fall through ... */ \
case FLOAT: case UNSIGNED_FLOAT: case FIX: case UNSIGNED_FIX: \
case FLOAT_EXTEND: case FLOAT_TRUNCATE: \
switch (alpha_cpu) \
@@ -1918,34 +1754,23 @@ do { \
/* Control the assembler format that we output. */
-/* We don't emit these labels, so as to avoid getting linker errors about
- missing exception handling info. If we emit a gcc_compiled. label into
- text, and the file has no code, then the DEC assembler gives us a zero
- sized text section with no associated exception handling info. The
- DEC linker sees this text section, and gives a warning saying that
- the exception handling info is missing. */
-#define ASM_IDENTIFY_GCC(x)
-#define ASM_IDENTIFY_LANGUAGE(x)
-
/* Output to assembler file text saying following lines
may contain character constants, extra white space, comments, etc. */
-
-#define ASM_APP_ON ""
+#define ASM_APP_ON (TARGET_EXPLICIT_RELOCS ? "\t.set\tmacro\n" : "")
/* Output to assembler file text saying following lines
no longer contain unusual constructs. */
+#define ASM_APP_OFF (TARGET_EXPLICIT_RELOCS ? "\t.set\tnomacro\n" : "")
-#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.
@@ -1968,7 +1793,7 @@ literal_section () \
if (firsttime) \
{ \
firsttime = 0; \
- ASM_OUTPUT_DOUBLE_INT (asm_out_file, const0_rtx); \
+ assemble_aligned_integer (8, const0_rtx); \
} \
\
in_section = readonly_data; \
@@ -1977,13 +1802,29 @@ literal_section () \
#define READONLY_DATA_SECTION literal_section
-/* If we are referencing a function that is static, make the SYMBOL_REF
- special. We use this to see indicate we can branch to this function
- without setting PV or restoring GP. */
+/* Define this macro if references to a symbol must be treated differently
+ depending on something about the variable or function named by the symbol
+ (such as what section it is in). */
-#define ENCODE_SECTION_INFO(DECL) \
- if (TREE_CODE (DECL) == FUNCTION_DECL && ! TREE_PUBLIC (DECL)) \
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;
+#define ENCODE_SECTION_INFO(DECL) alpha_encode_section_info (DECL)
+
+/* If a variable is weakened, made one only or moved into a different
+ section, it may be necessary to redo the section info to move the
+ variable out of sdata. */
+
+#define REDO_SECTION_INFO_P(DECL) \
+ ((TREE_CODE (DECL) == VAR_DECL) \
+ && (DECL_ONE_ONLY (DECL) || DECL_WEAK (DECL) || DECL_COMMON (DECL) \
+ || DECL_SECTION_NAME (DECL) != 0))
+
+#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
+do { \
+ (VAR) = (SYMBOL_NAME); \
+ if ((VAR)[0] == '@') \
+ (VAR) += 2; \
+ if ((VAR)[0] == '*') \
+ (VAR)++; \
+} while (0)
/* How to refer to registers in assembler output.
This sequence is indexed by compiler's hard-register-number (see above). */
@@ -1998,9 +1839,19 @@ literal_section () \
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",\
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "FP"}
-/* How to renumber registers for dbx and gdb. */
+/* Strip name encoding when emitting labels. */
-#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
+do { \
+ const char *name_ = NAME; \
+ if (*name_ == '@') \
+ name_ += 2; \
+ if (*name_ == '*') \
+ name_++; \
+ else \
+ fputs (user_label_prefix, STREAM); \
+ fputs (name_, STREAM); \
+} while (0)
/* This is how to output the definition of a user-level label named NAME,
such as the label on a static function or variable NAME. */
@@ -2014,7 +1865,7 @@ literal_section () \
#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
do { fputs ("\t.globl ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
-/* The prefix to add to user-visible assembler symbols. */
+/* The prefix to add to user-visible assembler symbols. */
#define USER_LABEL_PREFIX ""
@@ -2026,7 +1877,7 @@ literal_section () \
/* This is how to output a label for a jump table. Arguments are the same as
for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
- passed. */
+ passed. */
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
@@ -2044,74 +1895,18 @@ literal_section () \
#define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \
((OVERFLOW) = check_float_value (MODE, &D, OVERFLOW))
-/* 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); \
- } \
- }
-
-/* This is how to output an assembler line defining a `float' constant. */
-
-#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
- do { \
- long t; \
- REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
- fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \
-} while (0)
-
-/* This is how to output an assembler line defining an `int' constant. */
-
-#define ASM_OUTPUT_INT(FILE,VALUE) \
-( fprintf (FILE, "\t.long "), \
- output_addr_const (FILE, (VALUE)), \
- fprintf (FILE, "\n"))
-
-/* This is how to output an assembler line defining a `long' constant. */
-
-#define ASM_OUTPUT_DOUBLE_INT(FILE,VALUE) \
-( fprintf (FILE, "\t.quad "), \
- output_addr_const (FILE, (VALUE)), \
- fprintf (FILE, "\n"))
-
-/* Likewise for `char' and `short' constants. */
-
-#define ASM_OUTPUT_SHORT(FILE,VALUE) \
- fprintf (FILE, "\t.word %d\n", \
- (int)(GET_CODE (VALUE) == CONST_INT \
- ? INTVAL (VALUE) & 0xffff : (abort (), 0)))
-
-#define ASM_OUTPUT_CHAR(FILE,VALUE) \
- fprintf (FILE, "\t.byte %d\n", \
- (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
than 50 characters since the assembler doesn't support very long lines. */
#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 \""); \
@@ -2132,11 +1927,10 @@ literal_section () \
fprintf (asm_out_file, "\\%o", c); \
/* After an octal-escape, if a digit follows, \
terminate one string constant and start another. \
- The Vax assembler fails to stop reading the escape \
+ The VAX assembler fails to stop reading the escape \
after three digits, so this is the only way we \
can get it to parse the data properly. */ \
- if (i < thissize - 1 \
- && p[i + 1] >= '0' && p[i + 1] <= '9') \
+ if (i < thissize - 1 && ISDIGIT (p[i + 1])) \
_size_so_far = 0, fprintf (asm_out_file, "\"\n\t.ascii \""); \
} \
} \
@@ -2145,11 +1939,6 @@ literal_section () \
} \
while (0)
-/* To get unaligned data, we have to turn off auto alignment. */
-#define UNALIGNED_SHORT_ASM_OP ".align 0\n\t.word"
-#define UNALIGNED_INT_ASM_OP ".align 0\n\t.long"
-#define UNALIGNED_DOUBLE_INT_ASM_OP ".align 0\n\t.quad"
-
/* This is how to output an insn to push a register on the stack.
It need not be very fast code. */
@@ -2166,11 +1955,6 @@ literal_section () \
(REGNO) > 32 ? "t" : "q", (REGNO) > 32 ? "f" : "", \
(REGNO) & 31);
-/* 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", (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.) */
@@ -2179,7 +1963,7 @@ literal_section () \
/* This is how to output an element of a case-vector that is relative. */
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- fprintf (FILE, "\t.%s $L%d\n", TARGET_WINDOWS_NT ? "long" : "gprel32", \
+ fprintf (FILE, "\t.%s $L%d\n", TARGET_ABI_WINDOWS_NT ? "long" : "gprel32", \
(VALUE))
/* This is how to output an assembler line
@@ -2218,52 +2002,8 @@ literal_section () \
#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-
-/* Define the parentheses used to group arithmetic operations
- in assembler code. */
-
-#define ASM_OPEN_PAREN "("
-#define ASM_CLOSE_PAREN ")"
-
-/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
- Used for C++ multiple inheritance. */
-
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-do { \
- char *fn_name = XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0); \
- int reg; \
- \
- /* Mark end of prologue. */ \
- output_end_prologue (FILE); \
- \
- /* Rely on the assembler to macro expand a large delta. */ \
- 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))) \
- { \
- fprintf (FILE, "\tbr $31,$"); \
- assemble_name (FILE, fn_name); \
- fprintf (FILE, "..ng\n"); \
- } \
- else \
- { \
- fprintf (FILE, "\tjmp $31,"); \
- assemble_name (FILE, fn_name); \
- fputc ('\n', FILE); \
- } \
-} while (0)
-/* Define results of standard character escape sequences. */
-#define TARGET_BELL 007
-#define TARGET_BS 010
-#define TARGET_TAB 011
-#define TARGET_NEWLINE 012
-#define TARGET_VT 013
-#define TARGET_FF 014
-#define TARGET_CR 015
-
/* Print operand X (an rtx) in assembler syntax to file FILE.
CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
For `%' followed by punctuation, CODE is the punctuation and X is null. */
@@ -2271,30 +2011,12 @@ 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).
-
- & Generates fp-rounding mode suffix: nothing for normal, 'c' for
- chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
- mode. alpha_fprm controls which suffix is generated.
-
- ' 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.
+ not be alphabetic.
- ) 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).
+ ~ Generates the name of the current function.
- + Generates trap-mode suffix for instructions that accept the
- sui suffix (cvtqt and cvtqs).
+ / Generates the instruction suffix. The TRAP_SUFFIX and ROUND_SUFFIX
+ attributes are examined to determine what is appropriate.
, Generates single precision suffix for floating point
instructions (s for IEEE, f for VAX)
@@ -2303,9 +2025,9 @@ do { \
instructions (t for IEEE, g for VAX)
*/
-#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
- ((CODE) == '&' || (CODE) == '`' || (CODE) == '\'' || (CODE) == '(' \
- || (CODE) == ')' || (CODE) == '+' || (CODE) == ',' || (CODE) == '-')
+#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
+ ((CODE) == '/' || (CODE) == ',' || (CODE) == '-' || (CODE) == '~' \
+ || (CODE) == '#' || (CODE) == '*')
/* Print a memory address as an operand to reference that memory location. */
@@ -2330,23 +2052,46 @@ do { \
{"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}}, \
+ {"direct_call_operand", {SYMBOL_REF}}, \
+ {"local_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
+ {"small_symbolic_operand", {SYMBOL_REF, CONST}}, \
+ {"global_symbolic_operand", {SYMBOL_REF, CONST}}, \
{"call_operand", {REG, SYMBOL_REF}}, \
{"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
- SYMBOL_REF, CONST, LABEL_REF}}, \
+ SYMBOL_REF, CONST, LABEL_REF, HIGH}}, \
{"some_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
- SYMBOL_REF, CONST, LABEL_REF}}, \
+ SYMBOL_REF, CONST, LABEL_REF, HIGH}}, \
+ {"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}},
+ {"reg_no_subreg_operand", {REG}}, \
+ {"addition_operation", {PLUS}}, \
+ {"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
+ {"some_small_symbolic_mem_operand", {SET, PARALLEL}},
+
+/* 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)
/* Tell collect that the object format is ECOFF. */
#define OBJECT_FORMAT_COFF
@@ -2388,11 +2133,9 @@ 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. We must underestimate this
number, because the real length runs past this up to the next
@@ -2410,9 +2153,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
@@ -2478,7 +2221,7 @@ do { \
mips-tdump.c to print them out.
These must match the corresponding definitions in gdb/mipsread.c.
- Unfortunately, gcc and gdb do not currently share any directories. */
+ Unfortunately, gcc and gdb do not currently share any directories. */
#define CODE_MASK 0x8F300
#define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
@@ -2494,57 +2237,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
-/* Prototypes for alpha.c functions used in the md file & elsewhere. */
-extern struct rtx_def *get_unaligned_address ();
-extern void alpha_write_verstamp ();
-extern void alpha_reorg ();
-extern int check_float_value ();
-extern int direct_return ();
-extern int const48_operand ();
-extern int add_operand ();
-extern int and_operand ();
-extern int unaligned_memory_operand ();
-extern int zap_mask ();
-extern int current_file_function_operand ();
-extern int alpha_sa_size ();
-extern int alpha_adjust_cost ();
-extern void print_operand ();
-extern void print_operand_address ();
-extern int reg_or_0_operand ();
-extern int reg_or_8bit_operand ();
-extern int mul8_operand ();
-extern int reg_or_6bit_operand ();
-extern int alpha_comparison_operator ();
-extern int alpha_swapped_comparison_operator ();
-extern int sext_add_operand ();
-extern int cint8_operand ();
-extern int mode_mask_operand ();
-extern int or_operand ();
-extern int mode_width_operand ();
-extern int reg_or_fp0_operand ();
-extern int signed_comparison_operator ();
-extern int fp0_operand ();
-extern int some_operand ();
-extern int input_operand ();
-extern int divmod_operator ();
-extern int call_operand ();
-extern int reg_or_cint_operand ();
-extern int hard_fp_register_operand ();
-extern int reg_not_elim_operand ();
-extern void alpha_set_memflags ();
-extern int aligned_memory_operand ();
-extern void get_aligned_mem ();
-extern void alpha_expand_unaligned_load ();
-extern void alpha_expand_unaligned_store ();
-extern int alpha_expand_block_move ();
-extern int alpha_expand_block_clear ();
-extern void alpha_expand_prologue ();
-extern void alpha_expand_epilogue ();
+/* Generate calls to memcpy, etc., not bcopy, etc. */
+#define TARGET_MEM_FUNCTIONS 1
diff --git a/contrib/gcc/config/alpha/alpha.md b/contrib/gcc/config/alpha/alpha.md
index 6d075e9..b987de8 100644
--- a/contrib/gcc/config/alpha/alpha.md
+++ b/contrib/gcc/config/alpha/alpha.md
@@ -1,19 +1,20 @@
;; Machine description for DEC Alpha for GNU C compiler
-;; Copyright (C) 1992, 93-98, 1999 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.
-
+;;
;; GNU CC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
-
+;;
;; GNU CC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
-
+;;
;; You should have received a copy of the GNU General Public License
;; along with GNU CC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
@@ -22,25 +23,46 @@
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
;; Uses of UNSPEC in this file:
-;;
-;; 0 arg_home
-;; 1 cttz
-;; 2 insxh
-;; 3 mskxh
-;; 4 cvtlq
-;; 5 cvtql
-;; 6 nt_lda
-;;
+
+(define_constants
+ [(UNSPEC_ARG_HOME 0)
+ (UNSPEC_CTTZ 1)
+ (UNSPEC_INSXH 2)
+ (UNSPEC_MSKXH 3)
+ (UNSPEC_CVTQL 4)
+ (UNSPEC_NT_LDA 5)
+ (UNSPEC_UMK_LAUM 6)
+ (UNSPEC_UMK_LALM 7)
+ (UNSPEC_UMK_LAL 8)
+ (UNSPEC_UMK_LOAD_CIW 9)
+ (UNSPEC_LDGP2 10)
+ (UNSPEC_LITERAL 11)
+ (UNSPEC_LITUSE 12)
+ (UNSPEC_SIBCALL 13)
+ ])
+
;; UNSPEC_VOLATILE:
+
+(define_constants
+ [(UNSPECV_IMB 0)
+ (UNSPECV_BLOCKAGE 1)
+ (UNSPECV_SETJMPR 2) ; builtin_setjmp_receiver
+ (UNSPECV_LONGJMP 3) ; builtin_longjmp
+ (UNSPECV_TRAPB 4)
+ (UNSPECV_PSPL 5) ; prologue_stack_probe_loop
+ (UNSPECV_REALIGN 6)
+ (UNSPECV_EHR 7) ; exception_receiver
+ (UNSPECV_MCOUNT 8)
+ (UNSPECV_FORCE_MOV 9)
+ (UNSPECV_LDGP1 10)
+ (UNSPECV_PLDGP2 11) ; prologue ldgp
+ ])
+
+;; Where necessary, the suffixes _le and _be are used to distinguish between
+;; little-endian and big-endian patterns.
;;
-;; 0 imb
-;; 1 blockage
-;; 2 builtin_setjmp_receiver
-;; 3 builtin_longjmp
-;; 4 trapb
-;; 5 prologue_stack_probe_loop
-;; 6 realign
-;; 7 exception_receiver
+;; Note that the Unicos/Mk assembler does not support the following
+;; opcodes: mov, fmov, nop, fnop, unop.
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in alpha.h.
@@ -54,7 +76,8 @@
;; separately.
(define_attr "type"
- "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
+ "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,\
+fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(const_string "iadd"))
;; Describe a user's asm statement.
@@ -62,19 +85,42 @@
[(set_attr "type" "multi")])
;; Define the operand size an insn operates on. Used primarily by mul
-;; and div operations that have size dependant timings.
+;; and div operations that have size dependent timings.
-(define_attr "opsize" "si,di,udi" (const_string "di"))
+(define_attr "opsize" "si,di,udi"
+ (const_string "di"))
-;; The TRAP_TYPE attribute marks instructions that may generate traps
+;; The TRAP attribute marks instructions that may generate traps
;; (which are imprecise and may need a trapb if software completion
;; is desired).
-(define_attr "trap" "no,yes" (const_string "no"))
+(define_attr "trap" "no,yes"
+ (const_string "no"))
+
+;; The ROUND_SUFFIX attribute marks which instructions require a
+;; rounding-mode suffix. The value NONE indicates no suffix,
+;; the value NORMAL indicates a suffix controled by alpha_fprm.
+
+(define_attr "round_suffix" "none,normal,c"
+ (const_string "none"))
+
+;; The TRAP_SUFFIX attribute marks instructions requiring a trap-mode suffix:
+;; NONE no suffix
+;; SU accepts only /su (cmpt et al)
+;; SUI accepts only /sui (cvtqt and cvtqs)
+;; V_SV accepts /v and /sv (cvtql only)
+;; V_SV_SVI accepts /v, /sv and /svi (cvttq only)
+;; U_SU_SUI accepts /u, /su and /sui (most fp instructions)
+;;
+;; The actual suffix emitted is controled by alpha_fptm.
+
+(define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui"
+ (const_string "none"))
;; The length of an instruction sequence in bytes.
-(define_attr "length" "" (const_int 4))
+(define_attr "length" ""
+ (const_int 4))
;; On EV4 there are two classes of resources to consider: resources needed
;; to issue, and resources needed to execute. IBUS[01] are in the first
@@ -220,14 +266,14 @@
(and (eq_attr "cpu" "ev5")
(eq_attr "type" "fadd,fcmov,fmul,fcpys,fbr,fdiv"))
4 1)
-
+
(define_function_unit "ev5_fm" 1 0
(and (eq_attr "cpu" "ev5")
(eq_attr "type" "fmul"))
4 1)
; Add and cmov as you would expect; fbr never produces a result;
-; fdiv issues through fa to the divider,
+; fdiv issues through fa to the divider,
(define_function_unit "ev5_fa" 1 0
(and (eq_attr "cpu" "ev5")
(eq_attr "type" "fadd,fcmov,fbr,fdiv"))
@@ -239,20 +285,20 @@
(and (eq_attr "cpu" "ev5")
(and (eq_attr "type" "fdiv")
(eq_attr "opsize" "si")))
- 15 15) ; 15 to 31 data dependant
+ 15 15) ; 15 to 31 data dependent
(define_function_unit "fdiv" 1 0
(and (eq_attr "cpu" "ev5")
(and (eq_attr "type" "fdiv")
(eq_attr "opsize" "di")))
- 22 22) ; 22 to 60 data dependant
+ 22 22) ; 22 to 60 data dependent
;; EV6 scheduling. EV6 can issue 4 insns per clock.
;;
;; EV6 has two symmetric pairs ("clusters") of two asymetric integer units
;; ("upper" and "lower"), yielding pipe names U0, U1, L0, L1.
-;; Conditional moves decompose into two independant primitives, each
+;; Conditional moves decompose into two independent primitives, each
;; taking one cycle. Since ev6 is out-of-order, we can't see anything
;; but two cycles.
(define_function_unit "ev6_ebox" 4 0
@@ -337,7 +383,7 @@
;; For the FPU we are very similar to EV5, except there's no insn that
;; can issue to fm & fa, so we get to leave that out.
-
+
(define_function_unit "ev6_fm" 1 0
(and (eq_attr "cpu" "ev6")
(eq_attr "type" "fmul"))
@@ -388,24 +434,44 @@
;; sign-extend.
;; Handle 32-64 bit extension from memory to a floating point register
-;; specially, since this ocurrs frequently in int->double conversions.
-;; This is done with a define_split after reload converting the plain
-;; sign-extension into a load+unspec, which of course results in lds+cvtlq.
+;; specially, since this occurs frequently in int->double conversions.
;;
;; Note that while we must retain the =f case in the insn for reload's
;; benefit, it should be eliminated after reload, so we should never emit
;; code for that case. But we don't reject the possibility.
-(define_insn "extendsidi2"
- [(set (match_operand:DI 0 "register_operand" "=r,r,?f")
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
+(define_expand "extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
""
+ "")
+
+(define_insn "*extendsidi2_nofix"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,*f,?*f")
+ (sign_extend:DI
+ (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,m")))]
+ "! TARGET_FIX"
"@
addl %1,$31,%0
ldl %0,%1
+ cvtlq %1,%0
lds %0,%1\;cvtlq %0,%0"
- [(set_attr "type" "iadd,ild,fld")
- (set_attr "length" "*,*,8")])
+ [(set_attr "type" "iadd,ild,fadd,fld")
+ (set_attr "length" "*,*,*,8")])
+
+(define_insn "*extendsidi2_fix"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r,?*f,?*f")
+ (sign_extend:DI
+ (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))]
+ "TARGET_FIX"
+ "@
+ addl %1,$31,%0
+ ldl %0,%1
+ ftois %1,%0
+ cvtlq %1,%0
+ lds %0,%1\;cvtlq %0,%0"
+ [(set_attr "type" "iadd,ild,ftoi,fadd,fld")
+ (set_attr "length" "*,*,*,*,8")])
;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
(define_split
@@ -413,15 +479,44 @@
(sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
"reload_completed"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (unspec:DI [(match_dup 2)] 4))]
+ (set (match_dup 0) (sign_extend:DI (match_dup 2)))]
"operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=f")
- (unspec:DI [(match_operand:SI 1 "register_operand" "f")] 4))]
- ""
- "cvtlq %1,%0"
- [(set_attr "type" "fadd")])
+;; Optimize sign-extension of SImode loads. This shows up in the wake of
+;; reload when converting fp->int.
+
+(define_peephole2
+ [(set (match_operand:SI 0 "hard_int_register_operand" "")
+ (match_operand:SI 1 "memory_operand" ""))
+ (set (match_operand:DI 2 "hard_int_register_operand" "")
+ (sign_extend:DI (match_dup 0)))]
+ "true_regnum (operands[0]) == true_regnum (operands[2])
+ || peep2_reg_dead_p (2, operands[0])"
+ [(set (match_dup 2)
+ (sign_extend:DI (match_dup 1)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "hard_int_register_operand" "")
+ (match_operand:SI 1 "hard_fp_register_operand" ""))
+ (set (match_operand:DI 2 "hard_int_register_operand" "")
+ (sign_extend:DI (match_dup 0)))]
+ "TARGET_FIX
+ && (true_regnum (operands[0]) == true_regnum (operands[2])
+ || peep2_reg_dead_p (2, operands[0]))"
+ [(set (match_dup 2)
+ (sign_extend:DI (match_dup 1)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "hard_fp_register_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "hard_fp_register_operand" "")))
+ (set (match_operand:DI 2 "hard_int_register_operand" "")
+ (match_dup 0))]
+ "TARGET_FIX && peep2_reg_dead_p (2, operands[0])"
+ [(set (match_dup 2)
+ (sign_extend:DI (match_dup 1)))]
+ "")
;; Do addsi3 the way expand_binop would do if we didn't have one. This
;; generates better code. We have the anonymous addsi3 pattern below in
@@ -431,7 +526,6 @@
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "add_operand" "")))]
""
- "
{
if (optimize)
{
@@ -448,9 +542,9 @@
emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
DONE;
}
-}")
+})
-(define_insn ""
+(define_insn "*addsi_internal"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
(match_operand:SI 2 "add_operand" "rI,O,K,L")))]
@@ -468,7 +562,6 @@
"! add_operand (operands[2], SImode)"
[(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
- "
{
HOST_WIDE_INT val = INTVAL (operands[2]);
HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
@@ -476,9 +569,9 @@
operands[3] = GEN_INT (rest);
operands[4] = GEN_INT (low);
-}")
+})
-(define_insn ""
+(define_insn "*addsi_se"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(sign_extend:DI
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
@@ -491,7 +584,7 @@
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(sign_extend:DI
- (plus:SI (match_operand:SI 1 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "reg_not_elim_operand" "")
(match_operand:SI 2 "const_int_operand" ""))))
(clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
"! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
@@ -500,7 +593,6 @@
(set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
(match_dup 5))
(match_dup 1))))]
- "
{
HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
int mult = 4;
@@ -510,7 +602,7 @@
operands[4] = GEN_INT (val);
operands[5] = GEN_INT (mult);
-}")
+})
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -523,57 +615,96 @@
""
[(set (match_dup 5) (match_dup 6))
(set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
- "
{
operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
operands[2], operands[3]);
operands[7] = gen_lowpart (SImode, operands[5]);
-}")
+})
-(define_insn "adddi3"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
- (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
- (match_operand:DI 2 "add_operand" "rI,O,K,L")))]
+(define_insn "addvsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
+ (match_operand:SI 2 "sext_add_operand" "rI,O")))
+ (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
+ (sign_extend:DI (match_dup 2)))
+ (sign_extend:DI (plus:SI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
""
- "*
-{
- const char * const pattern[4] = {
- \"addq %r1,%2,%0\",
- \"subq %r1,%n2,%0\",
- \"lda %0,%2(%r1)\",
- \"ldah %0,%h2(%r1)\"
- };
+ "@
+ addlv %r1,%2,%0
+ sublv %r1,%n2,%0")
- /* The NT stack unwind code can't handle a subq to adjust the stack
- (that's a bug, but not one we can do anything about). As of NT4.0 SP3,
- the exception handling code will loop if a subq is used and an
- exception occurs.
+(define_expand "adddi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "add_operand" "")))]
+ ""
+ "")
- The 19980616 change to emit prologues as RTL also confused some
- versions of GDB, which also interprets prologues. This has been
- fixed as of GDB 4.18, but it does not harm to unconditionally
- use lda here. */
+(define_insn "*adddi_er_high_l"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
+ "TARGET_EXPLICIT_RELOCS"
+ "ldah %0,%2(%1)\t\t!gprelhigh")
- int which = which_alternative;
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (high:DI (match_operand:DI 1 "local_symbolic_operand" "")))]
+ "TARGET_EXPLICIT_RELOCS && reload_completed"
+ [(set (match_dup 0)
+ (plus:DI (match_dup 2) (high:DI (match_dup 1))))]
+ "operands[2] = pic_offset_table_rtx;")
- if (operands[0] == stack_pointer_rtx
- && GET_CODE (operands[2]) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))
- which = 2;
+;; We used to expend quite a lot of effort choosing addq/subq/lda.
+;; With complications like
+;;
+;; The NT stack unwind code can't handle a subq to adjust the stack
+;; (that's a bug, but not one we can do anything about). As of NT4.0 SP3,
+;; the exception handling code will loop if a subq is used and an
+;; exception occurs.
+;;
+;; The 19980616 change to emit prologues as RTL also confused some
+;; versions of GDB, which also interprets prologues. This has been
+;; fixed as of GDB 4.18, but it does not harm to unconditionally
+;; use lda here.
+;;
+;; and the fact that the three insns schedule exactly the same, it's
+;; just not worth the effort.
- return pattern[which];
-}")
+(define_insn "*adddi_internal"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+ (plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
+ (match_operand:DI 2 "add_operand" "r,K,L")))]
+ ""
+ "@
+ addq %1,%2,%0
+ lda %0,%2(%1)
+ ldah %0,%h2(%1)")
;; ??? Allow large constants when basing off the frame pointer or some
;; virtual register that may eliminate to the frame pointer. 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_insn ""
+(define_insn "*adddi_fp_hack"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r")
(match_operand:DI 2 "const_int_operand" "n")))]
- "REG_OK_FP_BASE_P (operands[1])"
+ "NONSTRICT_REG_OK_FP_BASE_P (operands[1])
+ && INTVAL (operands[2]) >= 0
+ /* This is the largest constant an lda+ldah pair can add, minus
+ an upper bound on the displacement between SP and AP during
+ register elimination. See INITIAL_ELIMINATION_OFFSET. */
+ && INTVAL (operands[2])
+ < (0x7fff8000
+ - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
+ - ALPHA_ROUND(current_function_outgoing_args_size)
+ - (ALPHA_ROUND (get_frame_size ()
+ + max_reg_num () * UNITS_PER_WORD
+ + current_function_pretend_args_size)
+ - current_function_pretend_args_size))"
"#")
;; Don't do this if we are adjusting SP since we don't want to do it
@@ -588,17 +719,26 @@
&& operands[1] != arg_pointer_rtx"
[(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
- "
{
HOST_WIDE_INT val = INTVAL (operands[2]);
HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
HOST_WIDE_INT rest = val - low;
- operands[3] = GEN_INT (rest);
operands[4] = GEN_INT (low);
-}")
+ if (CONST_OK_FOR_LETTER_P (rest, 'L'))
+ operands[3] = GEN_INT (rest);
+ else if (! no_new_pseudos)
+ {
+ operands[3] = gen_reg_rtx (DImode);
+ emit_move_insn (operands[3], operands[2]);
+ emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
+ DONE;
+ }
+ else
+ FAIL;
+})
-(define_insn ""
+(define_insn "*saddl"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
(match_operand:SI 2 "const48_operand" "I,I"))
@@ -608,7 +748,7 @@
s%2addl %1,%3,%0
s%2subl %1,%n3,%0")
-(define_insn ""
+(define_insn "*saddl_se"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(sign_extend:DI
(plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
@@ -626,21 +766,20 @@
[(match_operand 2 "" "")
(match_operand 3 "" "")])
(match_operand:SI 4 "const48_operand" ""))
- (match_operand:SI 5 "add_operand" ""))))
+ (match_operand:SI 5 "sext_add_operand" ""))))
(clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
""
[(set (match_dup 6) (match_dup 7))
(set (match_dup 0)
(sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
(match_dup 5))))]
- "
{
operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
operands[2], operands[3]);
operands[8] = gen_lowpart (SImode, operands[6]);
-}")
+})
-(define_insn ""
+(define_insn "*saddq"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
(match_operand:DI 2 "const48_operand" "I,I"))
@@ -650,94 +789,19 @@
s%2addq %1,%3,%0
s%2subq %1,%n3,%0")
-;; These variants of the above insns can occur if the third operand
-;; is the frame pointer. This is a kludge, but there doesn't
-;; seem to be a way around it. Only recognize them while reloading.
-
-(define_insn ""
- [(set (match_operand:DI 0 "some_operand" "=&r")
- (plus:DI (plus:DI (match_operand:DI 1 "some_operand" "r")
- (match_operand:DI 2 "some_operand" "r"))
- (match_operand:DI 3 "some_operand" "rIOKL")))]
- "reload_in_progress"
- "#")
-
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" ""))
- (match_operand:DI 3 "add_operand" "")))]
- "reload_completed"
- [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
- "")
-
-(define_insn ""
- [(set (match_operand:SI 0 "some_operand" "=&r")
- (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "some_operand" "rJ")
- (match_operand:SI 2 "const48_operand" "I"))
- (match_operand:SI 3 "some_operand" "r"))
- (match_operand:SI 4 "some_operand" "rIOKL")))]
- "reload_in_progress"
- "#")
-
-(define_split
- [(set (match_operand:SI 0 "register_operand" "r")
- (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
- (match_operand:SI 2 "const48_operand" ""))
- (match_operand:SI 3 "register_operand" ""))
- (match_operand:SI 4 "add_operand" "rIOKL")))]
- "reload_completed"
- [(set (match_dup 0)
- (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
- (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
- "")
-
-(define_insn ""
- [(set (match_operand:DI 0 "some_operand" "=&r")
- (sign_extend:DI
- (plus:SI (plus:SI
- (mult:SI (match_operand:SI 1 "some_operand" "rJ")
- (match_operand:SI 2 "const48_operand" "I"))
- (match_operand:SI 3 "some_operand" "r"))
- (match_operand:SI 4 "some_operand" "rIOKL"))))]
- "reload_in_progress"
- "#")
-
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI
- (plus:SI (plus:SI
- (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
- (match_operand:SI 2 "const48_operand" ""))
- (match_operand:SI 3 "register_operand" ""))
- (match_operand:SI 4 "add_operand" ""))))]
- "reload_completed"
- [(set (match_dup 5)
- (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
- (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 5) (match_dup 4))))]
- "operands[5] = gen_lowpart (SImode, operands[0]);")
-
-(define_insn ""
- [(set (match_operand:DI 0 "some_operand" "=&r")
- (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "some_operand" "rJ")
- (match_operand:DI 2 "const48_operand" "I"))
- (match_operand:DI 3 "some_operand" "r"))
- (match_operand:DI 4 "some_operand" "rIOKL")))]
- "reload_in_progress"
- "#")
-
-(define_split
- [(set (match_operand:DI 0 "register_operand" "=")
- (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "const48_operand" ""))
- (match_operand:DI 3 "register_operand" ""))
- (match_operand:DI 4 "add_operand" "")))]
- "reload_completed"
- [(set (match_dup 0)
- (plus:DI (mult:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
- (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
- "")
+(define_insn "addvdi3"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
+ (match_operand:DI 2 "sext_add_operand" "rI,O")))
+ (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
+ (sign_extend:TI (match_dup 2)))
+ (sign_extend:TI (plus:DI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
+ ""
+ "@
+ addqv %r1,%2,%0
+ subqv %r1,%n2,%0")
(define_insn "negsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -745,25 +809,42 @@
""
"subl $31,%1,%0")
-(define_insn ""
+(define_insn "*negsi_se"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI (neg:SI
(match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
""
"subl $31,%1,%0")
+(define_insn "negvsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_operand:SI 1 "register_operand" "r")))
+ (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
+ (sign_extend:DI (neg:SI (match_dup 1))))
+ (const_int 0))]
+ ""
+ "sublv $31,%1,%0")
+
(define_insn "negdi2"
[(set (match_operand:DI 0 "register_operand" "=r")
(neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
""
"subq $31,%1,%0")
+(define_insn "negvdi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (neg:DI (match_operand:DI 1 "register_operand" "r")))
+ (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
+ (sign_extend:TI (neg:DI (match_dup 1))))
+ (const_int 0))]
+ ""
+ "subqv $31,%1,%0")
+
(define_expand "subsi3"
[(set (match_operand:SI 0 "register_operand" "")
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_8bit_operand" "")))]
""
- "
{
if (optimize)
{
@@ -780,22 +861,34 @@
emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
DONE;
}
-} ")
+})
-(define_insn ""
+(define_insn "*subsi_internal"
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
""
"subl %r1,%2,%0")
-(define_insn ""
+(define_insn "*subsi_se"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
(match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
""
"subl %r1,%2,%0")
+(define_insn "subvsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
+ (match_operand:SI 2 "reg_or_8bit_operand" "rI")))
+ (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
+ (sign_extend:DI (match_dup 2)))
+ (sign_extend:DI (minus:SI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
+ ""
+ "sublv %r1,%2,%0")
+
(define_insn "subdi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
@@ -803,7 +896,7 @@
""
"subq %r1,%2,%0")
-(define_insn ""
+(define_insn "*ssubl"
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
(match_operand:SI 2 "const48_operand" "I"))
@@ -811,7 +904,7 @@
""
"s%2subl %1,%3,%0")
-(define_insn ""
+(define_insn "*ssubl_se"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI
(minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
@@ -820,7 +913,7 @@
""
"s%2subl %1,%3,%0")
-(define_insn ""
+(define_insn "*ssubq"
[(set (match_operand:DI 0 "register_operand" "=r")
(minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
(match_operand:DI 2 "const48_operand" "I"))
@@ -828,25 +921,53 @@
""
"s%2subq %1,%3,%0")
+(define_insn "subvdi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
+ (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
+ (sign_extend:TI (match_dup 2)))
+ (sign_extend:TI (minus:DI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
+ ""
+ "subqv %r1,%2,%0")
+
+;; The Unicos/Mk assembler doesn't support mull.
+
(define_insn "mulsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
- ""
+ "!TARGET_ABI_UNICOSMK"
"mull %r1,%2,%0"
[(set_attr "type" "imul")
(set_attr "opsize" "si")])
-(define_insn ""
+(define_insn "*mulsi_se"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
(match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
- ""
+ "!TARGET_ABI_UNICOSMK"
"mull %r1,%2,%0"
[(set_attr "type" "imul")
(set_attr "opsize" "si")])
+(define_insn "mulvsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
+ (match_operand:SI 2 "reg_or_8bit_operand" "rI")))
+ (trap_if (ne (mult:DI (sign_extend:DI (match_dup 1))
+ (sign_extend:DI (match_dup 2)))
+ (sign_extend:DI (mult:SI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
+ "!TARGET_ABI_UNICOSMK"
+ "mullv %r1,%2,%0"
+ [(set_attr "type" "imul")
+ (set_attr "opsize" "si")])
+
(define_insn "muldi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
@@ -855,6 +976,19 @@
"mulq %r1,%2,%0"
[(set_attr "type" "imul")])
+(define_insn "mulvdi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
+ (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
+ (trap_if (ne (mult:TI (sign_extend:TI (match_dup 1))
+ (sign_extend:TI (match_dup 2)))
+ (sign_extend:TI (mult:DI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
+ ""
+ "mulqv %r1,%2,%0"
+ [(set_attr "type" "imul")])
+
(define_insn "umuldi3_highpart"
[(set (match_operand:DI 0 "register_operand" "=r")
(truncate:DI
@@ -869,7 +1003,7 @@
[(set_attr "type" "imul")
(set_attr "opsize" "udi")])
-(define_insn ""
+(define_insn "*umuldi3_highpart_const"
[(set (match_operand:DI 0 "register_operand" "=r")
(truncate:DI
(lshiftrt:TI
@@ -881,144 +1015,324 @@
[(set_attr "type" "imul")
(set_attr "opsize" "udi")])
-;; The divide and remainder operations always take their inputs from
-;; r24 and r25, put their output in r27, and clobber r23 and r28.
-
-;; ??? Force sign-extension here because some versions of OSF/1 don't
-;; do the right thing if the inputs are not properly sign-extended.
-;; But Linux, for instance, does not have this problem. Is it worth
-;; the complication here to eliminate the sign extension?
-;; Interix/NT has the same sign-extension problem.
+;; The divide and remainder operations take their inputs from r24 and
+;; r25, put their output in r27, and clobber r23 and r28 on all
+;; systems except Unicos/Mk. On Unicos, the standard library provides
+;; subroutines which use the standard calling convention and work on
+;; DImode operands.
+
+;; ??? Force sign-extension here because some versions of OSF/1 and
+;; Interix/NT don't do the right thing if the inputs are not properly
+;; sign-extended. But Linux, for instance, does not have this
+;; problem. Is it worth the complication here to eliminate the sign
+;; extension?
(define_expand "divsi3"
- [(set (reg:DI 24)
+ [(set (match_dup 3)
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
- (set (reg:DI 25)
+ (set (match_dup 4)
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
- (parallel [(set (reg:DI 27)
- (sign_extend:DI (div:SI (reg:DI 24) (reg:DI 25))))
+ (parallel [(set (match_dup 5)
+ (sign_extend:DI (div:SI (match_dup 3) (match_dup 4))))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])
- (set (match_operand:SI 0 "general_operand" "")
- (subreg:SI (reg:DI 27) 0))]
- "!TARGET_OPEN_VMS"
- "")
+ (set (match_operand:SI 0 "nonimmediate_operand" "")
+ (subreg:SI (match_dup 5) 0))]
+ "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+{
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = gen_reg_rtx (DImode);
+})
(define_expand "udivsi3"
- [(set (reg:DI 24)
+ [(set (match_dup 3)
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
- (set (reg:DI 25)
+ (set (match_dup 4)
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
- (parallel [(set (reg:DI 27)
- (sign_extend:DI (udiv:SI (reg:DI 24) (reg:DI 25))))
+ (parallel [(set (match_dup 5)
+ (sign_extend:DI (udiv:SI (match_dup 3) (match_dup 4))))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])
- (set (match_operand:SI 0 "general_operand" "")
- (subreg:SI (reg:DI 27) 0))]
- "!TARGET_OPEN_VMS"
- "")
+ (set (match_operand:SI 0 "nonimmediate_operand" "")
+ (subreg:SI (match_dup 5) 0))]
+ "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+{
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = gen_reg_rtx (DImode);
+})
(define_expand "modsi3"
- [(set (reg:DI 24)
+ [(set (match_dup 3)
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
- (set (reg:DI 25)
+ (set (match_dup 4)
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
- (parallel [(set (reg:DI 27)
- (sign_extend:DI (mod:SI (reg:DI 24) (reg:DI 25))))
+ (parallel [(set (match_dup 5)
+ (sign_extend:DI (mod:SI (match_dup 3) (match_dup 4))))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])
- (set (match_operand:SI 0 "general_operand" "")
- (subreg:SI (reg:DI 27) 0))]
- "!TARGET_OPEN_VMS"
- "")
+ (set (match_operand:SI 0 "nonimmediate_operand" "")
+ (subreg:SI (match_dup 5) 0))]
+ "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+{
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = gen_reg_rtx (DImode);
+})
(define_expand "umodsi3"
- [(set (reg:DI 24)
+ [(set (match_dup 3)
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
- (set (reg:DI 25)
+ (set (match_dup 4)
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
- (parallel [(set (reg:DI 27)
- (sign_extend:DI (umod:SI (reg:DI 24) (reg:DI 25))))
+ (parallel [(set (match_dup 5)
+ (sign_extend:DI (umod:SI (match_dup 3) (match_dup 4))))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])
- (set (match_operand:SI 0 "general_operand" "")
- (subreg:SI (reg:DI 27) 0))]
- "!TARGET_OPEN_VMS"
- "")
+ (set (match_operand:SI 0 "nonimmediate_operand" "")
+ (subreg:SI (match_dup 5) 0))]
+ "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+{
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = gen_reg_rtx (DImode);
+})
(define_expand "divdi3"
- [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
- (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
- (parallel [(set (reg:DI 27)
- (div:DI (reg:DI 24)
- (reg:DI 25)))
+ [(parallel [(set (match_operand:DI 0 "register_operand" "")
+ (div:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
(clobber (reg:DI 23))
- (clobber (reg:DI 28))])
- (set (match_operand:DI 0 "general_operand" "")
- (reg:DI 27))]
- "!TARGET_OPEN_VMS"
+ (clobber (reg:DI 28))])]
+ "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
"")
(define_expand "udivdi3"
- [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
- (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
- (parallel [(set (reg:DI 27)
- (udiv:DI (reg:DI 24)
- (reg:DI 25)))
+ [(parallel [(set (match_operand:DI 0 "register_operand" "")
+ (udiv:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
(clobber (reg:DI 23))
- (clobber (reg:DI 28))])
- (set (match_operand:DI 0 "general_operand" "")
- (reg:DI 27))]
- "!TARGET_OPEN_VMS"
+ (clobber (reg:DI 28))])]
+ "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
"")
(define_expand "moddi3"
- [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
- (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
- (parallel [(set (reg:DI 27)
- (mod:DI (reg:DI 24)
- (reg:DI 25)))
+ [(use (match_operand:DI 0 "register_operand" ""))
+ (use (match_operand:DI 1 "register_operand" ""))
+ (use (match_operand:DI 2 "register_operand" ""))]
+ "!TARGET_ABI_OPEN_VMS"
+{
+ if (TARGET_ABI_UNICOSMK)
+ emit_insn (gen_moddi3_umk (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_moddi3_dft (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_expand "moddi3_dft"
+ [(parallel [(set (match_operand:DI 0 "register_operand" "")
+ (mod:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
(clobber (reg:DI 23))
- (clobber (reg:DI 28))])
- (set (match_operand:DI 0 "general_operand" "")
- (reg:DI 27))]
- "!TARGET_OPEN_VMS"
+ (clobber (reg:DI 28))])]
+ "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
"")
+;; On Unicos/Mk, we do as the system's C compiler does:
+;; compute the quotient, multiply and subtract.
+
+(define_expand "moddi3_umk"
+ [(use (match_operand:DI 0 "register_operand" ""))
+ (use (match_operand:DI 1 "register_operand" ""))
+ (use (match_operand:DI 2 "register_operand" ""))]
+ "TARGET_ABI_UNICOSMK"
+{
+ rtx div, mul = gen_reg_rtx (DImode);
+
+ div = expand_binop (DImode, sdiv_optab, operands[1], operands[2],
+ NULL_RTX, 0, OPTAB_LIB);
+ div = force_reg (DImode, div);
+ emit_insn (gen_muldi3 (mul, operands[2], div));
+ emit_insn (gen_subdi3 (operands[0], operands[1], mul));
+ DONE;
+})
+
(define_expand "umoddi3"
- [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
- (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
- (parallel [(set (reg:DI 27)
- (umod:DI (reg:DI 24)
- (reg:DI 25)))
+ [(use (match_operand:DI 0 "register_operand" ""))
+ (use (match_operand:DI 1 "register_operand" ""))
+ (use (match_operand:DI 2 "register_operand" ""))]
+ "! TARGET_ABI_OPEN_VMS"
+{
+ if (TARGET_ABI_UNICOSMK)
+ emit_insn (gen_umoddi3_umk (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_umoddi3_dft (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_expand "umoddi3_dft"
+ [(parallel [(set (match_operand:DI 0 "register_operand" "")
+ (umod:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
(clobber (reg:DI 23))
- (clobber (reg:DI 28))])
- (set (match_operand:DI 0 "general_operand" "")
- (reg:DI 27))]
- "!TARGET_OPEN_VMS"
+ (clobber (reg:DI 28))])]
+ "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
"")
+(define_expand "umoddi3_umk"
+ [(use (match_operand:DI 0 "register_operand" ""))
+ (use (match_operand:DI 1 "register_operand" ""))
+ (use (match_operand:DI 2 "register_operand" ""))]
+ "TARGET_ABI_UNICOSMK"
+{
+ rtx div, mul = gen_reg_rtx (DImode);
+
+ div = expand_binop (DImode, udiv_optab, operands[1], operands[2],
+ NULL_RTX, 1, OPTAB_LIB);
+ div = force_reg (DImode, div);
+ emit_insn (gen_muldi3 (mul, operands[2], div));
+ emit_insn (gen_subdi3 (operands[0], operands[1], mul));
+ DONE;
+})
+
;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
;; expanded by the assembler.
-(define_insn ""
- [(set (reg:DI 27)
- (sign_extend:DI (match_operator:SI 1 "divmod_operator"
- [(reg:DI 24) (reg:DI 25)])))
+
+(define_insn_and_split "*divmodsi_internal_er"
+ [(set (match_operand:DI 0 "register_operand" "=c")
+ (sign_extend:DI (match_operator:SI 3 "divmod_operator"
+ [(match_operand:DI 1 "register_operand" "a")
+ (match_operand:DI 2 "register_operand" "b")])))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
- "!TARGET_OPEN_VMS"
- "%E1 $24,$25,$27"
+ "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
+ "ldq $27,__%E3($29)\t\t!literal!%#\;jsr $23,($27),__%E3\t\t!lituse_jsr!%#"
+ "&& reload_completed"
+ [(parallel [(set (match_dup 0)
+ (sign_extend:DI (match_dup 3)))
+ (use (match_dup 0))
+ (use (match_dup 4))
+ (clobber (reg:DI 23))
+ (clobber (reg:DI 28))])]
+{
+ const char *str;
+ switch (GET_CODE (operands[3]))
+ {
+ case DIV:
+ str = "__divl";
+ break;
+ case UDIV:
+ str = "__divlu";
+ break;
+ case MOD:
+ str = "__reml";
+ break;
+ case UMOD:
+ str = "__remlu";
+ break;
+ default:
+ abort ();
+ }
+ operands[4] = GEN_INT (alpha_next_sequence_number++);
+ emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
+ gen_rtx_SYMBOL_REF (DImode, str),
+ operands[4]));
+}
+ [(set_attr "type" "jsr")
+ (set_attr "length" "8")])
+
+(define_insn "*divmodsi_internal_er_1"
+ [(set (match_operand:DI 0 "register_operand" "=c")
+ (sign_extend:DI (match_operator:SI 3 "divmod_operator"
+ [(match_operand:DI 1 "register_operand" "a")
+ (match_operand:DI 2 "register_operand" "b")])))
+ (use (match_operand:DI 4 "register_operand" "c"))
+ (use (match_operand 5 "const_int_operand" ""))
+ (clobber (reg:DI 23))
+ (clobber (reg:DI 28))]
+ "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
+ "jsr $23,($27),__%E3%J5"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "4")])
+
+(define_insn "*divmodsi_internal"
+ [(set (match_operand:DI 0 "register_operand" "=c")
+ (sign_extend:DI (match_operator:SI 3 "divmod_operator"
+ [(match_operand:DI 1 "register_operand" "a")
+ (match_operand:DI 2 "register_operand" "b")])))
+ (clobber (reg:DI 23))
+ (clobber (reg:DI 28))]
+ "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "%E3 %1,%2,%0"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "8")])
+
+(define_insn_and_split "*divmoddi_internal_er"
+ [(set (match_operand:DI 0 "register_operand" "=c")
+ (match_operator:DI 3 "divmod_operator"
+ [(match_operand:DI 1 "register_operand" "a")
+ (match_operand:DI 2 "register_operand" "b")]))
+ (clobber (reg:DI 23))
+ (clobber (reg:DI 28))]
+ "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
+ "ldq $27,__%E3($29)\t\t!literal!%#\;jsr $23,($27),__%E3\t\t!lituse_jsr!%#"
+ "&& reload_completed"
+ [(parallel [(set (match_dup 0) (match_dup 3))
+ (use (match_dup 0))
+ (use (match_dup 4))
+ (clobber (reg:DI 23))
+ (clobber (reg:DI 28))])]
+{
+ const char *str;
+ switch (GET_CODE (operands[3]))
+ {
+ case DIV:
+ str = "__divq";
+ break;
+ case UDIV:
+ str = "__divqu";
+ break;
+ case MOD:
+ str = "__remq";
+ break;
+ case UMOD:
+ str = "__remqu";
+ break;
+ default:
+ abort ();
+ }
+ operands[4] = GEN_INT (alpha_next_sequence_number++);
+ emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
+ gen_rtx_SYMBOL_REF (DImode, str),
+ operands[4]));
+}
[(set_attr "type" "jsr")
(set_attr "length" "8")])
-(define_insn ""
- [(set (reg:DI 27)
- (match_operator:DI 1 "divmod_operator"
- [(reg:DI 24) (reg:DI 25)]))
+(define_insn "*divmoddi_internal_er_1"
+ [(set (match_operand:DI 0 "register_operand" "=c")
+ (match_operator:DI 3 "divmod_operator"
+ [(match_operand:DI 1 "register_operand" "a")
+ (match_operand:DI 2 "register_operand" "b")]))
+ (use (match_operand:DI 4 "register_operand" "c"))
+ (use (match_operand 5 "const_int_operand" ""))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
- "!TARGET_OPEN_VMS"
- "%E1 $24,$25,$27"
+ "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
+ "jsr $23,($27),__%E3%J5"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "4")])
+
+(define_insn "*divmoddi_internal"
+ [(set (match_operand:DI 0 "register_operand" "=c")
+ (match_operator:DI 3 "divmod_operator"
+ [(match_operand:DI 1 "register_operand" "a")
+ (match_operand:DI 2 "register_operand" "b")]))
+ (clobber (reg:DI 23))
+ (clobber (reg:DI 28))]
+ "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "%E3 %1,%2,%0"
[(set_attr "type" "jsr")
(set_attr "length" "8")])
@@ -1048,7 +1362,6 @@
"HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
[(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
- "
{
unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
unsigned HOST_WIDE_INT mask2 = mask1;
@@ -1064,16 +1377,43 @@
operands[3] = GEN_INT (mask1);
operands[4] = GEN_INT (mask2);
-}")
+})
+
+(define_expand "zero_extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ ""
+{
+ if (! TARGET_BWX)
+ operands[1] = force_reg (QImode, operands[1]);
+})
-(define_insn "zero_extendqihi2"
+(define_insn "*zero_extendqihi2_bwx"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
+ "TARGET_BWX"
+ "@
+ and %1,0xff,%0
+ ldbu %0,%1"
+ [(set_attr "type" "ilog,ild")])
+
+(define_insn "*zero_extendqihi2_nobwx"
[(set (match_operand:HI 0 "register_operand" "=r")
(zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
- ""
+ "! TARGET_BWX"
"and %1,0xff,%0"
[(set_attr "type" "ilog")])
-(define_insn ""
+(define_expand "zero_extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ ""
+{
+ if (! TARGET_BWX)
+ operands[1] = force_reg (QImode, operands[1]);
+})
+
+(define_insn "*zero_extendqisi2_bwx"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
"TARGET_BWX"
@@ -1082,20 +1422,23 @@
ldbu %0,%1"
[(set_attr "type" "ilog,ild")])
-(define_insn ""
+(define_insn "*zero_extendqisi2_nobwx"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
"! TARGET_BWX"
"and %1,0xff,%0"
[(set_attr "type" "ilog")])
-(define_expand "zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
+(define_expand "zero_extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
""
- "")
+{
+ if (! TARGET_BWX)
+ operands[1] = force_reg (QImode, operands[1]);
+})
-(define_insn ""
+(define_insn "*zero_extendqidi2_bwx"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
"TARGET_BWX"
@@ -1104,20 +1447,23 @@
ldbu %0,%1"
[(set_attr "type" "ilog,ild")])
-(define_insn ""
+(define_insn "*zero_extendqidi2_nobwx"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
"! TARGET_BWX"
"and %1,0xff,%0"
[(set_attr "type" "ilog")])
-
-(define_expand "zero_extendqidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
+
+(define_expand "zero_extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
""
- "")
-
-(define_insn ""
+{
+ if (! TARGET_BWX)
+ operands[1] = force_reg (HImode, operands[1]);
+})
+
+(define_insn "*zero_extendhisi2_bwx"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
"TARGET_BWX"
@@ -1126,20 +1472,23 @@
ldwu %0,%1"
[(set_attr "type" "shift,ild")])
-(define_insn ""
+(define_insn "*zero_extendhisi2_nobwx"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
"! TARGET_BWX"
"zapnot %1,3,%0"
[(set_attr "type" "shift")])
-(define_expand "zero_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
+(define_expand "zero_extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
""
- "")
+{
+ if (! TARGET_BWX)
+ operands[1] = force_reg (HImode, operands[1]);
+})
-(define_insn ""
+(define_insn "*zero_extendhidi2_bwx"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
"TARGET_BWX"
@@ -1148,19 +1497,13 @@
ldwu %0,%1"
[(set_attr "type" "shift,ild")])
-(define_insn ""
+(define_insn "*zero_extendhidi2_nobwx"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
""
"zapnot %1,3,%0"
[(set_attr "type" "shift")])
-(define_expand "zero_extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
- ""
- "")
-
(define_insn "zero_extendsidi2"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
@@ -1168,7 +1511,7 @@
"zapnot %1,15,%0"
[(set_attr "type" "shift")])
-(define_insn ""
+(define_insn "andnotdi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
(match_operand:DI 2 "reg_or_0_operand" "rJ")))]
@@ -1193,7 +1536,7 @@
"ornot $31,%1,%0"
[(set_attr "type" "ilog")])
-(define_insn ""
+(define_insn "*iornot"
[(set (match_operand:DI 0 "register_operand" "=r")
(ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
(match_operand:DI 2 "reg_or_0_operand" "rJ")))]
@@ -1211,7 +1554,7 @@
eqv %r1,%N2,%0"
[(set_attr "type" "ilog")])
-(define_insn ""
+(define_insn "*xornot"
[(set (match_operand:DI 0 "register_operand" "=r")
(not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
(match_operand:DI 2 "register_operand" "rI"))))]
@@ -1219,37 +1562,28 @@
"eqv %r1,%2,%0"
[(set_attr "type" "ilog")])
-;; Handle the FFS insn iff we support CIX.
-;;
-;; These didn't make it into EV6 pass 2 as planned. Instead they
-;; cropped cttz/ctlz/ctpop from the old CIX and renamed it FIX for
-;; "Square Root and Floating Point Convert Extension".
-;;
-;; I'm assured that these insns will make it into EV67 (first pass
-;; due Summer 1999), presumably with a new AMASK bit, and presumably
-;; will still be named CIX.
+;; Handle the FFS insn iff we support CIX.
(define_expand "ffsdi2"
[(set (match_dup 2)
- (unspec [(match_operand:DI 1 "register_operand" "")] 1))
+ (unspec:DI [(match_operand:DI 1 "register_operand" "")] UNSPEC_CTTZ))
(set (match_dup 3)
(plus:DI (match_dup 2) (const_int 1)))
(set (match_operand:DI 0 "register_operand" "")
(if_then_else:DI (eq (match_dup 1) (const_int 0))
(const_int 0) (match_dup 3)))]
"TARGET_CIX"
- "
{
operands[2] = gen_reg_rtx (DImode);
operands[3] = gen_reg_rtx (DImode);
-}")
+})
-(define_insn ""
+(define_insn "*cttz"
[(set (match_operand:DI 0 "register_operand" "=r")
- (unspec [(match_operand:DI 1 "register_operand" "r")] 1))]
+ (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_CTTZ))]
"TARGET_CIX"
"cttz %1,%0"
- ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just
+ ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just
; reuse the existing type name.
[(set_attr "type" "mvi")])
@@ -1260,21 +1594,20 @@
(ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
(match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))]
""
- "*
{
switch (which_alternative)
{
case 0:
if (operands[2] == const1_rtx)
- return \"addq %r1,%r1,%0\";
+ return "addq %r1,%r1,%0";
else
- return \"s%P2addq %r1,0,%0\";
+ return "s%P2addq %r1,0,%0";
case 1:
- return \"sll %r1,%2,%0\";
+ return "sll %r1,%2,%0";
default:
abort();
}
-}"
+}
[(set_attr "type" "iadd,shift")])
;; ??? The following pattern is made by combine, but earlier phases
@@ -1287,15 +1620,14 @@
;; (match_operand:DI 2 "const_int_operand" "P"))
;; 0)))]
;; "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
-;; "*
;;{
;; if (operands[2] == const1_rtx)
-;; return \"addl %r1,%r1,%0\";
+;; return "addl %r1,%r1,%0";
;; else
-;; return \"s%P2addl %r1,0,%0\";
-;; }"
+;; return "s%P2addl %r1,0,%0";
+;;}
;; [(set_attr "type" "iadd")])
-
+
(define_insn "lshrdi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
@@ -1320,7 +1652,6 @@
(ashiftrt:DI (match_dup 2)
(const_int 56)))]
""
- "
{
if (TARGET_BWX)
{
@@ -1328,7 +1659,7 @@
force_reg (QImode, operands[1])));
DONE;
}
-
+
/* If we have an unaligned MEM, extend to DImode (which we do
specially) and then copy to the result. */
if (unaligned_memory_operand (operands[1], HImode))
@@ -1343,7 +1674,7 @@
operands[0] = gen_lowpart (DImode, operands[0]);
operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
operands[2] = gen_reg_rtx (DImode);
-}")
+})
(define_insn "extendqidi2x"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -1388,7 +1719,6 @@
(ashiftrt:DI (match_dup 2)
(const_int 56)))]
""
- "
{
if (TARGET_BWX)
{
@@ -1411,7 +1741,7 @@
operands[0] = gen_lowpart (DImode, operands[0]);
operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
operands[2] = gen_reg_rtx (DImode);
-}")
+})
(define_expand "extendqidi2"
[(set (match_dup 2)
@@ -1421,7 +1751,6 @@
(ashiftrt:DI (match_dup 2)
(const_int 56)))]
""
- "
{
if (TARGET_BWX)
{
@@ -1443,7 +1772,7 @@
operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
operands[2] = gen_reg_rtx (DImode);
-}")
+})
(define_expand "extendhisi2"
[(set (match_dup 2)
@@ -1453,7 +1782,6 @@
(ashiftrt:DI (match_dup 2)
(const_int 48)))]
""
- "
{
if (TARGET_BWX)
{
@@ -1476,7 +1804,7 @@
operands[0] = gen_lowpart (DImode, operands[0]);
operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
operands[2] = gen_reg_rtx (DImode);
-}")
+})
(define_expand "extendhidi2"
[(set (match_dup 2)
@@ -1486,7 +1814,6 @@
(ashiftrt:DI (match_dup 2)
(const_int 48)))]
""
- "
{
if (TARGET_BWX)
{
@@ -1508,7 +1835,7 @@
operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
operands[2] = gen_reg_rtx (DImode);
-}")
+})
;; Here's how we sign extend an unaligned byte and halfword. Doing this
;; as a pattern saves one instruction. The code is similar to that for
@@ -1516,48 +1843,120 @@
;;
;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
(define_expand "unaligned_extendqidi"
+ [(use (match_operand:QI 0 "register_operand" ""))
+ (use (match_operand:DI 1 "address_operand" ""))]
+ ""
+{
+ if (WORDS_BIG_ENDIAN)
+ emit_insn (gen_unaligned_extendqidi_be (operands[0], operands[1]));
+ else
+ emit_insn (gen_unaligned_extendqidi_le (operands[0], operands[1]));
+ DONE;
+})
+
+(define_expand "unaligned_extendqidi_le"
[(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
(set (match_dup 3)
(mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
(const_int -8))))
(set (match_dup 4)
(ashift:DI (match_dup 3)
- (minus:DI (const_int 56)
+ (minus:DI (const_int 64)
(ashift:DI
- (and:DI (plus:DI (match_dup 2) (const_int -1))
- (const_int 7))
+ (and:DI (match_dup 2) (const_int 7))
(const_int 3)))))
(set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
(ashiftrt:DI (match_dup 4) (const_int 56)))]
- ""
- "
-{ operands[2] = gen_reg_rtx (DImode);
+ "! WORDS_BIG_ENDIAN"
+{
+ operands[2] = gen_reg_rtx (DImode);
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
-}")
+})
+
+(define_expand "unaligned_extendqidi_be"
+ [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
+ (set (match_dup 3) (plus:DI (match_dup 2) (const_int -1)))
+ (set (match_dup 4)
+ (mem:DI (and:DI (match_dup 3)
+ (const_int -8))))
+ (set (match_dup 5) (plus:DI (match_dup 2) (const_int -2)))
+ (set (match_dup 6)
+ (ashift:DI (match_dup 4)
+ (ashift:DI
+ (and:DI
+ (plus:DI (match_dup 5) (const_int 1))
+ (const_int 7))
+ (const_int 3))))
+ (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (ashiftrt:DI (match_dup 6) (const_int 56)))]
+ "WORDS_BIG_ENDIAN"
+{
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = gen_reg_rtx (DImode);
+ operands[6] = gen_reg_rtx (DImode);
+})
(define_expand "unaligned_extendhidi"
+ [(use (match_operand:QI 0 "register_operand" ""))
+ (use (match_operand:DI 1 "address_operand" ""))]
+ ""
+{
+ operands[0] = gen_lowpart (DImode, operands[0]);
+ emit_insn ((WORDS_BIG_ENDIAN
+ ? gen_unaligned_extendhidi_be
+ : gen_unaligned_extendhidi_le) (operands[0], operands[1]));
+ DONE;
+})
+
+(define_expand "unaligned_extendhidi_le"
[(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
(set (match_dup 3)
(mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
(const_int -8))))
(set (match_dup 4)
(ashift:DI (match_dup 3)
- (minus:DI (const_int 56)
+ (minus:DI (const_int 64)
(ashift:DI
- (and:DI (plus:DI (match_dup 2) (const_int -1))
- (const_int 7))
+ (and:DI (match_dup 2) (const_int 7))
(const_int 3)))))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(ashiftrt:DI (match_dup 4) (const_int 48)))]
- ""
- "
-{ operands[2] = gen_reg_rtx (DImode);
+ "! WORDS_BIG_ENDIAN"
+{
+ operands[2] = gen_reg_rtx (DImode);
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
-}")
+})
-(define_insn ""
+(define_expand "unaligned_extendhidi_be"
+ [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
+ (set (match_dup 3) (plus:DI (match_dup 2) (const_int -2)))
+ (set (match_dup 4)
+ (mem:DI (and:DI (match_dup 3)
+ (const_int -8))))
+ (set (match_dup 5) (plus:DI (match_dup 2) (const_int -3)))
+ (set (match_dup 6)
+ (ashift:DI (match_dup 4)
+ (ashift:DI
+ (and:DI
+ (plus:DI (match_dup 5) (const_int 1))
+ (const_int 7))
+ (const_int 3))))
+ (set (match_operand:DI 0 "register_operand" "")
+ (ashiftrt:DI (match_dup 6) (const_int 48)))]
+ "WORDS_BIG_ENDIAN"
+{
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = gen_reg_rtx (DImode);
+ operands[6] = gen_reg_rtx (DImode);
+})
+
+(define_insn "*extxl_const"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(match_operand:DI 2 "mode_width_operand" "n")
@@ -1566,83 +1965,164 @@
"ext%M2l %r1,%s3,%0"
[(set_attr "type" "shift")])
-(define_insn "extxl"
+(define_insn "extxl_le"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(match_operand:DI 2 "mode_width_operand" "n")
(ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
(const_int 3))))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "ext%M2l %r1,%3,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "extxl_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (match_operand:DI 2 "mode_width_operand" "n")
+ (minus:DI
+ (const_int 56)
+ (ashift:DI
+ (match_operand:DI 3 "reg_or_8bit_operand" "rI")
+ (const_int 3)))))]
+ "WORDS_BIG_ENDIAN"
"ext%M2l %r1,%3,%0"
[(set_attr "type" "shift")])
;; Combine has some strange notion of preserving existing undefined behaviour
-;; in shifts larger than a word size. So capture these patterns that it
+;; in shifts larger than a word size. So capture these patterns that it
;; should have turned into zero_extracts.
-(define_insn ""
+(define_insn "*extxl_1_le"
[(set (match_operand:DI 0 "register_operand" "=r")
- (and (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 3)))
+ (and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
+ (const_int 3)))
(match_operand:DI 3 "mode_mask_operand" "n")))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "ext%U3l %1,%2,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "*extxl_1_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (and:DI (lshiftrt:DI
+ (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (minus:DI (const_int 56)
+ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
+ (const_int 3))))
+ (match_operand:DI 3 "mode_mask_operand" "n")))]
+ "WORDS_BIG_ENDIAN"
"ext%U3l %1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn ""
+(define_insn "*extql_2_le"
[(set (match_operand:DI 0 "register_operand" "=r")
(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "extql %1,%2,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "*extql_2_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (lshiftrt:DI
+ (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (minus:DI (const_int 56)
+ (ashift:DI
+ (match_operand:DI 2 "reg_or_8bit_operand" "rI")
+ (const_int 3)))))]
+ "WORDS_BIG_ENDIAN"
"extql %1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extqh"
+(define_insn "extqh_le"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(match_operand:DI 1 "reg_or_0_operand" "rJ")
- (minus:DI (const_int 56)
+ (minus:DI (const_int 64)
(ashift:DI
(and:DI
- (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int -1))
+ (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 7))
(const_int 3)))))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "extqh %r1,%2,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "extqh_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ashift:DI
+ (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (ashift:DI
+ (and:DI
+ (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
+ (const_int 1))
+ (const_int 7))
+ (const_int 3))))]
+ "WORDS_BIG_ENDIAN"
"extqh %r1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extlh"
+(define_insn "extlh_le"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(const_int 2147483647))
- (minus:DI (const_int 56)
+ (minus:DI (const_int 64)
(ashift:DI
(and:DI
- (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int -1))
+ (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 7))
(const_int 3)))))]
- ""
+ "! WORDS_BIG_ENDIAN"
"extlh %r1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extwh"
+(define_insn "extlh_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (and:DI
+ (ashift:DI
+ (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (ashift:DI
+ (and:DI
+ (plus:DI
+ (match_operand:DI 2 "reg_or_8bit_operand" "rI")
+ (const_int 1))
+ (const_int 7))
+ (const_int 3)))
+ (const_int 2147483647)))]
+ "WORDS_BIG_ENDIAN"
+ "extlh %r1,%2,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "extwh_le"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(const_int 65535))
- (minus:DI (const_int 56)
+ (minus:DI (const_int 64)
(ashift:DI
(and:DI
- (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int -1))
+ (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 7))
(const_int 3)))))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "extwh %r1,%2,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "extwh_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (and:DI
+ (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (ashift:DI
+ (and:DI
+ (plus:DI
+ (match_operand:DI 2 "reg_or_8bit_operand" "rI")
+ (const_int 1))
+ (const_int 7))
+ (const_int 3)))
+ (const_int 65535)))]
+ "WORDS_BIG_ENDIAN"
"extwh %r1,%2,%0"
[(set_attr "type" "shift")])
@@ -1667,12 +2147,12 @@
;; (match_dup 4)))]
;; "
;;{
-;; operands[6] = plus_constant (operands[3],
+;; operands[6] = plus_constant (operands[3],
;; INTVAL (operands[2]) / BITS_PER_UNIT);
;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
;;}")
-
-(define_insn ""
+
+(define_insn "*insbl_const"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
(match_operand:DI 2 "mul8_operand" "I")))]
@@ -1680,7 +2160,7 @@
"insbl %1,%s2,%0"
[(set_attr "type" "shift")])
-(define_insn ""
+(define_insn "*inswl_const"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
(match_operand:DI 2 "mul8_operand" "I")))]
@@ -1688,7 +2168,7 @@
"inswl %1,%s2,%0"
[(set_attr "type" "shift")])
-(define_insn ""
+(define_insn "*insll_const"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
(match_operand:DI 2 "mul8_operand" "I")))]
@@ -1696,46 +2176,86 @@
"insll %1,%s2,%0"
[(set_attr "type" "shift")])
-(define_insn "insbl"
+(define_insn "insbl_le"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "insbl %1,%2,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "insbl_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
+ (minus:DI (const_int 56)
+ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
+ (const_int 3)))))]
+ "WORDS_BIG_ENDIAN"
"insbl %1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "inswl"
+(define_insn "inswl_le"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "inswl %1,%2,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "inswl_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
+ (minus:DI (const_int 56)
+ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
+ (const_int 3)))))]
+ "WORDS_BIG_ENDIAN"
"inswl %1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "insll"
+(define_insn "insll_le"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
- ""
+ "! WORDS_BIG_ENDIAN"
"insll %1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "insql"
+(define_insn "insll_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (minus:DI (const_int 56)
+ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
+ (const_int 3)))))]
+ "WORDS_BIG_ENDIAN"
+ "insll %1,%2,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "insql_le"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (match_operand:DI 1 "register_operand" "r")
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "insql %1,%2,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "insql_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ashift:DI (match_operand:DI 1 "register_operand" "r")
+ (minus:DI (const_int 56)
+ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
+ (const_int 3)))))]
+ "WORDS_BIG_ENDIAN"
"insql %1,%2,%0"
[(set_attr "type" "shift")])
;; Combine has this sometimes habit of moving the and outside of the
;; shift, making life more interesting.
-(define_insn ""
+(define_insn "*insxl"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "mul8_operand" "I"))
@@ -1748,21 +2268,20 @@
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|| ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
== (unsigned HOST_WIDE_INT) INTVAL (operands[3])))"
- "*
{
#if HOST_BITS_PER_WIDE_INT == 64
if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
- return \"insbl %1,%s2,%0\";
+ return "insbl %1,%s2,%0";
if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
- return \"inswl %1,%s2,%0\";
+ return "inswl %1,%s2,%0";
if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
- return \"insll %1,%s2,%0\";
+ return "insll %1,%s2,%0";
#endif
abort();
-}"
+}
[(set_attr "type" "shift")])
;; We do not include the insXh insns because they are complex to express
@@ -1772,14 +2291,15 @@
(define_insn "insxh"
[(set (match_operand:DI 0 "register_operand" "=r")
- (unspec [(match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "mode_width_operand" "n")
- (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 2))]
+ (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand:DI 2 "mode_width_operand" "n")
+ (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
+ UNSPEC_INSXH))]
""
"ins%M2h %1,%3,%0"
[(set_attr "type" "shift")])
-(define_insn "mskxl"
+(define_insn "mskxl_le"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (not:DI (ashift:DI
(match_operand:DI 2 "mode_mask_operand" "n")
@@ -1787,7 +2307,20 @@
(match_operand:DI 3 "reg_or_8bit_operand" "rI")
(const_int 3))))
(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "msk%U2l %r1,%3,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "mskxl_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (and:DI (not:DI (ashift:DI
+ (match_operand:DI 2 "mode_mask_operand" "n")
+ (minus:DI (const_int 56)
+ (ashift:DI
+ (match_operand:DI 3 "reg_or_8bit_operand" "rI")
+ (const_int 3)))))
+ (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
+ "WORDS_BIG_ENDIAN"
"msk%U2l %r1,%3,%0"
[(set_attr "type" "shift")])
@@ -1798,12 +2331,29 @@
(define_insn "mskxh"
[(set (match_operand:DI 0 "register_operand" "=r")
- (unspec [(match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "mode_width_operand" "n")
- (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 3))]
+ (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand:DI 2 "mode_width_operand" "n")
+ (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
+ UNSPEC_MSKXH))]
""
"msk%M2h %1,%3,%0"
[(set_attr "type" "shift")])
+
+;; Prefer AND + NE over LSHIFTRT + AND.
+
+(define_insn_and_split "*ze_and_ne"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (const_int 1)
+ (match_operand 2 "const_int_operand" "I")))]
+ "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
+ "#"
+ "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
+ [(set (match_dup 0)
+ (and:DI (match_dup 1) (match_dup 3)))
+ (set (match_dup 0)
+ (ne:DI (match_dup 0) (const_int 0)))]
+ "operands[3] = GEN_INT (1 << INTVAL (operands[2]));")
;; Floating-point operations. All the double-precision insns can extend
;; from single, so indicate that. The exception are the ones that simply
@@ -1816,6 +2366,13 @@
"cpys $f31,%R1,%0"
[(set_attr "type" "fcpys")])
+(define_insn "*nabssf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
+ "TARGET_FP"
+ "cpysn $f31,%R1,%0"
+ [(set_attr "type" "fadd")])
+
(define_insn "absdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
@@ -1823,6 +2380,36 @@
"cpys $f31,%R1,%0"
[(set_attr "type" "fcpys")])
+(define_insn "*nabsdf2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG"))))]
+ "TARGET_FP"
+ "cpysn $f31,%R1,%0"
+ [(set_attr "type" "fadd")])
+
+(define_expand "abstf2"
+ [(parallel [(set (match_operand:TF 0 "register_operand" "")
+ (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "")))
+ (use (match_dup 2))])]
+ "TARGET_HAS_XFLOATING_LIBS"
+{
+#if HOST_BITS_PER_WIDE_INT >= 64
+ operands[2] = force_reg (DImode, GEN_INT ((HOST_WIDE_INT) 1 << 63));
+#else
+ operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
+#endif
+})
+
+(define_insn_and_split "*abstf_internal"
+ [(set (match_operand:TF 0 "register_operand" "=r")
+ (abs:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG")))
+ (use (match_operand:DI 2 "register_operand" "r"))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;")
+
(define_insn "negsf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
@@ -1837,62 +2424,104 @@
"cpysn %R1,%R1,%0"
[(set_attr "type" "fadd")])
-(define_insn ""
+(define_expand "negtf2"
+ [(parallel [(set (match_operand:TF 0 "register_operand" "")
+ (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "")))
+ (use (match_dup 2))])]
+ "TARGET_HAS_XFLOATING_LIBS"
+{
+#if HOST_BITS_PER_WIDE_INT >= 64
+ operands[2] = force_reg (DImode, GEN_INT ((HOST_WIDE_INT) 1 << 63));
+#else
+ operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
+#endif
+})
+
+(define_insn_and_split "*negtf_internal"
+ [(set (match_operand:TF 0 "register_operand" "=r")
+ (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG")))
+ (use (match_operand:DI 2 "register_operand" "r"))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
+
+(define_insn "*addsf_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
(plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
(match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "add%,%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "add%,%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
(define_insn "addsf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
(match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
"TARGET_FP"
- "add%,%)%& %R1,%R2,%0"
+ "add%,%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*adddf_ieee"
[(set (match_operand:DF 0 "register_operand" "=&f")
(plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "add%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "add%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
(define_insn "adddf3"
[(set (match_operand:DF 0 "register_operand" "=f")
(plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
"TARGET_FP"
- "add%-%)%& %R1,%R2,%0"
+ "add%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*adddf_ext1"
[(set (match_operand:DF 0 "register_operand" "=f")
(plus:DF (float_extend:DF
(match_operand:SF 1 "reg_or_fp0_operand" "fG"))
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "add%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "add%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*adddf_ext2"
[(set (match_operand:DF 0 "register_operand" "=f")
(plus:DF (float_extend:DF
(match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
(float_extend:DF
(match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "add%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "add%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_expand "addtf3"
+ [(use (match_operand 0 "register_operand" ""))
+ (use (match_operand 1 "general_operand" ""))
+ (use (match_operand 2 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
;; Define conversion operators between DFmode and SImode, using the cvtql
;; instruction. To allow combine et al to do useful things, we keep the
@@ -1905,473 +2534,672 @@
(define_insn "*cvtql"
[(set (match_operand:SI 0 "register_operand" "=f")
- (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")] 5))]
+ (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")]
+ UNSPEC_CVTQL))]
"TARGET_FP"
- "cvtql%` %R1,%0"
+ "cvtql%/ %R1,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
-
-(define_split
- [(set (match_operand:SI 0 "memory_operand" "")
- (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0))
- (clobber (match_scratch:DI 2 ""))
- (clobber (match_scratch:SI 3 ""))]
- "TARGET_FP && reload_completed"
- [(set (match_dup 2) (fix:DI (match_dup 1)))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
- (set (match_dup 0) (match_dup 3))]
- "")
+ (set_attr "trap" "yes")
+ (set_attr "trap_suffix" "v_sv")])
-(define_split
- [(set (match_operand:SI 0 "memory_operand" "")
- (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0))
- (clobber (match_scratch:DI 2 ""))]
- "TARGET_FP && reload_completed"
- [(set (match_dup 2) (fix:DI (match_dup 1)))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
- (set (match_dup 0) (match_dup 3))]
- ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
- "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));")
-
-(define_insn ""
+(define_insn_and_split "*fix_truncdfsi_ieee"
[(set (match_operand:SI 0 "memory_operand" "=m")
(subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
(clobber (match_scratch:DI 2 "=&f"))
(clobber (match_scratch:SI 3 "=&f"))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"#"
+ "&& reload_completed"
+ [(set (match_dup 2) (fix:DI (match_dup 1)))
+ (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 0) (match_dup 3))]
+ ""
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
-(define_insn ""
+(define_insn_and_split "*fix_truncdfsi_internal"
[(set (match_operand:SI 0 "memory_operand" "=m")
(subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
(clobber (match_scratch:DI 2 "=f"))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"#"
+ "&& reload_completed"
+ [(set (match_dup 2) (fix:DI (match_dup 1)))
+ (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 0) (match_dup 3))]
+ ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
+ "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
-(define_insn ""
+(define_insn "*fix_truncdfdi_ieee"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
(fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "cvt%-q%(c %R1,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "c")
+ (set_attr "trap_suffix" "v_sv_svi")])
(define_insn "fix_truncdfdi2"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
(fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
"TARGET_FP"
- "cvt%-q%(c %R1,%0"
+ "cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "c")
+ (set_attr "trap_suffix" "v_sv_svi")])
;; Likewise between SFmode and SImode.
-(define_split
- [(set (match_operand:SI 0 "memory_operand" "")
- (subreg:SI (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0))
- (clobber (match_scratch:DI 2 ""))
- (clobber (match_scratch:SI 3 ""))]
- "TARGET_FP && reload_completed"
- [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
- (set (match_dup 0) (match_dup 3))]
- "")
-
-(define_split
- [(set (match_operand:SI 0 "memory_operand" "")
- (subreg:SI (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0))
- (clobber (match_scratch:DI 2 ""))]
- "TARGET_FP && reload_completed"
- [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
- (set (match_dup 0) (match_dup 3))]
- ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
- "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));")
-
-(define_insn ""
+(define_insn_and_split "*fix_truncsfsi_ieee"
[(set (match_operand:SI 0 "memory_operand" "=m")
(subreg:SI (fix:DI (float_extend:DF
(match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
(clobber (match_scratch:DI 2 "=&f"))
(clobber (match_scratch:SI 3 "=&f"))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"#"
+ "&& reload_completed"
+ [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
+ (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 0) (match_dup 3))]
+ ""
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
-(define_insn ""
+(define_insn_and_split "*fix_truncsfsi_internal"
[(set (match_operand:SI 0 "memory_operand" "=m")
(subreg:SI (fix:DI (float_extend:DF
(match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
(clobber (match_scratch:DI 2 "=f"))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"#"
+ "&& reload_completed"
+ [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
+ (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 0) (match_dup 3))]
+ ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
+ "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
-(define_insn ""
+(define_insn "*fix_truncsfdi_ieee"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
(fix:DI (float_extend:DF
(match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "cvt%-q%(c %R1,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "c")
+ (set_attr "trap_suffix" "v_sv_svi")])
(define_insn "fix_truncsfdi2"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
(fix:DI (float_extend:DF
(match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
"TARGET_FP"
- "cvt%-q%(c %R1,%0"
+ "cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "c")
+ (set_attr "trap_suffix" "v_sv_svi")])
-(define_insn ""
+(define_expand "fix_trunctfdi2"
+ [(use (match_operand:DI 0 "register_operand" ""))
+ (use (match_operand:TF 1 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_cvt (FIX, operands); DONE;")
+
+(define_insn "*floatdisf_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "cvtq%,%+%& %1,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "cvtq%,%/ %1,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "sui")])
(define_insn "floatdisf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
"TARGET_FP"
- "cvtq%,%+%& %1,%0"
+ "cvtq%,%/ %1,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "sui")])
-(define_insn ""
+(define_insn "*floatdidf_ieee"
[(set (match_operand:DF 0 "register_operand" "=&f")
(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "cvtq%-%+%& %1,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "cvtq%-%/ %1,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "sui")])
(define_insn "floatdidf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
"TARGET_FP"
- "cvtq%-%+%& %1,%0"
+ "cvtq%-%/ %1,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "sui")])
+
+(define_expand "floatditf2"
+ [(use (match_operand:TF 0 "register_operand" ""))
+ (use (match_operand:DI 1 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
+
+(define_expand "floatunsdisf2"
+ [(use (match_operand:SF 0 "register_operand" ""))
+ (use (match_operand:DI 1 "register_operand" ""))]
+ "TARGET_FP"
+ "alpha_emit_floatuns (operands); DONE;")
-(define_expand "extendsfdf2"
+(define_expand "floatunsdidf2"
[(use (match_operand:DF 0 "register_operand" ""))
- (use (match_operand:SF 1 "nonimmediate_operand" ""))]
+ (use (match_operand:DI 1 "register_operand" ""))]
+ "TARGET_FP"
+ "alpha_emit_floatuns (operands); DONE;")
+
+(define_expand "floatunsditf2"
+ [(use (match_operand:TF 0 "register_operand" ""))
+ (use (match_operand:DI 1 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
+
+(define_expand "extendsfdf2"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
"TARGET_FP"
-"
{
- if (alpha_tp == ALPHA_TP_INSN)
- emit_insn (gen_extendsfdf2_tp (operands[0],
- force_reg (SFmode, operands[1])));
- else
- emit_insn (gen_extendsfdf2_no_tp (operands[0], operands[1]));
+ if (alpha_fptm >= ALPHA_FPTM_SU)
+ operands[1] = force_reg (SFmode, operands[1]);
+})
- DONE;
-}")
-;; FIXME
-(define_insn "extendsfdf2_tp"
+;; The Unicos/Mk assembler doesn't support cvtst, but we've already
+;; asserted that alpha_fptm == ALPHA_FPTM_N.
+
+(define_insn "*extendsfdf2_ieee"
[(set (match_operand:DF 0 "register_operand" "=&f")
(float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"cvtsts %1,%0"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
-(define_insn "extendsfdf2_no_tp"
+(define_insn "*extendsfdf2_internal"
[(set (match_operand:DF 0 "register_operand" "=f,f,m")
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"@
- fmov %1,%0
+ cpys %1,%1,%0
ld%, %0,%1
st%- %1,%0"
- [(set_attr "type" "fcpys,fld,fst")
- (set_attr "trap" "yes")])
+ [(set_attr "type" "fcpys,fld,fst")])
-(define_insn ""
+(define_expand "extendsftf2"
+ [(use (match_operand:TF 0 "register_operand" ""))
+ (use (match_operand:SF 1 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+{
+ rtx tmp = gen_reg_rtx (DFmode);
+ emit_insn (gen_extendsfdf2 (tmp, operands[1]));
+ emit_insn (gen_extenddftf2 (operands[0], tmp));
+ DONE;
+})
+
+(define_expand "extenddftf2"
+ [(use (match_operand:TF 0 "register_operand" ""))
+ (use (match_operand:DF 1 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
+
+(define_insn "*truncdfsf2_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
(float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "cvt%-%,%)%& %R1,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "cvt%-%,%/ %R1,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
(define_insn "truncdfsf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
"TARGET_FP"
- "cvt%-%,%)%& %R1,%0"
+ "cvt%-%,%/ %R1,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_expand "trunctfdf2"
+ [(use (match_operand:DF 0 "register_operand" ""))
+ (use (match_operand:TF 1 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
+
+(define_expand "trunctfsf2"
+ [(use (match_operand:SF 0 "register_operand" ""))
+ (use (match_operand:TF 1 "general_operand" ""))]
+ "TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
+{
+ rtx tmpf, sticky, arg, lo, hi;
+
+ tmpf = gen_reg_rtx (DFmode);
+ sticky = gen_reg_rtx (DImode);
+ arg = copy_to_mode_reg (TFmode, operands[1]);
+ lo = gen_lowpart (DImode, arg);
+ hi = gen_highpart (DImode, arg);
+
+ /* Convert the low word of the TFmode value into a sticky rounding bit,
+ then or it into the low bit of the high word. This leaves the sticky
+ bit at bit 48 of the fraction, which is representable in DFmode,
+ which prevents rounding error in the final conversion to SFmode. */
+
+ emit_insn (gen_rtx_SET (VOIDmode, sticky,
+ gen_rtx_NE (DImode, lo, const0_rtx)));
+ emit_insn (gen_iordi3 (hi, hi, sticky));
+ emit_insn (gen_trunctfdf2 (tmpf, arg));
+ emit_insn (gen_truncdfsf2 (operands[0], tmpf));
+ DONE;
+})
+
+(define_insn "*divsf3_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
(div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
(match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "div%,%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "div%,%/ %R1,%R2,%0"
[(set_attr "type" "fdiv")
(set_attr "opsize" "si")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
(define_insn "divsf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
(match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
"TARGET_FP"
- "div%,%)%& %R1,%R2,%0"
+ "div%,%/ %R1,%R2,%0"
[(set_attr "type" "fdiv")
(set_attr "opsize" "si")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*divdf3_ieee"
[(set (match_operand:DF 0 "register_operand" "=&f")
(div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "div%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "div%-%/ %R1,%R2,%0"
[(set_attr "type" "fdiv")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
(define_insn "divdf3"
[(set (match_operand:DF 0 "register_operand" "=f")
(div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
"TARGET_FP"
- "div%-%)%& %R1,%R2,%0"
+ "div%-%/ %R1,%R2,%0"
[(set_attr "type" "fdiv")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*divdf_ext1"
[(set (match_operand:DF 0 "register_operand" "=f")
(div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "div%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "div%-%/ %R1,%R2,%0"
[(set_attr "type" "fdiv")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*divdf_ext2"
[(set (match_operand:DF 0 "register_operand" "=f")
(div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
(float_extend:DF
(match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "div%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "div%-%/ %R1,%R2,%0"
[(set_attr "type" "fdiv")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*divdf_ext3"
[(set (match_operand:DF 0 "register_operand" "=f")
(div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
(float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "div%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "div%-%/ %R1,%R2,%0"
[(set_attr "type" "fdiv")
- (set_attr "trap" "yes")])
-
-(define_insn ""
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_expand "divtf3"
+ [(use (match_operand 0 "register_operand" ""))
+ (use (match_operand 1 "general_operand" ""))
+ (use (match_operand 2 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_arith (DIV, operands); DONE;")
+
+(define_insn "*mulsf3_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
(mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
(match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "mul%,%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "mul%,%/ %R1,%R2,%0"
[(set_attr "type" "fmul")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
(define_insn "mulsf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
(match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
"TARGET_FP"
- "mul%,%)%& %R1,%R2,%0"
+ "mul%,%/ %R1,%R2,%0"
[(set_attr "type" "fmul")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*muldf3_ieee"
[(set (match_operand:DF 0 "register_operand" "=&f")
(mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "mul%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "mul%-%/ %R1,%R2,%0"
[(set_attr "type" "fmul")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
(define_insn "muldf3"
[(set (match_operand:DF 0 "register_operand" "=f")
(mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
"TARGET_FP"
- "mul%-%)%& %R1,%R2,%0"
+ "mul%-%/ %R1,%R2,%0"
[(set_attr "type" "fmul")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*muldf_ext1"
[(set (match_operand:DF 0 "register_operand" "=f")
(mult:DF (float_extend:DF
(match_operand:SF 1 "reg_or_fp0_operand" "fG"))
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "mul%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "mul%-%/ %R1,%R2,%0"
[(set_attr "type" "fmul")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*muldf_ext2"
[(set (match_operand:DF 0 "register_operand" "=f")
(mult:DF (float_extend:DF
(match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
(float_extend:DF
(match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "mul%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "mul%-%/ %R1,%R2,%0"
[(set_attr "type" "fmul")
- (set_attr "trap" "yes")])
-
-(define_insn ""
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_expand "multf3"
+ [(use (match_operand 0 "register_operand" ""))
+ (use (match_operand 1 "general_operand" ""))
+ (use (match_operand 2 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_arith (MULT, operands); DONE;")
+
+(define_insn "*subsf3_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
(minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
(match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "sub%,%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "sub%,%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
(define_insn "subsf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
(match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
"TARGET_FP"
- "sub%,%)%& %R1,%R2,%0"
+ "sub%,%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*subdf3_ieee"
[(set (match_operand:DF 0 "register_operand" "=&f")
(minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "sub%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "sub%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
(define_insn "subdf3"
[(set (match_operand:DF 0 "register_operand" "=f")
(minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
"TARGET_FP"
- "sub%-%)%& %R1,%R2,%0"
+ "sub%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*subdf_ext1"
[(set (match_operand:DF 0 "register_operand" "=f")
(minus:DF (float_extend:DF
(match_operand:SF 1 "reg_or_fp0_operand" "fG"))
(match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "sub%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "sub%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*subdf_ext2"
[(set (match_operand:DF 0 "register_operand" "=f")
(minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
(float_extend:DF
(match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "sub%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "sub%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*subdf_ext3"
[(set (match_operand:DF 0 "register_operand" "=f")
(minus:DF (float_extend:DF
(match_operand:SF 1 "reg_or_fp0_operand" "fG"))
(float_extend:DF
(match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "sub%-%)%& %R1,%R2,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "sub%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
-
-(define_insn ""
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_expand "subtf3"
+ [(use (match_operand 0 "register_operand" ""))
+ (use (match_operand 1 "general_operand" ""))
+ (use (match_operand 2 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
+
+(define_insn "*sqrtsf2_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
(sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && TARGET_FIX && alpha_tp == ALPHA_TP_INSN"
- "sqrt%,%)%& %R1,%0"
+ "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
+ "sqrt%,%/ %R1,%0"
[(set_attr "type" "fsqrt")
(set_attr "opsize" "si")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
(define_insn "sqrtsf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
"TARGET_FP && TARGET_FIX"
- "sqrt%,%)%& %R1,%0"
+ "sqrt%,%/ %R1,%0"
[(set_attr "type" "fsqrt")
(set_attr "opsize" "si")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn ""
+(define_insn "*sqrtdf2_ieee"
[(set (match_operand:DF 0 "register_operand" "=&f")
(sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
- "TARGET_FP && TARGET_FIX && alpha_tp == ALPHA_TP_INSN"
- "sqrt%-%)%& %R1,%0"
+ "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
+ "sqrt%-%/ %R1,%0"
[(set_attr "type" "fsqrt")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
(define_insn "sqrtdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
"TARGET_FP && TARGET_FIX"
- "sqrt%-%)%& %1,%0"
+ "sqrt%-%/ %1,%0"
[(set_attr "type" "fsqrt")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
;; Next are all the integer comparisons, and conditional moves and branches
;; and some of the related define_expand's and define_split's.
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (match_operator:DI 1 "alpha_comparison_operator"
- [(match_operand:DI 2 "reg_or_0_operand" "rJ")
+(define_insn "*setcc_internal"
+ [(set (match_operand 0 "register_operand" "=r")
+ (match_operator 1 "alpha_comparison_operator"
+ [(match_operand:DI 2 "register_operand" "r")
(match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
- ""
- "cmp%C1 %r2,%3,%0"
+ "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
+ && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
+ && GET_MODE (operands[0]) == GET_MODE (operands[1])"
+ "cmp%C1 %2,%3,%0"
[(set_attr "type" "icmp")])
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (match_operator:DI 1 "alpha_swapped_comparison_operator"
- [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
+;; Yes, we can technically support reg_or_8bit_operand in operand 2,
+;; but that's non-canonical rtl and allowing that causes inefficiencies
+;; from cse on.
+(define_insn "*setcc_swapped_internal"
+ [(set (match_operand 0 "register_operand" "=r")
+ (match_operator 1 "alpha_swapped_comparison_operator"
+ [(match_operand:DI 2 "register_operand" "r")
(match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
- ""
+ "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
+ && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
+ && GET_MODE (operands[0]) == GET_MODE (operands[1])"
"cmp%c1 %r3,%2,%0"
[(set_attr "type" "icmp")])
-;; This pattern exists so conditional moves of SImode values are handled.
-;; Comparisons are still done in DImode though.
+;; Use match_operator rather than ne directly so that we can match
+;; multiple integer modes.
+(define_insn "*setne_internal"
+ [(set (match_operand 0 "register_operand" "=r")
+ (match_operator 1 "signed_comparison_operator"
+ [(match_operand:DI 2 "register_operand" "r")
+ (const_int 0)]))]
+ "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
+ && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
+ && GET_CODE (operands[1]) == NE
+ && GET_MODE (operands[0]) == GET_MODE (operands[1])"
+ "cmpult $31,%2,%0"
+ [(set_attr "type" "icmp")])
+
+;; The mode folding trick can't be used with const_int operands, since
+;; reload needs to know the proper mode.
+;;
+;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand
+;; in order to create more pairs of constants. As long as we're allowing
+;; two constants at the same time, and will have to reload one of them...
-(define_insn ""
+(define_insn "*movqicc_internal"
+ [(set (match_operand:QI 0 "register_operand" "=r,r,r,r")
+ (if_then_else:QI
+ (match_operator 2 "signed_comparison_operator"
+ [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
+ (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
+ (match_operand:QI 1 "add_operand" "rI,0,rI,0")
+ (match_operand:QI 5 "add_operand" "0,rI,0,rI")))]
+ "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
+ "@
+ cmov%C2 %r3,%1,%0
+ cmov%D2 %r3,%5,%0
+ cmov%c2 %r4,%1,%0
+ cmov%d2 %r4,%5,%0"
+ [(set_attr "type" "icmov")])
+
+(define_insn "*movhicc_internal"
+ [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
+ (if_then_else:HI
+ (match_operator 2 "signed_comparison_operator"
+ [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
+ (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
+ (match_operand:HI 1 "add_operand" "rI,0,rI,0")
+ (match_operand:HI 5 "add_operand" "0,rI,0,rI")))]
+ "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
+ "@
+ cmov%C2 %r3,%1,%0
+ cmov%D2 %r3,%5,%0
+ cmov%c2 %r4,%1,%0
+ cmov%d2 %r4,%5,%0"
+ [(set_attr "type" "icmov")])
+
+(define_insn "*movsicc_internal"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(if_then_else:SI
(match_operator 2 "signed_comparison_operator"
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
- (match_operand:SI 1 "reg_or_8bit_operand" "rI,0,rI,0")
- (match_operand:SI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
- "operands[3] == const0_rtx || operands[4] == const0_rtx"
+ (match_operand:SI 1 "add_operand" "rI,0,rI,0")
+ (match_operand:SI 5 "add_operand" "0,rI,0,rI")))]
+ "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
"@
cmov%C2 %r3,%1,%0
cmov%D2 %r3,%5,%0
@@ -2379,15 +3207,15 @@
cmov%d2 %r4,%5,%0"
[(set_attr "type" "icmov")])
-(define_insn ""
+(define_insn "*movdicc_internal"
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
(if_then_else:DI
(match_operator 2 "signed_comparison_operator"
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
- (match_operand:DI 1 "reg_or_8bit_operand" "rI,0,rI,0")
- (match_operand:DI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
- "operands[3] == const0_rtx || operands[4] == const0_rtx"
+ (match_operand:DI 1 "add_operand" "rI,0,rI,0")
+ (match_operand:DI 5 "add_operand" "0,rI,0,rI")))]
+ "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
"@
cmov%C2 %r3,%1,%0
cmov%D2 %r3,%5,%0
@@ -2395,7 +3223,52 @@
cmov%d2 %r4,%5,%0"
[(set_attr "type" "icmov")])
-(define_insn ""
+(define_insn "*movqicc_lbc"
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (if_then_else:QI
+ (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
+ (const_int 1)
+ (const_int 0))
+ (const_int 0))
+ (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
+ (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
+ ""
+ "@
+ cmovlbc %r2,%1,%0
+ cmovlbs %r2,%3,%0"
+ [(set_attr "type" "icmov")])
+
+(define_insn "*movhicc_lbc"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (if_then_else:HI
+ (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
+ (const_int 1)
+ (const_int 0))
+ (const_int 0))
+ (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
+ (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
+ ""
+ "@
+ cmovlbc %r2,%1,%0
+ cmovlbs %r2,%3,%0"
+ [(set_attr "type" "icmov")])
+
+(define_insn "*movsicc_lbc"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (if_then_else:SI
+ (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
+ (const_int 1)
+ (const_int 0))
+ (const_int 0))
+ (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
+ (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
+ ""
+ "@
+ cmovlbc %r2,%1,%0
+ cmovlbs %r2,%3,%0"
+ [(set_attr "type" "icmov")])
+
+(define_insn "*movdicc_lbc"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(if_then_else:DI
(eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
@@ -2410,7 +3283,52 @@
cmovlbs %r2,%3,%0"
[(set_attr "type" "icmov")])
-(define_insn ""
+(define_insn "*movqicc_lbs"
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (if_then_else:QI
+ (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
+ (const_int 1)
+ (const_int 0))
+ (const_int 0))
+ (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
+ (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
+ ""
+ "@
+ cmovlbs %r2,%1,%0
+ cmovlbc %r2,%3,%0"
+ [(set_attr "type" "icmov")])
+
+(define_insn "*movhicc_lbs"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (if_then_else:HI
+ (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
+ (const_int 1)
+ (const_int 0))
+ (const_int 0))
+ (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
+ (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
+ ""
+ "@
+ cmovlbs %r2,%1,%0
+ cmovlbc %r2,%3,%0"
+ [(set_attr "type" "icmov")])
+
+(define_insn "*movsicc_lbs"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (if_then_else:SI
+ (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
+ (const_int 1)
+ (const_int 0))
+ (const_int 0))
+ (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
+ (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
+ ""
+ "@
+ cmovlbs %r2,%1,%0
+ cmovlbc %r2,%3,%0"
+ [(set_attr "type" "icmov")])
+
+(define_insn "*movdicc_lbs"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(if_then_else:DI
(ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
@@ -2431,14 +3349,13 @@
[(set (match_operand:DI 0 "register_operand" "")
(abs:DI (match_operand:DI 1 "register_operand" "")))]
""
- "
-{ if (rtx_equal_p (operands[0], operands[1]))
+{
+ if (rtx_equal_p (operands[0], operands[1]))
emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
else
emit_insn (gen_absdi2_diff (operands[0], operands[1]));
-
DONE;
-}")
+})
(define_expand "absdi2_same"
[(set (match_operand:DI 1 "register_operand" "")
@@ -2463,7 +3380,7 @@
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(abs:DI (match_dup 0)))
- (clobber (match_operand:DI 2 "register_operand" ""))]
+ (clobber (match_operand:DI 1 "register_operand" ""))]
""
[(set (match_dup 1) (neg:DI (match_dup 0)))
(set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
@@ -2482,7 +3399,7 @@
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(neg:DI (abs:DI (match_dup 0))))
- (clobber (match_operand:DI 2 "register_operand" ""))]
+ (clobber (match_operand:DI 1 "register_operand" ""))]
""
[(set (match_dup 1) (neg:DI (match_dup 0)))
(set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
@@ -2570,9 +3487,7 @@
(if_then_else:DI (eq (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
- "
-{ operands[3] = gen_reg_rtx (DImode);
-}")
+ { operands[3] = gen_reg_rtx (DImode); })
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -2585,7 +3500,7 @@
(match_dup 1) (match_dup 2)))]
"")
-(define_insn ""
+(define_insn "*smax_const0"
[(set (match_operand:DI 0 "register_operand" "=r")
(smax:DI (match_operand:DI 1 "register_operand" "0")
(const_int 0)))]
@@ -2601,9 +3516,7 @@
(if_then_else:DI (ne (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
- "
-{ operands[3] = gen_reg_rtx (DImode);
-}")
+ { operands[3] = gen_reg_rtx (DImode); })
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -2616,7 +3529,7 @@
(match_dup 1) (match_dup 2)))]
"")
-(define_insn ""
+(define_insn "*smin_const0"
[(set (match_operand:DI 0 "register_operand" "=r")
(smin:DI (match_operand:DI 1 "register_operand" "0")
(const_int 0)))]
@@ -2625,16 +3538,14 @@
[(set_attr "type" "icmov")])
(define_expand "umaxdi3"
- [(set (match_dup 3)
+ [(set (match_dup 3)
(leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")))
(set (match_operand:DI 0 "register_operand" "")
(if_then_else:DI (eq (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
- "
-{ operands[3] = gen_reg_rtx (DImode);
-}")
+ "operands[3] = gen_reg_rtx (DImode);")
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -2655,9 +3566,7 @@
(if_then_else:DI (ne (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
- "
-{ operands[3] = gen_reg_rtx (DImode);
-}")
+ "operands[3] = gen_reg_rtx (DImode);")
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -2670,7 +3579,7 @@
(match_dup 1) (match_dup 2)))]
"")
-(define_insn ""
+(define_insn "*bcc_normal"
[(set (pc)
(if_then_else
(match_operator 1 "signed_comparison_operator"
@@ -2682,19 +3591,20 @@
"b%C1 %r2,%0"
[(set_attr "type" "ibr")])
-(define_insn ""
+(define_insn "*bcc_reverse"
[(set (pc)
(if_then_else
(match_operator 1 "signed_comparison_operator"
- [(const_int 0)
- (match_operand:DI 2 "register_operand" "r")])
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+ [(match_operand:DI 2 "register_operand" "r")
+ (const_int 0)])
+
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
""
"b%c1 %2,%0"
[(set_attr "type" "ibr")])
-(define_insn ""
+(define_insn "*blbs_normal"
[(set (pc)
(if_then_else
(ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
@@ -2707,7 +3617,7 @@
"blbs %r1,%0"
[(set_attr "type" "ibr")])
-(define_insn ""
+(define_insn "*blbc_normal"
[(set (pc)
(if_then_else
(eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
@@ -2746,100 +3656,108 @@
"")
;; The following are the corresponding floating-point insns. Recall
-;; we need to have variants that expand the arguments from SF mode
+;; we need to have variants that expand the arguments from SFmode
;; to DFmode.
-(define_insn ""
+(define_insn "*cmpdf_ieee"
[(set (match_operand:DF 0 "register_operand" "=&f")
- (match_operator:DF 1 "alpha_comparison_operator"
+ (match_operator:DF 1 "alpha_fp_comparison_operator"
[(match_operand:DF 2 "reg_or_fp0_operand" "fG")
(match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "cmp%-%C1%' %R2,%R3,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "cmp%-%C1%/ %R2,%R3,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "trap_suffix" "su")])
-(define_insn ""
+(define_insn "*cmpdf_internal"
[(set (match_operand:DF 0 "register_operand" "=f")
- (match_operator:DF 1 "alpha_comparison_operator"
+ (match_operator:DF 1 "alpha_fp_comparison_operator"
[(match_operand:DF 2 "reg_or_fp0_operand" "fG")
(match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "cmp%-%C1%' %R2,%R3,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "cmp%-%C1%/ %R2,%R3,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "trap_suffix" "su")])
-(define_insn ""
+(define_insn "*cmpdf_ieee_ext1"
[(set (match_operand:DF 0 "register_operand" "=&f")
- (match_operator:DF 1 "alpha_comparison_operator"
+ (match_operator:DF 1 "alpha_fp_comparison_operator"
[(float_extend:DF
(match_operand:SF 2 "reg_or_fp0_operand" "fG"))
(match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "cmp%-%C1%' %R2,%R3,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "cmp%-%C1%/ %R2,%R3,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "trap_suffix" "su")])
-(define_insn ""
+(define_insn "*cmpdf_ext1"
[(set (match_operand:DF 0 "register_operand" "=f")
- (match_operator:DF 1 "alpha_comparison_operator"
+ (match_operator:DF 1 "alpha_fp_comparison_operator"
[(float_extend:DF
(match_operand:SF 2 "reg_or_fp0_operand" "fG"))
(match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "cmp%-%C1%' %R2,%R3,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "cmp%-%C1%/ %R2,%R3,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "trap_suffix" "su")])
-(define_insn ""
+(define_insn "*cmpdf_ieee_ext2"
[(set (match_operand:DF 0 "register_operand" "=&f")
- (match_operator:DF 1 "alpha_comparison_operator"
+ (match_operator:DF 1 "alpha_fp_comparison_operator"
[(match_operand:DF 2 "reg_or_fp0_operand" "fG")
(float_extend:DF
(match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "cmp%-%C1%' %R2,%R3,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "cmp%-%C1%/ %R2,%R3,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "trap_suffix" "su")])
-(define_insn ""
+(define_insn "*cmpdf_ext2"
[(set (match_operand:DF 0 "register_operand" "=f")
- (match_operator:DF 1 "alpha_comparison_operator"
+ (match_operator:DF 1 "alpha_fp_comparison_operator"
[(match_operand:DF 2 "reg_or_fp0_operand" "fG")
(float_extend:DF
(match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "cmp%-%C1%' %R2,%R3,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "cmp%-%C1%/ %R2,%R3,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "trap_suffix" "su")])
-(define_insn ""
+(define_insn "*cmpdf_ieee_ext3"
[(set (match_operand:DF 0 "register_operand" "=&f")
- (match_operator:DF 1 "alpha_comparison_operator"
+ (match_operator:DF 1 "alpha_fp_comparison_operator"
[(float_extend:DF
(match_operand:SF 2 "reg_or_fp0_operand" "fG"))
(float_extend:DF
(match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
- "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
- "cmp%-%C1%' %R2,%R3,%0"
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "cmp%-%C1%/ %R2,%R3,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "trap_suffix" "su")])
-(define_insn ""
+(define_insn "*cmpdf_ext3"
[(set (match_operand:DF 0 "register_operand" "=f")
- (match_operator:DF 1 "alpha_comparison_operator"
+ (match_operator:DF 1 "alpha_fp_comparison_operator"
[(float_extend:DF
(match_operand:SF 2 "reg_or_fp0_operand" "fG"))
(float_extend:DF
(match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
- "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
- "cmp%-%C1%' %R2,%R3,%0"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "cmp%-%C1%/ %R2,%R3,%0"
[(set_attr "type" "fadd")
- (set_attr "trap" "yes")])
+ (set_attr "trap" "yes")
+ (set_attr "trap_suffix" "su")])
-(define_insn ""
+(define_insn "*movdfcc_internal"
[(set (match_operand:DF 0 "register_operand" "=f,f")
- (if_then_else:DF
+ (if_then_else:DF
(match_operator 3 "signed_comparison_operator"
[(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
(match_operand:DF 2 "fp0_operand" "G,G")])
@@ -2851,9 +3769,9 @@
fcmov%D3 %R4,%R5,%0"
[(set_attr "type" "fcmov")])
-(define_insn ""
+(define_insn "*movsfcc_internal"
[(set (match_operand:SF 0 "register_operand" "=f,f")
- (if_then_else:SF
+ (if_then_else:SF
(match_operator 3 "signed_comparison_operator"
[(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
(match_operand:DF 2 "fp0_operand" "G,G")])
@@ -2865,9 +3783,9 @@
fcmov%D3 %R4,%R5,%0"
[(set_attr "type" "fcmov")])
-(define_insn ""
+(define_insn "*movdfcc_ext1"
[(set (match_operand:DF 0 "register_operand" "=f,f")
- (if_then_else:DF
+ (if_then_else:DF
(match_operator 3 "signed_comparison_operator"
[(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
(match_operand:DF 2 "fp0_operand" "G,G")])
@@ -2879,11 +3797,11 @@
fcmov%D3 %R4,%R5,%0"
[(set_attr "type" "fcmov")])
-(define_insn ""
+(define_insn "*movdfcc_ext2"
[(set (match_operand:DF 0 "register_operand" "=f,f")
- (if_then_else:DF
+ (if_then_else:DF
(match_operator 3 "signed_comparison_operator"
- [(float_extend:DF
+ [(float_extend:DF
(match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
(match_operand:DF 2 "fp0_operand" "G,G")])
(match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
@@ -2894,9 +3812,9 @@
fcmov%D3 %R4,%R5,%0"
[(set_attr "type" "fcmov")])
-(define_insn ""
+(define_insn "*movdfcc_ext3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
- (if_then_else:SF
+ (if_then_else:SF
(match_operator 3 "signed_comparison_operator"
[(float_extend:DF
(match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
@@ -2909,9 +3827,9 @@
fcmov%D3 %R4,%R5,%0"
[(set_attr "type" "fcmov")])
-(define_insn ""
+(define_insn "*movdfcc_ext4"
[(set (match_operand:DF 0 "register_operand" "=f,f")
- (if_then_else:DF
+ (if_then_else:DF
(match_operator 3 "signed_comparison_operator"
[(float_extend:DF
(match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
@@ -2932,10 +3850,10 @@
(if_then_else:DF (eq (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP"
- "
-{ operands[3] = gen_reg_rtx (DFmode);
+{
+ operands[3] = gen_reg_rtx (DFmode);
operands[4] = CONST0_RTX (DFmode);
-}")
+})
(define_expand "mindf3"
[(set (match_dup 3)
@@ -2945,10 +3863,10 @@
(if_then_else:DF (ne (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP"
- "
-{ operands[3] = gen_reg_rtx (DFmode);
+{
+ operands[3] = gen_reg_rtx (DFmode);
operands[4] = CONST0_RTX (DFmode);
-}")
+})
(define_expand "maxsf3"
[(set (match_dup 3)
@@ -2958,10 +3876,10 @@
(if_then_else:SF (eq (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP"
- "
-{ operands[3] = gen_reg_rtx (DFmode);
+{
+ operands[3] = gen_reg_rtx (DFmode);
operands[4] = CONST0_RTX (DFmode);
-}")
+})
(define_expand "minsf3"
[(set (match_dup 3)
@@ -2971,12 +3889,12 @@
(if_then_else:SF (ne (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP"
- "
-{ operands[3] = gen_reg_rtx (DFmode);
+{
+ operands[3] = gen_reg_rtx (DFmode);
operands[4] = CONST0_RTX (DFmode);
-}")
+})
-(define_insn ""
+(define_insn "*fbcc_normal"
[(set (pc)
(if_then_else
(match_operator 1 "signed_comparison_operator"
@@ -2988,7 +3906,7 @@
"fb%C1 %R2,%0"
[(set_attr "type" "fbr")])
-(define_insn ""
+(define_insn "*fbcc_ext_normal"
[(set (pc)
(if_then_else
(match_operator 1 "signed_comparison_operator"
@@ -3008,25 +3926,34 @@
[(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
(match_operand:DF 1 "reg_or_fp0_operand" "")))]
"TARGET_FP"
- "
{
- alpha_compare_op0 = operands[0];
- alpha_compare_op1 = operands[1];
- alpha_compare_fp_p = 1;
+ alpha_compare.op0 = operands[0];
+ alpha_compare.op1 = operands[1];
+ alpha_compare.fp_p = 1;
DONE;
-}")
+})
+
+(define_expand "cmptf"
+ [(set (cc0) (compare (match_operand:TF 0 "general_operand" "")
+ (match_operand:TF 1 "general_operand" "")))]
+ "TARGET_HAS_XFLOATING_LIBS"
+{
+ alpha_compare.op0 = operands[0];
+ alpha_compare.op1 = operands[1];
+ alpha_compare.fp_p = 1;
+ DONE;
+})
(define_expand "cmpdi"
- [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "")
- (match_operand:DI 1 "reg_or_8bit_operand" "")))]
+ [(set (cc0) (compare (match_operand:DI 0 "general_operand" "")
+ (match_operand:DI 1 "general_operand" "")))]
""
- "
{
- alpha_compare_op0 = operands[0];
- alpha_compare_op1 = operands[1];
- alpha_compare_fp_p = 0;
+ alpha_compare.op0 = operands[0];
+ alpha_compare.op1 = operands[1];
+ alpha_compare.fp_p = 0;
DONE;
-}")
+})
(define_expand "beq"
[(set (pc)
@@ -3108,130 +4035,93 @@
""
"{ operands[1] = alpha_emit_conditional_branch (GEU); }")
+(define_expand "bunordered"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = alpha_emit_conditional_branch (UNORDERED); }")
+
+(define_expand "bordered"
+ [(set (pc)
+ (if_then_else (match_dup 1)
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = alpha_emit_conditional_branch (ORDERED); }")
+
(define_expand "seq"
[(set (match_operand:DI 0 "register_operand" "")
(match_dup 1))]
""
- "
-{
- if (alpha_compare_fp_p)
- FAIL;
-
- operands[1] = gen_rtx_EQ (DImode, alpha_compare_op0, alpha_compare_op1);
-}")
+ "{ if ((operands[1] = alpha_emit_setcc (EQ)) == NULL_RTX) FAIL; }")
(define_expand "sne"
[(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))
- (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))]
+ (match_dup 1))]
""
- "
-{
- if (alpha_compare_fp_p)
- FAIL;
-
- operands[1] = gen_rtx_EQ (DImode, alpha_compare_op0, alpha_compare_op1);
-}")
+ "{ if ((operands[1] = alpha_emit_setcc (NE)) == NULL_RTX) FAIL; }")
(define_expand "slt"
[(set (match_operand:DI 0 "register_operand" "")
(match_dup 1))]
""
- "
-{
- if (alpha_compare_fp_p)
- FAIL;
-
- operands[1] = gen_rtx_LT (DImode, alpha_compare_op0, alpha_compare_op1);
-}")
+ "{ if ((operands[1] = alpha_emit_setcc (LT)) == NULL_RTX) FAIL; }")
(define_expand "sle"
[(set (match_operand:DI 0 "register_operand" "")
(match_dup 1))]
""
- "
-{
- if (alpha_compare_fp_p)
- FAIL;
-
- operands[1] = gen_rtx_LE (DImode, alpha_compare_op0, alpha_compare_op1);
-}")
+ "{ if ((operands[1] = alpha_emit_setcc (LE)) == NULL_RTX) FAIL; }")
(define_expand "sgt"
[(set (match_operand:DI 0 "register_operand" "")
(match_dup 1))]
""
- "
-{
- if (alpha_compare_fp_p)
- FAIL;
-
- operands[1] = gen_rtx_LT (DImode, force_reg (DImode, alpha_compare_op1),
- alpha_compare_op0);
-}")
+ "{ if ((operands[1] = alpha_emit_setcc (GT)) == NULL_RTX) FAIL; }")
(define_expand "sge"
[(set (match_operand:DI 0 "register_operand" "")
(match_dup 1))]
""
- "
-{
- if (alpha_compare_fp_p)
- FAIL;
-
- operands[1] = gen_rtx_LE (DImode, force_reg (DImode, alpha_compare_op1),
- alpha_compare_op0);
-}")
+ "{ if ((operands[1] = alpha_emit_setcc (GE)) == NULL_RTX) FAIL; }")
(define_expand "sltu"
[(set (match_operand:DI 0 "register_operand" "")
(match_dup 1))]
""
- "
-{
- if (alpha_compare_fp_p)
- FAIL;
-
- operands[1] = gen_rtx_LTU (DImode, alpha_compare_op0, alpha_compare_op1);
-}")
+ "{ if ((operands[1] = alpha_emit_setcc (LTU)) == NULL_RTX) FAIL; }")
(define_expand "sleu"
[(set (match_operand:DI 0 "register_operand" "")
(match_dup 1))]
""
- "
-{
- if (alpha_compare_fp_p)
- FAIL;
-
- operands[1] = gen_rtx_LEU (DImode, alpha_compare_op0, alpha_compare_op1);
-}")
+ "{ if ((operands[1] = alpha_emit_setcc (LEU)) == NULL_RTX) FAIL; }")
(define_expand "sgtu"
[(set (match_operand:DI 0 "register_operand" "")
(match_dup 1))]
""
- "
-{
- if (alpha_compare_fp_p)
- FAIL;
-
- operands[1] = gen_rtx_LTU (DImode, force_reg (DImode, alpha_compare_op1),
- alpha_compare_op0);
-}")
+ "{ if ((operands[1] = alpha_emit_setcc (GTU)) == NULL_RTX) FAIL; }")
(define_expand "sgeu"
[(set (match_operand:DI 0 "register_operand" "")
(match_dup 1))]
""
- "
-{
- if (alpha_compare_fp_p)
- FAIL;
+ "{ if ((operands[1] = alpha_emit_setcc (GEU)) == NULL_RTX) FAIL; }")
- operands[1] = gen_rtx_LEU (DImode, force_reg (DImode, alpha_compare_op1),
- alpha_compare_op0);
-}")
+(define_expand "sunordered"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_dup 1))]
+ ""
+ "{ if ((operands[1] = alpha_emit_setcc (UNORDERED)) == NULL_RTX) FAIL; }")
+
+(define_expand "sordered"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_dup 1))]
+ ""
+ "{ if ((operands[1] = alpha_emit_setcc (ORDERED)) == NULL_RTX) FAIL; }")
;; These are the main define_expand's used to make conditional moves.
@@ -3241,11 +4131,10 @@
(match_operand:SI 2 "reg_or_8bit_operand" "")
(match_operand:SI 3 "reg_or_8bit_operand" "")))]
""
- "
{
if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
FAIL;
-}")
+})
(define_expand "movdicc"
[(set (match_operand:DI 0 "register_operand" "")
@@ -3253,11 +4142,10 @@
(match_operand:DI 2 "reg_or_8bit_operand" "")
(match_operand:DI 3 "reg_or_8bit_operand" "")))]
""
- "
{
if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
FAIL;
-}")
+})
(define_expand "movsfcc"
[(set (match_operand:SF 0 "register_operand" "")
@@ -3265,11 +4153,10 @@
(match_operand:SF 2 "reg_or_8bit_operand" "")
(match_operand:SF 3 "reg_or_8bit_operand" "")))]
""
- "
{
if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
FAIL;
-}")
+})
(define_expand "movdfcc"
[(set (match_operand:DF 0 "register_operand" "")
@@ -3277,11 +4164,10 @@
(match_operand:DF 2 "reg_or_8bit_operand" "")
(match_operand:DF 3 "reg_or_8bit_operand" "")))]
""
- "
{
if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
FAIL;
-}")
+})
;; These define_split definitions are used in cases when comparisons have
;; not be stated in the correct way and we need to reverse the second
@@ -3313,8 +4199,8 @@
[(set (match_dup 6) (match_dup 7))
(set (match_dup 0)
(if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
- "
-{ enum rtx_code code = GET_CODE (operands[1]);
+{
+ enum rtx_code code = GET_CODE (operands[1]);
int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
/* If we are comparing for equality with a constant and that constant
@@ -3355,7 +4241,7 @@
operands[2], operands[3]);
operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
}
-}")
+})
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -3371,8 +4257,8 @@
[(set (match_dup 6) (match_dup 7))
(set (match_dup 0)
(if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
- "
-{ enum rtx_code code = GET_CODE (operands[1]);
+{
+ enum rtx_code code = GET_CODE (operands[1]);
int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
rtx tem;
@@ -3380,7 +4266,7 @@
&& ! (extended_count (operands[2], DImode, unsignedp) >= 1
&& extended_count (operands[3], DImode, unsignedp) >= 1)))
FAIL;
-
+
if (GET_CODE (operands[3]) == CONST_INT)
tem = gen_rtx_PLUS (SImode, operands[2],
GEN_INT (- INTVAL (operands[3])));
@@ -3390,7 +4276,7 @@
operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
operands[6], const0_rtx);
-}")
+})
(define_split
[(set (pc)
@@ -3404,8 +4290,8 @@
"operands[3] != const0_rtx"
[(set (match_dup 4) (match_dup 5))
(set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
- "
-{ enum rtx_code code = GET_CODE (operands[1]);
+{
+ enum rtx_code code = GET_CODE (operands[1]);
int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
if (code == NE || code == EQ
@@ -3433,7 +4319,7 @@
operands[2], operands[3]);
operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
}
-}")
+})
(define_split
[(set (pc)
@@ -3448,26 +4334,26 @@
&& (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
[(set (match_dup 4) (match_dup 5))
(set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
- "
-{ rtx tem;
+{
+ rtx tem;
if (GET_CODE (operands[3]) == CONST_INT)
tem = gen_rtx_PLUS (SImode, operands[2],
GEN_INT (- INTVAL (operands[3])));
else
tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
-
+
operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
operands[4], const0_rtx);
-}")
+})
;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
;; This eliminates one, and sometimes two, insns when the AND can be done
;; with a ZAP.
(define_split
[(set (match_operand:DI 0 "register_operand" "")
- (match_operator 1 "comparison_operator"
+ (match_operator:DI 1 "comparison_operator"
[(match_operand:DI 2 "register_operand" "")
(match_operand:DI 3 "const_int_operand" "")]))
(clobber (match_operand:DI 4 "register_operand" ""))]
@@ -3478,69 +4364,299 @@
&& extended_count (operands[2], DImode, 1) > 0))"
[(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
(set (match_dup 0) (match_dup 6))]
- "
{
operands[5] = GEN_INT (~ INTVAL (operands[3]));
operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
|| GET_CODE (operands[1]) == GT)
? NE : EQ),
DImode, operands[4], const0_rtx);
-}")
+})
+
+;; Prefer to use cmp and arithmetic when possible instead of a cmove.
+
+(define_split
+ [(set (match_operand 0 "register_operand" "")
+ (if_then_else (match_operator 1 "signed_comparison_operator"
+ [(match_operand:DI 2 "reg_or_0_operand" "")
+ (const_int 0)])
+ (match_operand 3 "const_int_operand" "")
+ (match_operand 4 "const_int_operand" "")))]
+ ""
+ [(const_int 0)]
+{
+ if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0],
+ operands[2], operands[3], operands[4]))
+ DONE;
+ else
+ FAIL;
+})
+
+;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
+;; Oh well, we match it in movcc, so it must be partially our fault.
+(define_split
+ [(set (match_operand 0 "register_operand" "")
+ (if_then_else (match_operator 1 "signed_comparison_operator"
+ [(const_int 0)
+ (match_operand:DI 2 "reg_or_0_operand" "")])
+ (match_operand 3 "const_int_operand" "")
+ (match_operand 4 "const_int_operand" "")))]
+ ""
+ [(const_int 0)]
+{
+ if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])),
+ operands[0], operands[2], operands[3],
+ operands[4]))
+ DONE;
+ else
+ FAIL;
+})
+
+(define_insn_and_split "*cmp_sadd_di"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (if_then_else:DI
+ (match_operator 1 "alpha_zero_comparison_operator"
+ [(match_operand:DI 2 "reg_or_0_operand" "rJ")
+ (const_int 0)])
+ (match_operand:DI 3 "const48_operand" "I")
+ (const_int 0))
+ (match_operand:DI 4 "sext_add_operand" "rIO")))
+ (clobber (match_scratch:DI 5 "=r"))]
+ ""
+ "#"
+ "! no_new_pseudos || reload_completed"
+ [(set (match_dup 5)
+ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
+ (set (match_dup 0)
+ (plus:DI (mult:DI (match_dup 5) (match_dup 3))
+ (match_dup 4)))]
+{
+ if (! no_new_pseudos)
+ operands[5] = gen_reg_rtx (DImode);
+ else if (reg_overlap_mentioned_p (operands[5], operands[4]))
+ operands[5] = operands[0];
+})
+
+(define_insn_and_split "*cmp_sadd_si"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (if_then_else:SI
+ (match_operator 1 "alpha_zero_comparison_operator"
+ [(match_operand:DI 2 "reg_or_0_operand" "rJ")
+ (const_int 0)])
+ (match_operand:SI 3 "const48_operand" "I")
+ (const_int 0))
+ (match_operand:SI 4 "sext_add_operand" "rIO")))
+ (clobber (match_scratch:SI 5 "=r"))]
+ ""
+ "#"
+ "! no_new_pseudos || reload_completed"
+ [(set (match_dup 5)
+ (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+ (set (match_dup 0)
+ (plus:SI (mult:SI (match_dup 5) (match_dup 3))
+ (match_dup 4)))]
+{
+ if (! no_new_pseudos)
+ operands[5] = gen_reg_rtx (DImode);
+ else if (reg_overlap_mentioned_p (operands[5], operands[4]))
+ operands[5] = operands[0];
+})
+
+(define_insn_and_split "*cmp_sadd_sidi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (plus:SI (if_then_else:SI
+ (match_operator 1 "alpha_zero_comparison_operator"
+ [(match_operand:DI 2 "reg_or_0_operand" "rJ")
+ (const_int 0)])
+ (match_operand:SI 3 "const48_operand" "I")
+ (const_int 0))
+ (match_operand:SI 4 "sext_add_operand" "rIO"))))
+ (clobber (match_scratch:SI 5 "=r"))]
+ ""
+ "#"
+ "! no_new_pseudos || reload_completed"
+ [(set (match_dup 5)
+ (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+ (set (match_dup 0)
+ (sign_extend:DI (plus:SI (mult:SI (match_dup 5) (match_dup 3))
+ (match_dup 4))))]
+{
+ if (! no_new_pseudos)
+ operands[5] = gen_reg_rtx (DImode);
+ else if (reg_overlap_mentioned_p (operands[5], operands[4]))
+ operands[5] = operands[0];
+})
+
+(define_insn_and_split "*cmp_ssub_di"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:DI (if_then_else:DI
+ (match_operator 1 "alpha_zero_comparison_operator"
+ [(match_operand:DI 2 "reg_or_0_operand" "rJ")
+ (const_int 0)])
+ (match_operand:DI 3 "const48_operand" "I")
+ (const_int 0))
+ (match_operand:DI 4 "reg_or_8bit_operand" "rI")))
+ (clobber (match_scratch:DI 5 "=r"))]
+ ""
+ "#"
+ "! no_new_pseudos || reload_completed"
+ [(set (match_dup 5)
+ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
+ (set (match_dup 0)
+ (minus:DI (mult:DI (match_dup 5) (match_dup 3))
+ (match_dup 4)))]
+{
+ if (! no_new_pseudos)
+ operands[5] = gen_reg_rtx (DImode);
+ else if (reg_overlap_mentioned_p (operands[5], operands[4]))
+ operands[5] = operands[0];
+})
+
+(define_insn_and_split "*cmp_ssub_si"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI (if_then_else:SI
+ (match_operator 1 "alpha_zero_comparison_operator"
+ [(match_operand:DI 2 "reg_or_0_operand" "rJ")
+ (const_int 0)])
+ (match_operand:SI 3 "const48_operand" "I")
+ (const_int 0))
+ (match_operand:SI 4 "reg_or_8bit_operand" "rI")))
+ (clobber (match_scratch:SI 5 "=r"))]
+ ""
+ "#"
+ "! no_new_pseudos || reload_completed"
+ [(set (match_dup 5)
+ (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+ (set (match_dup 0)
+ (minus:SI (mult:SI (match_dup 5) (match_dup 3))
+ (match_dup 4)))]
+{
+ if (! no_new_pseudos)
+ operands[5] = gen_reg_rtx (DImode);
+ else if (reg_overlap_mentioned_p (operands[5], operands[4]))
+ operands[5] = operands[0];
+})
+
+(define_insn_and_split "*cmp_ssub_sidi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (minus:SI (if_then_else:SI
+ (match_operator 1 "alpha_zero_comparison_operator"
+ [(match_operand:DI 2 "reg_or_0_operand" "rJ")
+ (const_int 0)])
+ (match_operand:SI 3 "const48_operand" "I")
+ (const_int 0))
+ (match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
+ (clobber (match_scratch:SI 5 "=r"))]
+ ""
+ "#"
+ "! no_new_pseudos || reload_completed"
+ [(set (match_dup 5)
+ (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+ (set (match_dup 0)
+ (sign_extend:DI (minus:SI (mult:SI (match_dup 5) (match_dup 3))
+ (match_dup 4))))]
+{
+ if (! no_new_pseudos)
+ operands[5] = gen_reg_rtx (DImode);
+ else if (reg_overlap_mentioned_p (operands[5], operands[4]))
+ operands[5] = operands[0];
+})
;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
;; work differently, so we have different patterns for each.
+;; On Unicos/Mk a call information word (CIW) must be generated for each
+;; call. The CIW contains information about arguments passed in registers
+;; and is stored in the caller's SSIB. Its offset relative to the beginning
+;; of the SSIB is passed in $25. Handling this properly is quite complicated
+;; in the presence of inlining since the CIWs for calls performed by the
+;; inlined function must be stored in the SSIB of the function it is inlined
+;; into as well. We encode the CIW in an unspec and append it to the list
+;; of the CIWs for the current function only when the instruction for loading
+;; $25 is generated.
+
(define_expand "call"
[(use (match_operand:DI 0 "" ""))
(use (match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(use (match_operand 3 "" ""))]
""
- "
-{ if (TARGET_WINDOWS_NT)
+{
+ if (TARGET_ABI_WINDOWS_NT)
emit_call_insn (gen_call_nt (operands[0], operands[1]));
- else if (TARGET_OPEN_VMS)
+ else if (TARGET_ABI_OPEN_VMS)
emit_call_insn (gen_call_vms (operands[0], operands[2]));
+ else if (TARGET_ABI_UNICOSMK)
+ emit_call_insn (gen_call_umk (operands[0], operands[2]));
else
emit_call_insn (gen_call_osf (operands[0], operands[1]));
-
DONE;
-}")
+})
+
+(define_expand "sibcall"
+ [(parallel [(call (mem:DI (match_operand 0 "" ""))
+ (match_operand 1 "" ""))
+ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
+ "TARGET_ABI_OSF"
+{
+ if (GET_CODE (operands[0]) != MEM)
+ abort ();
+ operands[0] = XEXP (operands[0], 0);
+})
(define_expand "call_osf"
[(parallel [(call (mem:DI (match_operand 0 "" ""))
(match_operand 1 "" ""))
- (clobber (reg:DI 27))
+ (use (reg:DI 29))
(clobber (reg:DI 26))])]
""
- "
-{ if (GET_CODE (operands[0]) != MEM)
+{
+ if (GET_CODE (operands[0]) != MEM)
abort ();
operands[0] = XEXP (operands[0], 0);
-
- if (GET_CODE (operands[0]) != SYMBOL_REF
- && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
- {
- rtx tem = gen_rtx_REG (DImode, 27);
- emit_move_insn (tem, operands[0]);
- operands[0] = tem;
- }
-}")
+ if (! call_operand (operands[0], Pmode))
+ operands[0] = copy_to_mode_reg (Pmode, operands[0]);
+})
(define_expand "call_nt"
[(parallel [(call (mem:DI (match_operand 0 "" ""))
(match_operand 1 "" ""))
(clobber (reg:DI 26))])]
""
- "
-{ if (GET_CODE (operands[0]) != MEM)
+{
+ if (GET_CODE (operands[0]) != MEM)
abort ();
operands[0] = XEXP (operands[0], 0);
if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
operands[0] = force_reg (DImode, operands[0]);
-}")
+})
+
+;; Calls on Unicos/Mk are always indirect.
+;; op 0: symbol ref for called function
+;; op 1: CIW for $25 represented by an unspec
+
+(define_expand "call_umk"
+ [(parallel [(call (mem:DI (match_operand 0 "" ""))
+ (match_operand 1 "" ""))
+ (use (reg:DI 25))
+ (clobber (reg:DI 26))])]
+ ""
+{
+ if (GET_CODE (operands[0]) != MEM)
+ abort ();
+
+ /* Always load the address of the called function into a register;
+ load the CIW in $25. */
+
+ operands[0] = XEXP (operands[0], 0);
+ if (GET_CODE (operands[0]) != REG)
+ operands[0] = force_reg (DImode, operands[0]);
+
+ emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
+})
;;
;; call openvms/alpha
@@ -3555,8 +4671,8 @@
(use (reg:DI 26))
(clobber (reg:DI 27))])]
""
- "
-{ if (GET_CODE (operands[0]) != MEM)
+{
+ if (GET_CODE (operands[0]) != MEM)
abort ();
operands[0] = XEXP (operands[0], 0);
@@ -3568,23 +4684,9 @@
emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
if (GET_CODE (operands[0]) == SYMBOL_REF)
{
- extern char *savealloc ();
- char *linksym, *symbol = XSTR (operands[0], 0);
- rtx linkage;
-
- if (*symbol == '*')
- symbol++;
- linksym = savealloc (strlen (symbol) + 6);
-
- alpha_need_linkage (symbol, 0);
-
- linksym[0] = '$';
- strcpy (linksym+1, symbol);
- strcat (linksym, \"..lk\");
- linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
+ rtx linkage = alpha_need_linkage (XSTR (operands[0], 0), 0);
emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
-
operands[2]
= validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
}
@@ -3592,11 +4694,10 @@
{
emit_move_insn (gen_rtx_REG (Pmode, 26),
gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
-
operands[2] = operands[0];
}
-}")
+})
(define_expand "call_value"
[(use (match_operand 0 "" ""))
@@ -3605,39 +4706,48 @@
(use (match_operand 3 "" ""))
(use (match_operand 4 "" ""))]
""
- "
-{ if (TARGET_WINDOWS_NT)
+{
+ if (TARGET_ABI_WINDOWS_NT)
emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
- else if (TARGET_OPEN_VMS)
+ else if (TARGET_ABI_OPEN_VMS)
emit_call_insn (gen_call_value_vms (operands[0], operands[1],
operands[3]));
+ else if (TARGET_ABI_UNICOSMK)
+ emit_call_insn (gen_call_value_umk (operands[0], operands[1],
+ operands[3]));
else
emit_call_insn (gen_call_value_osf (operands[0], operands[1],
operands[2]));
DONE;
-}")
+})
+
+(define_expand "sibcall_value"
+ [(parallel [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand 1 "" ""))
+ (match_operand 2 "" "")))
+ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
+ "TARGET_ABI_OSF"
+{
+ if (GET_CODE (operands[1]) != MEM)
+ abort ();
+ operands[1] = XEXP (operands[1], 0);
+})
(define_expand "call_value_osf"
[(parallel [(set (match_operand 0 "" "")
(call (mem:DI (match_operand 1 "" ""))
(match_operand 2 "" "")))
- (clobber (reg:DI 27))
+ (use (reg:DI 29))
(clobber (reg:DI 26))])]
""
- "
-{ if (GET_CODE (operands[1]) != MEM)
+{
+ if (GET_CODE (operands[1]) != MEM)
abort ();
operands[1] = XEXP (operands[1], 0);
-
- if (GET_CODE (operands[1]) != SYMBOL_REF
- && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
- {
- rtx tem = gen_rtx_REG (DImode, 27);
- emit_move_insn (tem, operands[1]);
- operands[1] = tem;
- }
-}")
+ if (! call_operand (operands[1], Pmode))
+ operands[1] = copy_to_mode_reg (Pmode, operands[1]);
+})
(define_expand "call_value_nt"
[(parallel [(set (match_operand 0 "" "")
@@ -3645,14 +4755,14 @@
(match_operand 2 "" "")))
(clobber (reg:DI 26))])]
""
- "
-{ if (GET_CODE (operands[1]) != MEM)
+{
+ if (GET_CODE (operands[1]) != MEM)
abort ();
operands[1] = XEXP (operands[1], 0);
if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG)
operands[1] = force_reg (DImode, operands[1]);
-}")
+})
(define_expand "call_value_vms"
[(parallel [(set (match_operand 0 "" "")
@@ -3663,8 +4773,8 @@
(use (reg:DI 26))
(clobber (reg:DI 27))])]
""
- "
-{ if (GET_CODE (operands[1]) != MEM)
+{
+ if (GET_CODE (operands[1]) != MEM)
abort ();
operands[1] = XEXP (operands[1], 0);
@@ -3676,22 +4786,9 @@
emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
if (GET_CODE (operands[1]) == SYMBOL_REF)
{
- extern char *savealloc ();
- char *linksym, *symbol = XSTR (operands[1], 0);
- rtx linkage;
-
- if (*symbol == '*')
- symbol++;
- linksym = savealloc (strlen (symbol) + 6);
-
- alpha_need_linkage (symbol, 0);
- linksym[0] = '$';
- strcpy (linksym+1, symbol);
- strcat (linksym, \"..lk\");
- linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
+ rtx linkage = alpha_need_linkage (XSTR (operands[1], 0), 0);
emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
-
operands[3]
= validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
}
@@ -3699,92 +4796,208 @@
{
emit_move_insn (gen_rtx_REG (Pmode, 26),
gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
-
operands[3] = operands[1];
}
-}")
+})
+
+(define_expand "call_value_umk"
+ [(parallel [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand 1 "" ""))
+ (match_operand 2 "" "")))
+ (use (reg:DI 25))
+ (clobber (reg:DI 26))])]
+ ""
+{
+ if (GET_CODE (operands[1]) != MEM)
+ abort ();
+
+ operands[1] = XEXP (operands[1], 0);
+ if (GET_CODE (operands[1]) != REG)
+ operands[1] = force_reg (DImode, operands[1]);
-(define_insn ""
- [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
+ emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
+})
+
+(define_insn "*call_osf_1_er"
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
(match_operand 1 "" ""))
- (clobber (reg:DI 27))
+ (use (reg:DI 29))
(clobber (reg:DI 26))]
- "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
- jsr $26,($27),0\;ldgp $29,0($26)
+ jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
bsr $26,$%0..ng
- jsr $26,%0\;ldgp $29,0($26)"
+ ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
[(set_attr "type" "jsr")
(set_attr "length" "12,*,16")])
-
-(define_insn ""
- [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
+
+;; We must use peep2 instead of a split because we need accurate life
+;; information for $gp. Consider the case of { bar(); while (1); }.
+(define_peephole2
+ [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
+ (match_operand 1 "" ""))
+ (use (reg:DI 29))
+ (clobber (reg:DI 26))])]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
+ && ! current_file_function_operand (operands[0], Pmode)
+ && peep2_regno_dead_p (1, 29)"
+ [(parallel [(call (mem:DI (match_dup 2))
+ (match_dup 1))
+ (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
+ (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (use (match_dup 0))
+ (use (match_dup 3))])]
+{
+ if (CONSTANT_P (operands[0]))
+ {
+ operands[2] = gen_rtx_REG (Pmode, 27);
+ operands[3] = GEN_INT (alpha_next_sequence_number++);
+ emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
+ operands[0], operands[3]));
+ }
+ else
+ {
+ operands[2] = operands[0];
+ operands[0] = const0_rtx;
+ operands[3] = const0_rtx;
+ }
+})
+
+(define_peephole2
+ [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
+ (match_operand 1 "" ""))
+ (use (reg:DI 29))
+ (clobber (reg:DI 26))])]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
+ && ! current_file_function_operand (operands[0], Pmode)
+ && ! peep2_regno_dead_p (1, 29)"
+ [(parallel [(call (mem:DI (match_dup 2))
+ (match_dup 1))
+ (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
+ (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (use (match_dup 0))
+ (use (match_dup 4))])
+ (set (reg:DI 29)
+ (unspec_volatile:DI [(reg:DI 26) (match_dup 3)] UNSPECV_LDGP1))
+ (set (reg:DI 29)
+ (unspec:DI [(reg:DI 29) (match_dup 3)] UNSPEC_LDGP2))]
+{
+ if (CONSTANT_P (operands[0]))
+ {
+ operands[2] = gen_rtx_REG (Pmode, 27);
+ operands[4] = GEN_INT (alpha_next_sequence_number++);
+ emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
+ operands[0], operands[4]));
+ }
+ else
+ {
+ operands[2] = operands[0];
+ operands[0] = const0_rtx;
+ operands[4] = const0_rtx;
+ }
+ operands[3] = GEN_INT (alpha_next_sequence_number++);
+})
+
+;; We add a blockage unspec_volatile to prevent insns from moving down
+;; from above the call to in between the call and the ldah gpdisp.
+
+(define_insn "*call_osf_2_er"
+ [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
+ (match_operand 1 "" ""))
+ (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
+ (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (use (match_operand 2 "" ""))
+ (use (match_operand 3 "const_int_operand" ""))]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "jsr $26,(%0),%2%J3"
+ [(set_attr "type" "jsr")])
+
+(define_insn "*call_osf_1_noreturn"
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
(match_operand 1 "" ""))
+ (use (reg:DI 29))
(clobber (reg:DI 26))]
- "TARGET_WINDOWS_NT"
+ "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
"@
- jsr $26,(%0)
- bsr $26,%0
+ jsr $26,($27),0
+ bsr $26,$%0..ng
jsr $26,%0"
[(set_attr "type" "jsr")
- (set_attr "length" "*,*,12")])
-
-(define_insn ""
- [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
- (match_operand 1 "" ""))
- (use (match_operand:DI 2 "general_operand" "r,m"))
- (use (reg:DI 25))
- (use (reg:DI 26))
- (clobber (reg:DI 27))]
- "TARGET_OPEN_VMS"
- "@
- mov %2,$27\;jsr $26,0\;ldq $27,0($29)
- ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
- [(set_attr "type" "jsr")
- (set_attr "length" "12,16")])
+ (set_attr "length" "*,*,8")])
-(define_insn ""
- [(set (match_operand 0 "register_operand" "=rf,rf,rf")
- (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
- (match_operand 2 "" "")))
- (clobber (reg:DI 27))
+(define_insn "*call_osf_1"
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
+ (match_operand 1 "" ""))
+ (use (reg:DI 29))
(clobber (reg:DI 26))]
- "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
+ "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
jsr $26,($27),0\;ldgp $29,0($26)
- bsr $26,$%1..ng
- jsr $26,%1\;ldgp $29,0($26)"
+ bsr $26,$%0..ng
+ jsr $26,%0\;ldgp $29,0($26)"
[(set_attr "type" "jsr")
(set_attr "length" "12,*,16")])
-(define_insn ""
- [(set (match_operand 0 "register_operand" "=rf,rf,rf")
- (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
- (match_operand 2 "" "")))
+;; Note that the DEC assembler expands "jmp foo" with $at, which
+;; doesn't do what we want.
+(define_insn "*sibcall_osf_1_er"
+ [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
+ (match_operand 1 "" ""))
+ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "@
+ br $31,$%0..ng
+ ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "*,8")])
+
+(define_insn "*sibcall_osf_1"
+ [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
+ (match_operand 1 "" ""))
+ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
+ "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "@
+ br $31,$%0..ng
+ lda $27,%0\;jmp $31,($27),%0"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "*,8")])
+
+(define_insn "*call_nt_1"
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,s"))
+ (match_operand 1 "" ""))
(clobber (reg:DI 26))]
- "TARGET_WINDOWS_NT"
+ "TARGET_ABI_WINDOWS_NT"
"@
- jsr $26,(%1)
- bsr $26,%1
- jsr $26,%1"
+ jsr $26,(%0)
+ bsr $26,%0
+ jsr $26,%0"
[(set_attr "type" "jsr")
(set_attr "length" "*,*,12")])
-(define_insn ""
- [(set (match_operand 0 "register_operand" "")
- (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
- (match_operand 2 "" "")))
- (use (match_operand:DI 3 "general_operand" "r,m"))
+(define_insn "*call_vms_1"
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
+ (match_operand 1 "" ""))
+ (use (match_operand:DI 2 "nonimmediate_operand" "r,m"))
(use (reg:DI 25))
(use (reg:DI 26))
(clobber (reg:DI 27))]
- "TARGET_OPEN_VMS"
+ "TARGET_ABI_OPEN_VMS"
"@
- mov %3,$27\;jsr $26,0\;ldq $27,0($29)
- ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
+ mov %2,$27\;jsr $26,0\;ldq $27,0($29)
+ ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
[(set_attr "type" "jsr")
(set_attr "length" "12,16")])
+(define_insn "*call_umk_1"
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "r"))
+ (match_operand 1 "" ""))
+ (use (reg:DI 25))
+ (clobber (reg:DI 26))]
+ "TARGET_ABI_UNICOSMK"
+ "jsr $26,(%0)"
+ [(set_attr "type" "jsr")])
+
;; Call subroutine returning any type.
(define_expand "untyped_call"
@@ -3793,11 +5006,10 @@
(match_operand 1 "" "")
(match_operand 2 "" "")])]
""
- "
{
int i;
- emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
+ emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
for (i = 0; i < XVECLEN (operands[2], 0); i++)
{
@@ -3812,13 +5024,13 @@
emit_insn (gen_blockage ());
DONE;
-}")
+})
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
;; all of memory. This blocks insns from being moved across this point.
(define_insn "blockage"
- [(unspec_volatile [(const_int 0)] 1)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
""
""
[(set_attr "length" "0")])
@@ -3830,18 +5042,14 @@
"br $31,%l0"
[(set_attr "type" "ibr")])
-(define_insn "return"
+(define_expand "return"
[(return)]
"direct_return ()"
- "ret $31,($26),1"
- [(set_attr "type" "ibr")])
+ "")
-;; Use a different pattern for functions which have non-trivial
-;; epilogues so as not to confuse jump and reorg.
-(define_insn "return_internal"
- [(use (reg:DI 26))
- (return)]
- ""
+(define_insn "*return_internal"
+ [(return)]
+ "reload_completed"
"ret $31,($26),1"
[(set_attr "type" "ibr")])
@@ -3852,155 +5060,43 @@
[(set_attr "type" "ibr")])
(define_expand "tablejump"
- [(use (match_operand:SI 0 "register_operand" ""))
- (use (match_operand:SI 1 "" ""))]
+ [(parallel [(set (pc)
+ (match_operand 0 "register_operand" ""))
+ (use (label_ref:DI (match_operand 1 "" "")))])]
""
- "
{
- if (TARGET_WINDOWS_NT)
- emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
- else if (TARGET_OPEN_VMS)
- emit_jump_insn (gen_tablejump_vms (operands[0], operands[1]));
- else
- emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
-
- DONE;
-}")
-
-(define_expand "tablejump_osf"
- [(set (match_dup 3)
- (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
- (parallel [(set (pc)
- (plus:DI (match_dup 3)
- (label_ref:DI (match_operand 1 "" ""))))
- (clobber (match_scratch:DI 2 "=r"))])]
- ""
- "
-{ operands[3] = gen_reg_rtx (DImode); }")
-
-(define_expand "tablejump_nt"
- [(set (match_dup 3)
- (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
- (parallel [(set (pc)
- (match_dup 3))
- (use (label_ref (match_operand 1 "" "")))])]
- ""
- "
-{ operands[3] = gen_reg_rtx (DImode); }")
-
-;;
-;; tablejump, openVMS way
-;; op 0: offset
-;; op 1: label preceding jump-table
-;;
-(define_expand "tablejump_vms"
- [(set (match_dup 2)
- (match_operand:DI 0 "register_operand" ""))
- (set (pc)
- (plus:DI (match_dup 2)
- (label_ref:DI (match_operand 1 "" ""))))]
- ""
- "
-{ operands[2] = gen_reg_rtx (DImode); }")
-
-(define_insn ""
- [(set (pc)
- (plus:DI (match_operand:DI 0 "register_operand" "r")
- (label_ref:DI (match_operand 1 "" ""))))
- (clobber (match_scratch:DI 2 "=r"))]
- "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && next_active_insn (insn) != 0
- && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
- && PREV_INSN (next_active_insn (insn)) == operands[1]"
- "*
-{ rtx best_label = 0;
- rtx jump_table_insn = next_active_insn (operands[1]);
-
- if (GET_CODE (jump_table_insn) == JUMP_INSN
- && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
+ if (TARGET_ABI_WINDOWS_NT)
{
- rtx jump_table = PATTERN (jump_table_insn);
- int n_labels = XVECLEN (jump_table, 1);
- int best_count = -1;
- int i, j;
-
- for (i = 0; i < n_labels; i++)
- {
- int count = 1;
-
- for (j = i + 1; j < n_labels; j++)
- if (XEXP (XVECEXP (jump_table, 1, i), 0)
- == XEXP (XVECEXP (jump_table, 1, j), 0))
- count++;
-
- if (count > best_count)
- best_count = count, best_label = XVECEXP (jump_table, 1, i);
- }
+ rtx dest = gen_reg_rtx (DImode);
+ emit_insn (gen_extendsidi2 (dest, operands[0]));
+ operands[0] = dest;
}
-
- if (best_label)
+ else if (TARGET_ABI_OSF)
{
- operands[3] = best_label;
- return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
+ rtx dest = gen_reg_rtx (DImode);
+ emit_insn (gen_extendsidi2 (dest, operands[0]));
+ emit_insn (gen_adddi3 (dest, pic_offset_table_rtx, dest));
+ operands[0] = dest;
}
- else
- return \"addq %0,$29,%2\;jmp $31,(%2),0\";
-}"
- [(set_attr "type" "ibr")
- (set_attr "length" "8")])
+})
-(define_insn ""
+(define_insn "*tablejump_osf_nt_internal"
[(set (pc)
(match_operand:DI 0 "register_operand" "r"))
- (use (label_ref (match_operand 1 "" "")))]
- "TARGET_WINDOWS_NT && next_active_insn (insn) != 0
- && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
- && PREV_INSN (next_active_insn (insn)) == operands[1]"
- "*
-{ rtx best_label = 0;
- rtx jump_table_insn = next_active_insn (operands[1]);
-
- if (GET_CODE (jump_table_insn) == JUMP_INSN
- && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
- {
- rtx jump_table = PATTERN (jump_table_insn);
- int n_labels = XVECLEN (jump_table, 1);
- int best_count = -1;
- int i, j;
-
- for (i = 0; i < n_labels; i++)
- {
- int count = 1;
-
- for (j = i + 1; j < n_labels; j++)
- if (XEXP (XVECEXP (jump_table, 1, i), 0)
- == XEXP (XVECEXP (jump_table, 1, j), 0))
- count++;
-
- if (count > best_count)
- best_count = count, best_label = XVECEXP (jump_table, 1, i);
- }
- }
-
- if (best_label)
- {
- operands[2] = best_label;
- return \"jmp $31,(%0),%2\";
- }
- else
- return \"jmp $31,(%0),0\";
-}"
+ (use (label_ref:DI (match_operand 1 "" "")))]
+ "(TARGET_ABI_OSF || TARGET_ABI_WINDOWS_NT)
+ && alpha_tablejump_addr_vec (insn)"
+{
+ operands[2] = alpha_tablejump_best_label (insn);
+ return "jmp $31,(%0),%2";
+}
[(set_attr "type" "ibr")])
-;;
-;; op 0 is table offset
-;; op 1 is table label
-;;
-
-(define_insn ""
+(define_insn "*tablejump_internal"
[(set (pc)
- (plus:DI (match_operand 0 "register_operand" "r")
- (label_ref (match_operand 1 "" ""))))]
- "TARGET_OPEN_VMS"
+ (match_operand:DI 0 "register_operand" "r"))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
"jmp $31,(%0),0"
[(set_attr "type" "ibr")])
@@ -4011,7 +5107,7 @@
;; if we need a GP. Use ibr instead since it has the same EV5 scheduling
;; characteristics.
(define_insn "imb"
- [(unspec_volatile [(const_int 0)] 0)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_IMB)]
""
"call_pal 0x86"
[(set_attr "type" "ibr")])
@@ -4020,31 +5116,31 @@
;; are done via define_expand. Start with the floating-point insns, since
;; they are simpler.
-(define_insn ""
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m")
- (match_operand:SF 1 "input_operand" "fG,m,rG,m,fG,r"))]
- "! TARGET_FIX
+(define_insn "*movsf_nofix"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
+ (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
+ "TARGET_FPREGS && ! TARGET_FIX
&& (register_operand (operands[0], SFmode)
|| reg_or_fp0_operand (operands[1], SFmode))"
"@
- fmov %R1,%0
+ cpys %R1,%R1,%0
ld%, %0,%1
- mov %r1,%0
+ bis $31,%r1,%0
ldl %0,%1
st%, %R1,%0
stl %r1,%0"
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
-(define_insn ""
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r")
- (match_operand:SF 1 "input_operand" "fG,m,rG,m,fG,r,r,*f"))]
- "TARGET_FIX
+(define_insn "*movsf_fix"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
+ (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
+ "TARGET_FPREGS && TARGET_FIX
&& (register_operand (operands[0], SFmode)
|| reg_or_fp0_operand (operands[1], SFmode))"
"@
- fmov %R1,%0
+ cpys %R1,%R1,%0
ld%, %0,%1
- mov %r1,%0
+ bis $31,%r1,%0
ldl %0,%1
st%, %R1,%0
stl %r1,%0
@@ -4052,31 +5148,43 @@
ftois %1,%0"
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
-(define_insn ""
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m")
- (match_operand:DF 1 "input_operand" "fG,m,rG,m,fG,r"))]
- "! TARGET_FIX
+(define_insn "*movsf_nofp"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
+ (match_operand:SF 1 "input_operand" "rG,m,r"))]
+ "! TARGET_FPREGS
+ && (register_operand (operands[0], SFmode)
+ || reg_or_fp0_operand (operands[1], SFmode))"
+ "@
+ bis $31,%r1,%0
+ ldl %0,%1
+ stl %r1,%0"
+ [(set_attr "type" "ilog,ild,ist")])
+
+(define_insn "*movdf_nofix"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
+ (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
+ "TARGET_FPREGS && ! TARGET_FIX
&& (register_operand (operands[0], DFmode)
|| reg_or_fp0_operand (operands[1], DFmode))"
"@
- fmov %R1,%0
+ cpys %R1,%R1,%0
ld%- %0,%1
- mov %r1,%0
+ bis $31,%r1,%0
ldq %0,%1
st%- %R1,%0
stq %r1,%0"
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
-(define_insn ""
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r")
- (match_operand:DF 1 "input_operand" "fG,m,rG,m,fG,r,r,*f"))]
- "TARGET_FIX
+(define_insn "*movdf_fix"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
+ (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
+ "TARGET_FPREGS && TARGET_FIX
&& (register_operand (operands[0], DFmode)
|| reg_or_fp0_operand (operands[1], DFmode))"
"@
- fmov %R1,%0
+ cpys %R1,%R1,%0
ld%- %0,%1
- mov %r1,%0
+ bis $31,%r1,%0
ldq %0,%1
st%- %R1,%0
stq %r1,%0
@@ -4084,157 +5192,183 @@
ftoit %1,%0"
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
+(define_insn "*movdf_nofp"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
+ (match_operand:DF 1 "input_operand" "rG,m,r"))]
+ "! TARGET_FPREGS
+ && (register_operand (operands[0], DFmode)
+ || reg_or_fp0_operand (operands[1], DFmode))"
+ "@
+ bis $31,%r1,%0
+ ldq %0,%1
+ stq %r1,%0"
+ [(set_attr "type" "ilog,ild,ist")])
+
+;; Subregs suck for register allocation. Pretend we can move TFmode
+;; data between general registers until after reload.
+
+(define_insn_and_split "*movtf_internal"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
+ (match_operand:TF 1 "input_operand" "roG,rG"))]
+ "register_operand (operands[0], TFmode)
+ || reg_or_fp0_operand (operands[1], TFmode)"
+ "#"
+ "reload_completed"
+ [(set (match_dup 0) (match_dup 2))
+ (set (match_dup 1) (match_dup 3))]
+{
+ alpha_split_tfmode_pair (operands);
+ if (reg_overlap_mentioned_p (operands[0], operands[3]))
+ {
+ rtx tmp;
+ tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
+ tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
+ }
+})
+
(define_expand "movsf"
[(set (match_operand:SF 0 "nonimmediate_operand" "")
(match_operand:SF 1 "general_operand" ""))]
""
- "
{
if (GET_CODE (operands[0]) == MEM
&& ! reg_or_fp0_operand (operands[1], SFmode))
operands[1] = force_reg (SFmode, operands[1]);
-}")
+})
(define_expand "movdf"
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(match_operand:DF 1 "general_operand" ""))]
""
- "
{
if (GET_CODE (operands[0]) == MEM
&& ! reg_or_fp0_operand (operands[1], DFmode))
operands[1] = force_reg (DFmode, operands[1]);
-}")
+})
-(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m")
- (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f"))]
- "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_FIX
+(define_expand "movtf"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (match_operand:TF 1 "general_operand" ""))]
+ ""
+{
+ if (GET_CODE (operands[0]) == MEM
+ && ! reg_or_fp0_operand (operands[1], TFmode))
+ operands[1] = force_reg (TFmode, operands[1]);
+})
+
+(define_insn "*movsi_nofix"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
+ "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK) && ! TARGET_FIX
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
- mov %r1,%0
- lda %0,%1
- ldah %0,%h1
+ bis $31,%r1,%0
+ lda %0,%1($31)
+ ldah %0,%h1($31)
ldl %0,%1
stl %r1,%0
- fmov %R1,%0
+ cpys %R1,%R1,%0
ld%, %0,%1
st%, %R1,%0"
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
-(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m,r,*f")
- (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f,f,*r"))]
- "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX
+(define_insn "*movsi_fix"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
+ "TARGET_ABI_OSF && TARGET_FIX
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
- mov %r1,%0
- lda %0,%1
- ldah %0,%h1
+ bis $31,%r1,%0
+ lda %0,%1($31)
+ ldah %0,%h1($31)
ldl %0,%1
stl %r1,%0
- fmov %R1,%0
+ cpys %R1,%R1,%0
ld%, %0,%1
st%, %R1,%0
ftois %1,%0
itofs %1,%0"
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
-(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f,m")
- (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,m,f"))]
- "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
+(define_insn "*movsi_nt_vms"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
+ "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
- mov %1,%0
+ bis $31,%1,%0
lda %0,%1
ldah %0,%h1
lda %0,%1
ldl %0,%1
stl %r1,%0
- fmov %R1,%0
+ cpys %R1,%R1,%0
ld%, %0,%1
st%, %R1,%0"
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
-(define_insn ""
- [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,f")
- (match_operand:HI 1 "input_operand" "rJ,n,fJ"))]
+(define_insn "*movhi_nobwx"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (match_operand:HI 1 "input_operand" "rJ,n"))]
"! TARGET_BWX
&& (register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode))"
"@
- mov %r1,%0
- lda %0,%L1
- fmov %R1,%0"
- [(set_attr "type" "ilog,iadd,fcpys")])
+ bis $31,%r1,%0
+ lda %0,%L1($31)"
+ [(set_attr "type" "ilog,iadd")])
-(define_insn ""
- [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,f")
- (match_operand:HI 1 "input_operand" "rJ,n,m,rJ,fJ"))]
+(define_insn "*movhi_bwx"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
+ (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
"TARGET_BWX
&& (register_operand (operands[0], HImode)
|| reg_or_0_operand (operands[1], HImode))"
"@
- mov %r1,%0
- lda %0,%L1
+ bis $31,%r1,%0
+ lda %0,%L1($31)
ldwu %0,%1
- stw %r1,%0
- fmov %R1,%0"
- [(set_attr "type" "ilog,iadd,ild,ist,fcpys")])
+ stw %r1,%0"
+ [(set_attr "type" "ilog,iadd,ild,ist")])
-(define_insn ""
- [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,f")
- (match_operand:QI 1 "input_operand" "rJ,n,fJ"))]
+(define_insn "*movqi_nobwx"
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (match_operand:QI 1 "input_operand" "rJ,n"))]
"! TARGET_BWX
&& (register_operand (operands[0], QImode)
|| register_operand (operands[1], QImode))"
"@
- mov %r1,%0
- lda %0,%L1
- fmov %R1,%0"
- [(set_attr "type" "ilog,iadd,fcpys")])
+ bis $31,%r1,%0
+ lda %0,%L1($31)"
+ [(set_attr "type" "ilog,iadd")])
-(define_insn ""
- [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m,f")
- (match_operand:QI 1 "input_operand" "rJ,n,m,rJ,fJ"))]
+(define_insn "*movqi_bwx"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
+ (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
"TARGET_BWX
&& (register_operand (operands[0], QImode)
|| reg_or_0_operand (operands[1], QImode))"
"@
- mov %r1,%0
- lda %0,%L1
+ bis $31,%r1,%0
+ lda %0,%L1($31)
ldbu %0,%1
- stb %r1,%0
- fmov %R1,%0"
- [(set_attr "type" "ilog,iadd,ild,ist,fcpys")])
+ stb %r1,%0"
+ [(set_attr "type" "ilog,iadd,ild,ist")])
;; We do two major things here: handle mem->mem and construct long
;; constants.
(define_expand "movsi"
- [(set (match_operand:SI 0 "general_operand" "")
+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
(match_operand:SI 1 "general_operand" ""))]
""
- "
{
- if (GET_CODE (operands[0]) == MEM
- && ! reg_or_0_operand (operands[1], SImode))
- operands[1] = force_reg (SImode, operands[1]);
-
- if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
- ;
- else if (GET_CODE (operands[1]) == CONST_INT)
- {
- operands[1]
- = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
- if (rtx_equal_p (operands[0], operands[1]))
- DONE;
- }
-}")
+ if (alpha_expand_mov (SImode, operands))
+ DONE;
+})
;; Split a load of a large constant into the appropriate two-insn
;; sequence.
@@ -4245,126 +5379,267 @@
"! add_operand (operands[1], SImode)"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
- "
-{ rtx tem
+{
+ rtx tem
= alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
if (tem == operands[0])
DONE;
else
FAIL;
-}")
+})
-(define_insn ""
- [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q")
- (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f"))]
- "! TARGET_FIX
+;; Split the load of an address into a four-insn sequence on Unicos/Mk.
+;; Always generate a REG_EQUAL note for the last instruction to facilitate
+;; optimisations. If the symbolic operand is a label_ref, generate REG_LABEL
+;; notes and update LABEL_NUSES because this is not done automatically.
+;; Labels may be incorrectly deleted if we don't do this.
+;;
+;; Describing what the individual instructions do correctly is too complicated
+;; so use UNSPECs for each of the three parts of an address.
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "symbolic_operand" ""))]
+ "TARGET_ABI_UNICOSMK && reload_completed"
+ [(const_int 0)]
+{
+ rtx insn1, insn2, insn3;
+
+ insn1 = emit_insn (gen_umk_laum (operands[0], operands[1]));
+ emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
+ insn2 = emit_insn (gen_umk_lalm (operands[0], operands[0], operands[1]));
+ insn3 = emit_insn (gen_umk_lal (operands[0], operands[0], operands[1]));
+ REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
+ REG_NOTES (insn3));
+ if (GET_CODE (operands[1]) == LABEL_REF)
+ {
+ rtx label;
+
+ label = XEXP (operands[1], 0);
+ REG_NOTES (insn1) = gen_rtx_EXPR_LIST (REG_LABEL, label,
+ REG_NOTES (insn1));
+ REG_NOTES (insn2) = gen_rtx_EXPR_LIST (REG_LABEL, label,
+ REG_NOTES (insn2));
+ REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_LABEL, label,
+ REG_NOTES (insn3));
+ LABEL_NUSES (label) += 3;
+ }
+ DONE;
+})
+
+;; Instructions for loading the three parts of an address on Unicos/Mk.
+
+(define_insn "umk_laum"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_UMK_LAUM))]
+ "TARGET_ABI_UNICOSMK"
+ "laum %r0,%t1($31)"
+ [(set_attr "type" "iadd")])
+
+(define_insn "umk_lalm"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_UMK_LALM)))]
+ "TARGET_ABI_UNICOSMK"
+ "lalm %r0,%t2(%r1)"
+ [(set_attr "type" "iadd")])
+
+(define_insn "umk_lal"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_UMK_LAL)))]
+ "TARGET_ABI_UNICOSMK"
+ "lal %r0,%t2(%r1)"
+ [(set_attr "type" "iadd")])
+
+;; Add a new call information word to the current function's list of CIWs
+;; and load its index into $25. Doing it here ensures that the CIW will be
+;; associated with the correct function even in the presence of inlining.
+
+(define_insn "*umk_load_ciw"
+ [(set (reg:DI 25)
+ (unspec:DI [(match_operand 0 "" "")] UNSPEC_UMK_LOAD_CIW))]
+ "TARGET_ABI_UNICOSMK"
+{
+ operands[0] = unicosmk_add_call_info_word (operands[0]);
+ return "lda $25,%0";
+}
+ [(set_attr "type" "iadd")])
+
+(define_insn "*movdi_er_low_l"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
+ (match_operand:DI 2 "local_symbolic_operand" "")))]
+ "TARGET_EXPLICIT_RELOCS"
+{
+ if (true_regnum (operands[1]) == 29)
+ return "lda %0,%2(%1)\t\t!gprel";
+ else
+ return "lda %0,%2(%1)\t\t!gprellow";
+})
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "small_symbolic_operand" ""))]
+ "TARGET_EXPLICIT_RELOCS && reload_completed"
+ [(set (match_dup 0)
+ (lo_sum:DI (match_dup 2) (match_dup 1)))]
+ "operands[2] = pic_offset_table_rtx;")
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "local_symbolic_operand" ""))]
+ "TARGET_EXPLICIT_RELOCS && reload_completed"
+ [(set (match_dup 0)
+ (plus:DI (match_dup 2) (high:DI (match_dup 1))))
+ (set (match_dup 0)
+ (lo_sum:DI (match_dup 0) (match_dup 1)))]
+ "operands[2] = pic_offset_table_rtx;")
+
+(define_split
+ [(match_operand 0 "some_small_symbolic_mem_operand" "")]
+ "TARGET_EXPLICIT_RELOCS && reload_completed"
+ [(match_dup 0)]
+ "operands[0] = split_small_symbolic_mem_operand (operands[0]);")
+
+(define_insn "movdi_er_high_g"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand:DI 2 "global_symbolic_operand" "")
+ (match_operand 3 "const_int_operand" "")]
+ UNSPEC_LITERAL))]
+ "TARGET_EXPLICIT_RELOCS"
+{
+ if (INTVAL (operands[3]) == 0)
+ return "ldq %0,%2(%1)\t\t!literal";
+ else
+ return "ldq %0,%2(%1)\t\t!literal!%3";
+}
+ [(set_attr "type" "ldsym")])
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "global_symbolic_operand" ""))]
+ "TARGET_EXPLICIT_RELOCS && reload_completed"
+ [(set (match_dup 0)
+ (unspec:DI [(match_dup 2)
+ (match_dup 1)
+ (const_int 0)] UNSPEC_LITERAL))]
+ "operands[2] = pic_offset_table_rtx;")
+
+(define_insn "*movdi_er_nofix"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
+ (match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))]
+ "TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
"@
mov %r1,%0
- lda %0,%1
- ldah %0,%h1
- lda %0,%1
+ lda %0,%1($31)
+ ldah %0,%h1($31)
+ #
+ #
ldq%A1 %0,%1
stq%A0 %r1,%0
fmov %R1,%0
ldt %0,%1
stt %R1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
+ [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
-(define_insn ""
- [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q,r,*f")
- (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f,f,*r"))]
- "TARGET_FIX
+;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should
+;; have been split up by the rules above but we shouldn't reject the
+;; possibility of them getting through.
+
+(define_insn "*movdi_nofix"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
+ (match_operand:DI 1 "input_operand" "rJ,K,L,U,s,m,rJ,*fJ,Q,*f"))]
+ "! TARGET_FIX
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
"@
- mov %r1,%0
- lda %0,%1
- ldah %0,%h1
+ bis $31,%r1,%0
+ lda %0,%1($31)
+ ldah %0,%h1($31)
+ laum %0,%t1($31)\;sll %0,32,%0\;lalm %0,%t1(%0)\;lal %0,%t1(%0)
lda %0,%1
ldq%A1 %0,%1
stq%A0 %r1,%0
+ cpys %R1,%R1,%0
+ ldt %0,%1
+ stt %R1,%0"
+ [(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,ild,ist,fcpys,fld,fst")
+ (set_attr "length" "*,*,*,16,*,*,*,*,*,*")])
+
+(define_insn "*movdi_er_fix"
+ [(set (match_operand:DI 0 "nonimmediate_operand"
+ "=r,r,r,r,r,r, m, *f,*f, Q, r,*f")
+ (match_operand:DI 1 "input_operand"
+ "rJ,K,L,T,s,m,rJ,*fJ, Q,*f,*f, r"))]
+ "TARGET_EXPLICIT_RELOCS && TARGET_FIX
+ && (register_operand (operands[0], DImode)
+ || reg_or_0_operand (operands[1], DImode))"
+ "@
+ mov %r1,%0
+ lda %0,%1($31)
+ ldah %0,%h1($31)
+ #
+ #
+ ldq%A1 %0,%1
+ stq%A0 %r1,%0
fmov %R1,%0
ldt %0,%1
stt %R1,%0
ftoit %1,%0
itoft %1,%0"
+ [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
+
+(define_insn "*movdi_fix"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
+ (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
+ "! TARGET_EXPLICIT_RELOCS && TARGET_FIX
+ && (register_operand (operands[0], DImode)
+ || reg_or_0_operand (operands[1], DImode))"
+ "@
+ bis $31,%r1,%0
+ lda %0,%1($31)
+ ldah %0,%h1($31)
+ lda %0,%1
+ ldq%A1 %0,%1
+ stq%A0 %r1,%0
+ cpys %R1,%R1,%0
+ ldt %0,%1
+ stt %R1,%0
+ ftoit %1,%0
+ itoft %1,%0"
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
+;; VMS needs to set up "vms_base_regno" for unwinding. This move
+;; often appears dead to the life analysis code, at which point we
+;; abort for emitting dead prologue instructions. Force this live.
+
+(define_insn "force_movdi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
+ UNSPECV_FORCE_MOV))]
+ ""
+ "mov %1,%0"
+ [(set_attr "type" "ilog")])
+
;; We do three major things here: handle mem->mem, put 64-bit constants in
;; memory, and construct long 32-bit constants.
(define_expand "movdi"
- [(set (match_operand:DI 0 "general_operand" "")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
(match_operand:DI 1 "general_operand" ""))]
""
- "
{
- rtx tem;
-
- if (GET_CODE (operands[0]) == MEM
- && ! reg_or_0_operand (operands[1], DImode))
- operands[1] = force_reg (DImode, operands[1]);
-
- if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
- ;
- else if (GET_CODE (operands[1]) == CONST_INT
- && (tem = alpha_emit_set_const (operands[0], DImode,
- INTVAL (operands[1]), 3)) != 0)
- {
- if (rtx_equal_p (tem, operands[0]))
- DONE;
- else
- operands[1] = tem;
- }
- else if (CONSTANT_P (operands[1]))
- {
- if (TARGET_BUILD_CONSTANTS)
- {
- HOST_WIDE_INT i0, i1;
-
- if (GET_CODE (operands[1]) == CONST_INT)
- {
- i0 = INTVAL (operands[1]);
- i1 = -(i0 < 0);
- }
- else if (GET_CODE (operands[1]) == CONST_DOUBLE)
- {
-#if HOST_BITS_PER_WIDE_INT >= 64
- i0 = CONST_DOUBLE_LOW (operands[1]);
- i1 = -(i0 < 0);
-#else
- i0 = CONST_DOUBLE_LOW (operands[1]);
- i1 = CONST_DOUBLE_HIGH (operands[1]);
-#endif
- }
- else
- abort();
-
- tem = alpha_emit_set_long_const (operands[0], i0, i1);
- if (rtx_equal_p (tem, operands[0]))
- DONE;
- else
- operands[1] = tem;
- }
- else
- {
- operands[1] = force_const_mem (DImode, operands[1]);
- if (reload_in_progress)
- {
- emit_move_insn (operands[0], XEXP (operands[1], 0));
- operands[1] = copy_rtx (operands[1]);
- XEXP (operands[1], 0) = operands[0];
- }
- else
- operands[1] = validize_mem (operands[1]);
- }
- }
- else
- abort ();
-}")
+ if (alpha_expand_mov (DImode, operands))
+ DONE;
+})
;; Split a load of a large constant into the appropriate two-insn
;; sequence.
@@ -4375,15 +5650,15 @@
"! add_operand (operands[1], DImode)"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
- "
-{ rtx tem
+{
+ rtx tem
= alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
if (tem == operands[0])
DONE;
else
FAIL;
-}")
+})
;; These are the partial-word cases.
;;
@@ -4401,10 +5676,10 @@
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 8)
(match_operand:DI 2 "const_int_operand" "")))]
-
+
""
"")
-
+
(define_expand "aligned_loadhi"
[(set (match_operand:SI 3 "register_operand" "")
(match_operand:SI 1 "memory_operand" ""))
@@ -4412,17 +5687,34 @@
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 16)
(match_operand:DI 2 "const_int_operand" "")))]
-
+
""
"")
-
+
;; Similar for unaligned loads, where we use the sequence from the
-;; Alpha Architecture manual.
+;; Alpha Architecture manual. We have to distinguish between little-endian
+;; and big-endian systems as the sequences are different.
;;
;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
;; operand 3 can overlap the input and output registers.
(define_expand "unaligned_loadqi"
+ [(use (match_operand:QI 0 "register_operand" ""))
+ (use (match_operand:DI 1 "address_operand" ""))
+ (use (match_operand:DI 2 "register_operand" ""))
+ (use (match_operand:DI 3 "register_operand" ""))]
+ ""
+{
+ if (WORDS_BIG_ENDIAN)
+ emit_insn (gen_unaligned_loadqi_be (operands[0], operands[1],
+ operands[2], operands[3]));
+ else
+ emit_insn (gen_unaligned_loadqi_le (operands[0], operands[1],
+ operands[2], operands[3]));
+ DONE;
+})
+
+(define_expand "unaligned_loadqi_le"
[(set (match_operand:DI 2 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
(const_int -8))))
@@ -4432,10 +5724,41 @@
(zero_extract:DI (match_dup 2)
(const_int 8)
(ashift:DI (match_dup 3) (const_int 3))))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "")
+
+(define_expand "unaligned_loadqi_be"
+ [(set (match_operand:DI 2 "register_operand" "")
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
+ (const_int -8))))
+ (set (match_operand:DI 3 "register_operand" "")
+ (match_dup 1))
+ (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (zero_extract:DI (match_dup 2)
+ (const_int 8)
+ (minus:DI
+ (const_int 56)
+ (ashift:DI (match_dup 3) (const_int 3)))))]
+ "WORDS_BIG_ENDIAN"
"")
(define_expand "unaligned_loadhi"
+ [(use (match_operand:QI 0 "register_operand" ""))
+ (use (match_operand:DI 1 "address_operand" ""))
+ (use (match_operand:DI 2 "register_operand" ""))
+ (use (match_operand:DI 3 "register_operand" ""))]
+ ""
+{
+ if (WORDS_BIG_ENDIAN)
+ emit_insn (gen_unaligned_loadhi_be (operands[0], operands[1],
+ operands[2], operands[3]));
+ else
+ emit_insn (gen_unaligned_loadhi_le (operands[0], operands[1],
+ operands[2], operands[3]));
+ DONE;
+})
+
+(define_expand "unaligned_loadhi_le"
[(set (match_operand:DI 2 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
(const_int -8))))
@@ -4445,11 +5768,26 @@
(zero_extract:DI (match_dup 2)
(const_int 16)
(ashift:DI (match_dup 3) (const_int 3))))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "")
+
+(define_expand "unaligned_loadhi_be"
+ [(set (match_operand:DI 2 "register_operand" "")
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
+ (const_int -8))))
+ (set (match_operand:DI 3 "register_operand" "")
+ (plus:DI (match_dup 1) (const_int 1)))
+ (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (zero_extract:DI (match_dup 2)
+ (const_int 16)
+ (minus:DI
+ (const_int 56)
+ (ashift:DI (match_dup 3) (const_int 3)))))]
+ "WORDS_BIG_ENDIAN"
"")
;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
-;; aligned SImode MEM. Operand 1 is the register containing the
+;; aligned SImode MEM. Operand 1 is the register containing the
;; byte or word to store. Operand 2 is the number of bits within the word that
;; the value should be placed. Operands 3 and 4 are SImode temporaries.
@@ -4465,10 +5803,10 @@
(ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
(set (match_dup 0) (match_dup 4))]
""
- "
-{ operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
+{
+ operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
<< INTVAL (operands[2])));
-}")
+})
;; For the unaligned byte and halfword cases, we use code similar to that
;; in the ;; Architecture book, but reordered to lower the number of registers
@@ -4478,6 +5816,25 @@
;; operand 2 can be that register.
(define_expand "unaligned_storeqi"
+ [(use (match_operand:DI 0 "address_operand" ""))
+ (use (match_operand:QI 1 "register_operand" ""))
+ (use (match_operand:DI 2 "register_operand" ""))
+ (use (match_operand:DI 3 "register_operand" ""))
+ (use (match_operand:DI 4 "register_operand" ""))]
+ ""
+{
+ if (WORDS_BIG_ENDIAN)
+ emit_insn (gen_unaligned_storeqi_be (operands[0], operands[1],
+ operands[2], operands[3],
+ operands[4]));
+ else
+ emit_insn (gen_unaligned_storeqi_le (operands[0], operands[1],
+ operands[2], operands[3],
+ operands[4]));
+ DONE;
+})
+
+(define_expand "unaligned_storeqi_le"
[(set (match_operand:DI 3 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
(const_int -8))))
@@ -4493,10 +5850,50 @@
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
(match_dup 4))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "")
+
+(define_expand "unaligned_storeqi_be"
+ [(set (match_operand:DI 3 "register_operand" "")
+ (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
+ (const_int -8))))
+ (set (match_operand:DI 2 "register_operand" "")
+ (match_dup 0))
+ (set (match_dup 3)
+ (and:DI (not:DI (ashift:DI (const_int 255)
+ (minus:DI (const_int 56)
+ (ashift:DI (match_dup 2) (const_int 3)))))
+ (match_dup 3)))
+ (set (match_operand:DI 4 "register_operand" "")
+ (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
+ (minus:DI (const_int 56)
+ (ashift:DI (match_dup 2) (const_int 3)))))
+ (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
+ (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
+ (match_dup 4))]
+ "WORDS_BIG_ENDIAN"
"")
(define_expand "unaligned_storehi"
+ [(use (match_operand:DI 0 "address_operand" ""))
+ (use (match_operand:HI 1 "register_operand" ""))
+ (use (match_operand:DI 2 "register_operand" ""))
+ (use (match_operand:DI 3 "register_operand" ""))
+ (use (match_operand:DI 4 "register_operand" ""))]
+ ""
+{
+ if (WORDS_BIG_ENDIAN)
+ emit_insn (gen_unaligned_storehi_be (operands[0], operands[1],
+ operands[2], operands[3],
+ operands[4]));
+ else
+ emit_insn (gen_unaligned_storehi_le (operands[0], operands[1],
+ operands[2], operands[3],
+ operands[4]));
+ DONE;
+})
+
+(define_expand "unaligned_storehi_le"
[(set (match_operand:DI 3 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
(const_int -8))))
@@ -4512,7 +5909,29 @@
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
(match_dup 4))]
- ""
+ "! WORDS_BIG_ENDIAN"
+ "")
+
+(define_expand "unaligned_storehi_be"
+ [(set (match_operand:DI 3 "register_operand" "")
+ (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
+ (const_int -8))))
+ (set (match_operand:DI 2 "register_operand" "")
+ (plus:DI (match_dup 0) (const_int 1)))
+ (set (match_dup 3)
+ (and:DI (not:DI (ashift:DI
+ (const_int 65535)
+ (minus:DI (const_int 56)
+ (ashift:DI (match_dup 2) (const_int 3)))))
+ (match_dup 3)))
+ (set (match_operand:DI 4 "register_operand" "")
+ (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
+ (minus:DI (const_int 56)
+ (ashift:DI (match_dup 2) (const_int 3)))))
+ (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
+ (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
+ (match_dup 4))]
+ "WORDS_BIG_ENDIAN"
"")
;; Here are the define_expand's for QI and HI moves that use the above
@@ -4520,241 +5939,26 @@
;; registers for reload.
(define_expand "movqi"
- [(set (match_operand:QI 0 "general_operand" "")
+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
(match_operand:QI 1 "general_operand" ""))]
""
- "
{
- if (TARGET_BWX)
- {
- if (GET_CODE (operands[0]) == MEM
- && ! reg_or_0_operand (operands[1], QImode))
- operands[1] = force_reg (QImode, operands[1]);
-
- if (GET_CODE (operands[1]) == CONST_INT
- && ! input_operand (operands[1], QImode))
- {
- operands[1] = alpha_emit_set_const (operands[0], QImode,
- INTVAL (operands[1]), 3);
-
- if (rtx_equal_p (operands[0], operands[1]))
- DONE;
- }
-
- goto def;
- }
-
- /* If the output is not a register, the input must be. */
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (QImode, operands[1]);
-
- /* Handle four memory cases, unaligned and aligned for either the input
- or the output. The only case where we can be called during reload is
- for aligned loads; all other cases require temporaries. */
-
- if (GET_CODE (operands[1]) == MEM
- || (GET_CODE (operands[1]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[1])) == MEM)
- || (reload_in_progress && GET_CODE (operands[1]) == REG
- && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
- || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[1])) == REG
- && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
- {
- if (aligned_memory_operand (operands[1], QImode))
- {
- if (reload_in_progress)
- {
- emit_insn (gen_reload_inqi_help
- (operands[0], operands[1],
- gen_rtx_REG (SImode, REGNO (operands[0]))));
- }
- else
- {
- rtx aligned_mem, bitnum;
- rtx scratch = gen_reg_rtx (SImode);
-
- get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-
- emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
- scratch));
- }
- }
- else
- {
- /* Don't pass these as parameters since that makes the generated
- code depend on parameter evaluation order which will cause
- bootstrap failures. */
-
- rtx temp1 = gen_reg_rtx (DImode);
- rtx temp2 = gen_reg_rtx (DImode);
- rtx seq
- = gen_unaligned_loadqi (operands[0],
- get_unaligned_address (operands[1], 0),
- temp1, temp2);
-
- alpha_set_memflags (seq, operands[1]);
- emit_insn (seq);
- }
-
- DONE;
- }
-
- else if (GET_CODE (operands[0]) == MEM
- || (GET_CODE (operands[0]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[0])) == MEM)
- || (reload_in_progress && GET_CODE (operands[0]) == REG
- && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
- || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[0])) == REG
- && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
- {
- if (aligned_memory_operand (operands[0], QImode))
- {
- rtx aligned_mem, bitnum;
- rtx temp1 = gen_reg_rtx (SImode);
- rtx temp2 = gen_reg_rtx (SImode);
-
- get_aligned_mem (operands[0], &aligned_mem, &bitnum);
-
- emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
- temp1, temp2));
- }
- else
- {
- rtx temp1 = gen_reg_rtx (DImode);
- rtx temp2 = gen_reg_rtx (DImode);
- rtx temp3 = gen_reg_rtx (DImode);
- rtx seq
- = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
- operands[1], temp1, temp2, temp3);
-
- alpha_set_memflags (seq, operands[0]);
- emit_insn (seq);
- }
- DONE;
- }
- def:;
-}")
+ if (TARGET_BWX
+ ? alpha_expand_mov (QImode, operands)
+ : alpha_expand_mov_nobwx (QImode, operands))
+ DONE;
+})
(define_expand "movhi"
- [(set (match_operand:HI 0 "general_operand" "")
+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
(match_operand:HI 1 "general_operand" ""))]
""
- "
{
- if (TARGET_BWX)
- {
- if (GET_CODE (operands[0]) == MEM
- && ! reg_or_0_operand (operands[1], HImode))
- operands[1] = force_reg (HImode, operands[1]);
-
- if (GET_CODE (operands[1]) == CONST_INT
- && ! input_operand (operands[1], HImode))
- {
- operands[1] = alpha_emit_set_const (operands[0], HImode,
- INTVAL (operands[1]), 3);
-
- if (rtx_equal_p (operands[0], operands[1]))
- DONE;
- }
-
- goto def;
- }
-
- /* If the output is not a register, the input must be. */
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (HImode, operands[1]);
-
- /* Handle four memory cases, unaligned and aligned for either the input
- or the output. The only case where we can be called during reload is
- for aligned loads; all other cases require temporaries. */
-
- if (GET_CODE (operands[1]) == MEM
- || (GET_CODE (operands[1]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[1])) == MEM)
- || (reload_in_progress && GET_CODE (operands[1]) == REG
- && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
- || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[1])) == REG
- && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
- {
- if (aligned_memory_operand (operands[1], HImode))
- {
- if (reload_in_progress)
- {
- emit_insn (gen_reload_inhi_help
- (operands[0], operands[1],
- gen_rtx_REG (SImode, REGNO (operands[0]))));
- }
- else
- {
- rtx aligned_mem, bitnum;
- rtx scratch = gen_reg_rtx (SImode);
-
- get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-
- emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
- scratch));
- }
- }
- else
- {
- /* Don't pass these as parameters since that makes the generated
- code depend on parameter evaluation order which will cause
- bootstrap failures. */
-
- rtx temp1 = gen_reg_rtx (DImode);
- rtx temp2 = gen_reg_rtx (DImode);
- rtx seq
- = gen_unaligned_loadhi (operands[0],
- get_unaligned_address (operands[1], 0),
- temp1, temp2);
-
- alpha_set_memflags (seq, operands[1]);
- emit_insn (seq);
- }
-
- DONE;
- }
-
- else if (GET_CODE (operands[0]) == MEM
- || (GET_CODE (operands[0]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[0])) == MEM)
- || (reload_in_progress && GET_CODE (operands[0]) == REG
- && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
- || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[0])) == REG
- && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
- {
- if (aligned_memory_operand (operands[0], HImode))
- {
- rtx aligned_mem, bitnum;
- rtx temp1 = gen_reg_rtx (SImode);
- rtx temp2 = gen_reg_rtx (SImode);
-
- get_aligned_mem (operands[0], &aligned_mem, &bitnum);
-
- emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
- temp1, temp2));
- }
- else
- {
- rtx temp1 = gen_reg_rtx (DImode);
- rtx temp2 = gen_reg_rtx (DImode);
- rtx temp3 = gen_reg_rtx (DImode);
- rtx seq
- = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
- operands[1], temp1, temp2, temp3);
-
- alpha_set_memflags (seq, operands[0]);
- emit_insn (seq);
- }
-
- DONE;
- }
- def:;
-}")
+ if (TARGET_BWX
+ ? alpha_expand_mov (HImode, operands)
+ : alpha_expand_mov_nobwx (HImode, operands))
+ DONE;
+})
;; Here are the versions for reload. Note that in the unaligned cases
;; we know that the operand must not be a pseudo-register because stack
@@ -4765,7 +5969,6 @@
(match_operand:QI 1 "any_memory_operand" "m")
(match_operand:TI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
- "
{
rtx scratch, seq;
@@ -4796,14 +5999,13 @@
}
emit_insn (seq);
DONE;
-}")
+})
(define_expand "reload_inhi"
[(parallel [(match_operand:HI 0 "register_operand" "=r")
(match_operand:HI 1 "any_memory_operand" "m")
(match_operand:TI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
- "
{
rtx scratch, seq;
@@ -4812,7 +6014,7 @@
if (aligned_memory_operand (operands[1], HImode))
{
- seq = gen_reload_inhi_help (operands[0], operands[1],
+ seq = gen_reload_inhi_help (operands[0], operands[1],
gen_rtx_REG (SImode, REGNO (operands[2])));
}
else
@@ -4834,14 +6036,13 @@
}
emit_insn (seq);
DONE;
-}")
+})
(define_expand "reload_outqi"
[(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
(match_operand:QI 1 "register_operand" "r")
(match_operand:TI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
- "
{
if (GET_CODE (operands[0]) != MEM)
abort ();
@@ -4870,14 +6071,13 @@
emit_insn (seq);
}
DONE;
-}")
+})
(define_expand "reload_outhi"
[(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
(match_operand:HI 1 "register_operand" "r")
(match_operand:TI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
- "
{
if (GET_CODE (operands[0]) != MEM)
abort ();
@@ -4906,103 +6106,101 @@
emit_insn (seq);
}
DONE;
-}")
+})
;; Helpers for the above. The way reload is structured, we can't
;; always get a proper address for a stack slot during reload_foo
;; expansion, so we must delay our address manipulations until after.
(define_insn "reload_inqi_help"
- [(set (match_operand:QI 0 "register_operand" "r")
+ [(set (match_operand:QI 0 "register_operand" "=r")
(match_operand:QI 1 "memory_operand" "m"))
- (clobber (match_operand:SI 2 "register_operand" "r"))]
+ (clobber (match_operand:SI 2 "register_operand" "=r"))]
"! TARGET_BWX && (reload_in_progress || reload_completed)"
"#")
(define_insn "reload_inhi_help"
- [(set (match_operand:HI 0 "register_operand" "r")
+ [(set (match_operand:HI 0 "register_operand" "=r")
(match_operand:HI 1 "memory_operand" "m"))
- (clobber (match_operand:SI 2 "register_operand" "r"))]
+ (clobber (match_operand:SI 2 "register_operand" "=r"))]
"! TARGET_BWX && (reload_in_progress || reload_completed)"
"#")
(define_insn "reload_outqi_help"
- [(set (match_operand:QI 0 "memory_operand" "m")
+ [(set (match_operand:QI 0 "memory_operand" "=m")
(match_operand:QI 1 "register_operand" "r"))
- (clobber (match_operand:SI 2 "register_operand" "r"))
- (clobber (match_operand:SI 3 "register_operand" "r"))]
+ (clobber (match_operand:SI 2 "register_operand" "=r"))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))]
"! TARGET_BWX && (reload_in_progress || reload_completed)"
"#")
(define_insn "reload_outhi_help"
- [(set (match_operand:HI 0 "memory_operand" "m")
+ [(set (match_operand:HI 0 "memory_operand" "=m")
(match_operand:HI 1 "register_operand" "r"))
- (clobber (match_operand:SI 2 "register_operand" "r"))
- (clobber (match_operand:SI 3 "register_operand" "r"))]
+ (clobber (match_operand:SI 2 "register_operand" "=r"))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))]
"! TARGET_BWX && (reload_in_progress || reload_completed)"
"#")
(define_split
- [(set (match_operand:QI 0 "register_operand" "r")
- (match_operand:QI 1 "memory_operand" "m"))
- (clobber (match_operand:SI 2 "register_operand" "r"))]
+ [(set (match_operand:QI 0 "register_operand" "")
+ (match_operand:QI 1 "memory_operand" ""))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
"! TARGET_BWX && reload_completed"
[(const_int 0)]
- "
{
rtx aligned_mem, bitnum;
get_aligned_mem (operands[1], &aligned_mem, &bitnum);
+
emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
operands[2]));
DONE;
-}")
-
+})
+
(define_split
- [(set (match_operand:HI 0 "register_operand" "r")
- (match_operand:HI 1 "memory_operand" "m"))
- (clobber (match_operand:SI 2 "register_operand" "r"))]
+ [(set (match_operand:HI 0 "register_operand" "")
+ (match_operand:HI 1 "memory_operand" ""))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
"! TARGET_BWX && reload_completed"
[(const_int 0)]
- "
{
rtx aligned_mem, bitnum;
get_aligned_mem (operands[1], &aligned_mem, &bitnum);
+
emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
operands[2]));
DONE;
-}")
-
+})
+
(define_split
- [(set (match_operand:QI 0 "memory_operand" "m")
- (match_operand:QI 1 "register_operand" "r"))
- (clobber (match_operand:SI 2 "register_operand" "r"))
- (clobber (match_operand:SI 3 "register_operand" "r"))]
+ [(set (match_operand:QI 0 "memory_operand" "")
+ (match_operand:QI 1 "register_operand" ""))
+ (clobber (match_operand:SI 2 "register_operand" ""))
+ (clobber (match_operand:SI 3 "register_operand" ""))]
"! TARGET_BWX && reload_completed"
[(const_int 0)]
- "
{
rtx aligned_mem, bitnum;
get_aligned_mem (operands[0], &aligned_mem, &bitnum);
emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
operands[2], operands[3]));
DONE;
-}")
+})
(define_split
- [(set (match_operand:HI 0 "memory_operand" "m")
- (match_operand:HI 1 "register_operand" "r"))
- (clobber (match_operand:SI 2 "register_operand" "r"))
- (clobber (match_operand:SI 3 "register_operand" "r"))]
+ [(set (match_operand:HI 0 "memory_operand" "")
+ (match_operand:HI 1 "register_operand" ""))
+ (clobber (match_operand:SI 2 "register_operand" ""))
+ (clobber (match_operand:SI 3 "register_operand" ""))]
"! TARGET_BWX && reload_completed"
[(const_int 0)]
- "
{
rtx aligned_mem, bitnum;
get_aligned_mem (operands[0], &aligned_mem, &bitnum);
emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
operands[2], operands[3]));
DONE;
-}")
+})
;; Bit field extract patterns which use ext[wlq][lh]
@@ -5012,8 +6210,9 @@
(match_operand:DI 2 "immediate_operand" "")
(match_operand:DI 3 "immediate_operand" "")))]
""
- "
{
+ int ofs;
+
/* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
if (INTVAL (operands[3]) % 8 != 0
|| (INTVAL (operands[2]) != 16
@@ -5026,19 +6225,30 @@
if (GET_CODE (operands[1]) != MEM)
FAIL;
+ /* The bit number is relative to the mode of operand 1 which is
+ usually QImode (this might actually be a bug in expmed.c). Note
+ that the bit number is negative in big-endian mode in this case.
+ We have to convert that to the offset. */
+ if (WORDS_BIG_ENDIAN)
+ ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
+ - INTVAL (operands[2]) - INTVAL (operands[3]);
+ else
+ ofs = INTVAL (operands[3]);
+
+ ofs = ofs / 8;
+
alpha_expand_unaligned_load (operands[0], operands[1],
INTVAL (operands[2]) / 8,
- INTVAL (operands[3]) / 8, 1);
+ ofs, 1);
DONE;
-}")
+})
(define_expand "extzv"
[(set (match_operand:DI 0 "register_operand" "")
- (zero_extract:DI (match_operand:DI 1 "general_operand" "")
+ (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
(match_operand:DI 2 "immediate_operand" "")
(match_operand:DI 3 "immediate_operand" "")))]
""
- "
{
/* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
if (INTVAL (operands[3]) % 8 != 0
@@ -5050,16 +6260,30 @@
if (GET_CODE (operands[1]) == MEM)
{
+ int ofs;
+
/* Fail 8 bit fields, falling back on a simple byte load. */
if (INTVAL (operands[2]) == 8)
FAIL;
+ /* The bit number is relative to the mode of operand 1 which is
+ usually QImode (this might actually be a bug in expmed.c). Note
+ that the bit number is negative in big-endian mode in this case.
+ We have to convert that to the offset. */
+ if (WORDS_BIG_ENDIAN)
+ ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
+ - INTVAL (operands[2]) - INTVAL (operands[3]);
+ else
+ ofs = INTVAL (operands[3]);
+
+ ofs = ofs / 8;
+
alpha_expand_unaligned_load (operands[0], operands[1],
INTVAL (operands[2]) / 8,
- INTVAL (operands[3]) / 8, 0);
+ ofs, 0);
DONE;
}
-}")
+})
(define_expand "insv"
[(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
@@ -5067,8 +6291,9 @@
(match_operand:DI 2 "immediate_operand" ""))
(match_operand:DI 3 "register_operand" ""))]
""
- "
{
+ int ofs;
+
/* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
if (INTVAL (operands[2]) % 8 != 0
|| (INTVAL (operands[1]) != 16
@@ -5081,13 +6306,22 @@
if (GET_CODE (operands[0]) != MEM)
FAIL;
- alpha_expand_unaligned_store (operands[0], operands[3],
- INTVAL (operands[1]) / 8,
- INTVAL (operands[2]) / 8);
- DONE;
-}")
+ /* The bit number is relative to the mode of operand 1 which is
+ usually QImode (this might actually be a bug in expmed.c). Note
+ that the bit number is negative in big-endian mode in this case.
+ We have to convert that to the offset. */
+ if (WORDS_BIG_ENDIAN)
+ ofs = GET_MODE_BITSIZE (GET_MODE (operands[0]))
+ - INTVAL (operands[1]) - INTVAL (operands[2]);
+ else
+ ofs = INTVAL (operands[2]);
+ ofs = ofs / 8;
+ alpha_expand_unaligned_store (operands[0], operands[3],
+ INTVAL (operands[1]) / 8, ofs);
+ DONE;
+})
;; Block move/clear, see alpha.c for more details.
;; Argument 0 is the destination
@@ -5096,52 +6330,49 @@
;; Argument 3 is the alignment
(define_expand "movstrqi"
- [(parallel [(set (match_operand:BLK 0 "general_operand" "")
- (match_operand:BLK 1 "general_operand" ""))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
(use (match_operand:DI 2 "immediate_operand" ""))
(use (match_operand:DI 3 "immediate_operand" ""))])]
""
- "
{
if (alpha_expand_block_move (operands))
DONE;
else
FAIL;
-}")
+})
(define_expand "clrstrqi"
- [(parallel [(set (match_operand:BLK 0 "general_operand" "")
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0))
(use (match_operand:DI 1 "immediate_operand" ""))
(use (match_operand:DI 2 "immediate_operand" ""))])]
""
- "
{
if (alpha_expand_block_clear (operands))
DONE;
else
FAIL;
-}")
+})
;; Subroutine of stack space allocation. Perform a stack probe.
(define_expand "probe_stack"
[(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
""
- "
{
operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
INTVAL (operands[0])));
MEM_VOLATILE_P (operands[1]) = 1;
operands[0] = const0_rtx;
-}")
+})
;; This is how we allocate stack space. If we are allocating a
;; constant amount of space and we know it is less than 4096
;; bytes, we need do nothing.
;;
;; If it is more than 4096 bytes, we need to probe the stack
-;; periodically.
+;; periodically.
(define_expand "allocate_stack"
[(set (reg:DI 30)
(plus:DI (reg:DI 30)
@@ -5149,7 +6380,6 @@
(set (match_operand:DI 0 "register_operand" "=r")
(match_dup 2))]
""
- "
{
if (GET_CODE (operands[1]) == CONST_INT
&& INTVAL (operands[1]) < 32768)
@@ -5198,8 +6428,6 @@
emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
emit_insn (gen_cmpdi (tmp, want));
emit_jump_insn (gen_bgtu (loop_label));
- if (obey_regdecls)
- gen_rtx_USE (VOIDmode, tmp);
memref = gen_rtx_MEM (DImode, want);
MEM_VOLATILE_P (memref) = 1;
@@ -5212,74 +6440,150 @@
emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
DONE;
}
-}")
+})
;; This is used by alpha_expand_prolog to do the same thing as above,
;; except we cannot at that time generate new basic blocks, so we hide
;; the loop in this one insn.
(define_insn "prologue_stack_probe_loop"
- [(unspec_volatile [(match_operand 0 "register_operand" "r")
- (match_operand 1 "register_operand" "r")] 5)]
+ [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
+ (match_operand:DI 1 "register_operand" "r")]
+ UNSPECV_PSPL)]
""
- "*
{
operands[2] = gen_label_rtx ();
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
CODE_LABEL_NUMBER (operands[2]));
- return \"stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2\";
-}"
+ return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
+}
[(set_attr "length" "16")
(set_attr "type" "multi")])
(define_expand "prologue"
[(clobber (const_int 0))]
""
- "alpha_expand_prologue (); DONE;")
+{
+ alpha_expand_prologue ();
+ DONE;
+})
+
+;; These take care of emitting the ldgp insn in the prologue. This will be
+;; an lda/ldah pair and we want to align them properly. So we have two
+;; unspec_volatile insns, the first of which emits the ldgp assembler macro
+;; and the second of which emits nothing. However, both are marked as type
+;; IADD (the default) so the alignment code in alpha.c does the right thing
+;; with them.
+
+(define_expand "prologue_ldgp"
+ [(set (match_dup 0)
+ (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
+ (set (match_dup 0)
+ (unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))]
+ ""
+{
+ operands[0] = pic_offset_table_rtx;
+ operands[1] = gen_rtx_REG (Pmode, 27);
+ operands[2] = (TARGET_EXPLICIT_RELOCS
+ ? GEN_INT (alpha_next_sequence_number++)
+ : const0_rtx);
+})
+
+(define_insn "*ldgp_er_1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand 2 "const_int_operand" "")]
+ UNSPECV_LDGP1))]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "ldah %0,0(%1)\t\t!gpdisp!%2")
+
+(define_insn "*ldgp_er_2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand 2 "const_int_operand" "")]
+ UNSPEC_LDGP2))]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "lda %0,0(%1)\t\t!gpdisp!%2")
+
+(define_insn "*prologue_ldgp_er_2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand 2 "const_int_operand" "")]
+ UNSPECV_PLDGP2))]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:")
+
+(define_insn "*prologue_ldgp_1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand 2 "const_int_operand" "")]
+ UNSPECV_LDGP1))]
+ ""
+ "ldgp %0,0(%1)\n$%~..ng:")
+
+(define_insn "*prologue_ldgp_2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand 2 "const_int_operand" "")]
+ UNSPECV_PLDGP2))]
+ ""
+ "")
+
+;; The _mcount profiling hook has special calling conventions, and
+;; does not clobber all the registers that a normal call would. So
+;; hide the fact this is a call at all.
+
+(define_insn "prologue_mcount"
+ [(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)]
+ ""
+{
+ if (TARGET_EXPLICIT_RELOCS)
+ /* Note that we cannot use a lituse_jsr reloc, since _mcount
+ cannot be called via the PLT. */
+ return "ldq $28,_mcount($29)\t\t!literal\;jsr $28,($28),_mcount";
+ else
+ return "lda $28,_mcount\;jsr $28,($28),_mcount";
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "8")])
(define_insn "init_fp"
- [(set (match_operand:DI 0 "register_operand" "r")
+ [(set (match_operand:DI 0 "register_operand" "=r")
(match_operand:DI 1 "register_operand" "r"))
- (clobber (mem:BLK (match_operand:DI 2 "register_operand" "r")))]
+ (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
""
- "mov %1,%0")
+ "bis $31,%1,%0")
(define_expand "epilogue"
- [(clobber (const_int 0))]
+ [(return)]
""
- "alpha_expand_epilogue (); DONE;")
+{
+ alpha_expand_epilogue ();
+})
-(define_expand "eh_epilogue"
- [(use (match_operand:DI 0 "register_operand" "r"))
- (use (match_operand:DI 1 "register_operand" "r"))
- (use (match_operand:DI 2 "register_operand" "r"))]
- "! TARGET_OPEN_VMS"
- "
+(define_expand "sibcall_epilogue"
+ [(return)]
+ "TARGET_ABI_OSF"
{
- alpha_eh_epilogue_sp_ofs = operands[1];
- if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
- {
- rtx ra = gen_rtx_REG (Pmode, 26);
- emit_move_insn (ra, operands[2]);
- operands[2] = ra;
- }
-}")
+ alpha_expand_epilogue ();
+ DONE;
+})
;; In creating a large stack frame, NT _must_ use ldah+lda to load
;; the frame size into a register. We use this pattern to ensure
;; we get lda instead of addq.
(define_insn "nt_lda"
- [(set (match_operand:DI 0 "register_operand" "r")
+ [(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_dup 0)
- (match_operand:DI 1 "const_int_operand" "n")] 6))]
+ (match_operand:DI 1 "const_int_operand" "n")]
+ UNSPEC_NT_LDA))]
""
"lda %0,%1(%0)")
(define_expand "builtin_longjmp"
- [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
- "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
- "
+ [(use (match_operand:DI 0 "register_operand" "r"))]
+ "TARGET_ABI_OSF"
{
/* The elements of the buffer are, in order: */
rtx fp = gen_rtx_MEM (Pmode, operands[0]);
@@ -5297,41 +6601,123 @@
/* Load the label we are jumping through into $27 so that we know
where to look for it when we get back to setjmp's function for
restoring the gp. */
- emit_indirect_jump (pv);
+ emit_jump_insn (gen_builtin_longjmp_internal (pv));
+ emit_barrier ();
DONE;
-}")
+})
-(define_insn "builtin_setjmp_receiver"
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
- "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT && TARGET_AS_CAN_SUBTRACT_LABELS"
- "\\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)"
- [(set_attr "length" "8")
- (set_attr "type" "multi")])
+;; This is effectively a copy of indirect_jump, but constrained such
+;; that register renaming cannot foil our cunning plan with $27.
+(define_insn "builtin_longjmp_internal"
+ [(set (pc)
+ (unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
+ UNSPECV_LONGJMP))]
+ ""
+ "jmp $31,(%0),0"
+ [(set_attr "type" "ibr")])
-(define_insn ""
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
- "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
- "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
+(define_insn "*builtin_setjmp_receiver_er_sl_1"
+ [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
+ "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
+
+(define_insn "*builtin_setjmp_receiver_er_1"
+ [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "br $27,$LSJ%=\n$LSJ%=:"
+ [(set_attr "type" "ibr")])
+
+(define_split
+ [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
+ && prev_nonnote_insn (insn) == operands[0]"
+ [(const_int 0)]
+ "DONE;")
+
+(define_insn "*builtin_setjmp_receiver_1"
+ [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
+ "TARGET_ABI_OSF"
+ "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)"
[(set_attr "length" "12")
(set_attr "type" "multi")])
-(define_insn "exception_receiver"
- [(unspec_volatile [(const_int 0)] 7)]
- "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
- "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
- [(set_attr "length" "12")
+(define_expand "builtin_setjmp_receiver_er"
+ [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)
+ (set (match_dup 1)
+ (unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
+ (set (match_dup 1)
+ (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
+ ""
+{
+ operands[1] = pic_offset_table_rtx;
+ operands[2] = gen_rtx_REG (Pmode, 27);
+ operands[3] = GEN_INT (alpha_next_sequence_number++);
+})
+
+(define_expand "builtin_setjmp_receiver"
+ [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
+ "TARGET_ABI_OSF"
+{
+ if (TARGET_EXPLICIT_RELOCS)
+ {
+ emit_insn (gen_builtin_setjmp_receiver_er (operands[0]));
+ DONE;
+ }
+})
+
+(define_expand "exception_receiver_er"
+ [(set (match_dup 0)
+ (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
+ (set (match_dup 0)
+ (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
+ ""
+{
+ operands[0] = pic_offset_table_rtx;
+ operands[1] = gen_rtx_REG (Pmode, 26);
+ operands[2] = GEN_INT (alpha_next_sequence_number++);
+})
+
+(define_expand "exception_receiver"
+ [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
+ "TARGET_ABI_OSF"
+{
+ if (TARGET_LD_BUGGY_LDGP)
+ operands[0] = alpha_gp_save_rtx ();
+ else if (TARGET_EXPLICIT_RELOCS)
+ {
+ emit_insn (gen_exception_receiver_er ());
+ DONE;
+ }
+ else
+ operands[0] = const0_rtx;
+})
+
+(define_insn "*exception_receiver_1"
+ [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
+ "! TARGET_LD_BUGGY_LDGP"
+ "ldgp $29,0($26)"
+ [(set_attr "length" "8")
(set_attr "type" "multi")])
+(define_insn "*exception_receiver_2"
+ [(unspec_volatile [(match_operand:DI 0 "nonimmediate_operand" "r,m")]
+ UNSPECV_EHR)]
+ "TARGET_LD_BUGGY_LDGP"
+ "@
+ bis $31,%0,$29
+ ldq $29,%0"
+ [(set_attr "type" "ilog,ild")])
+
(define_expand "nonlocal_goto_receiver"
- [(unspec_volatile [(const_int 0)] 1)
+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(set (reg:DI 27) (mem:DI (reg:DI 29)))
- (unspec_volatile [(const_int 0)] 1)
+ (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(use (reg:DI 27))]
- "TARGET_OPEN_VMS"
+ "TARGET_ABI_OPEN_VMS"
"")
(define_insn "arg_home"
- [(unspec [(const_int 0)] 0)
+ [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
(use (reg:DI 1))
(use (reg:DI 25))
(use (reg:DI 16))
@@ -5350,66 +6736,335 @@
(clobber (reg:DI 24))
(clobber (reg:DI 25))
(clobber (reg:DI 0))]
- "TARGET_OPEN_VMS"
+ "TARGET_ABI_OPEN_VMS"
"lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
[(set_attr "length" "16")
(set_attr "type" "multi")])
-;; Close the trap shadow of preceeding instructions. This is generated
+;; Load the CIW into r2 for calling __T3E_MISMATCH
+
+(define_expand "umk_mismatch_args"
+ [(set:DI (match_dup 1) (mem:DI (plus:DI (reg:DI 15) (const_int -16))))
+ (set:DI (match_dup 2) (mem:DI (plus:DI (match_dup 1) (const_int -32))))
+ (set:DI (reg:DI 1) (match_operand:DI 0 "const_int_operand" ""))
+ (set:DI (match_dup 3) (plus:DI (mult:DI (reg:DI 25)
+ (const_int 8))
+ (match_dup 2)))
+ (set:DI (reg:DI 2) (mem:DI (match_dup 3)))]
+ "TARGET_ABI_UNICOSMK"
+{
+ operands[1] = gen_reg_rtx (DImode);
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+})
+
+(define_insn "arg_home_umk"
+ [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
+ (use (reg:DI 1))
+ (use (reg:DI 2))
+ (use (reg:DI 16))
+ (use (reg:DI 17))
+ (use (reg:DI 18))
+ (use (reg:DI 19))
+ (use (reg:DI 20))
+ (use (reg:DI 21))
+ (use (reg:DI 48))
+ (use (reg:DI 49))
+ (use (reg:DI 50))
+ (use (reg:DI 51))
+ (use (reg:DI 52))
+ (use (reg:DI 53))
+ (clobber (mem:BLK (const_int 0)))
+ (parallel [
+ (clobber (reg:DI 22))
+ (clobber (reg:DI 23))
+ (clobber (reg:DI 24))
+ (clobber (reg:DI 0))
+ (clobber (reg:DI 1))
+ (clobber (reg:DI 2))
+ (clobber (reg:DI 3))
+ (clobber (reg:DI 4))
+ (clobber (reg:DI 5))
+ (clobber (reg:DI 6))
+ (clobber (reg:DI 7))
+ (clobber (reg:DI 8))])]
+ "TARGET_ABI_UNICOSMK"
+ "laum $4,__T3E_MISMATCH($31)\;sll $4,32,$4\;lalm $4,__T3E_MISMATCH($4)\;lal $4,__T3E_MISMATCH($4)\;jsr $3,($4)"
+ [(set_attr "length" "16")
+ (set_attr "type" "multi")])
+
+;; Prefetch data.
+;;
+;; On EV4, these instructions are nops -- no load occurs.
+;;
+;; On EV5, these instructions act as a normal load, and thus can trap
+;; if the address is invalid. The OS may (or may not) handle this in
+;; the entMM fault handler and suppress the fault. If so, then this
+;; has the effect of a read prefetch instruction.
+;;
+;; On EV6, these become official prefetch instructions.
+
+(define_insn "prefetch"
+ [(prefetch (match_operand:DI 0 "address_operand" "p")
+ (match_operand:DI 1 "const_int_operand" "n")
+ (match_operand:DI 2 "const_int_operand" "n"))]
+ "TARGET_FIXUP_EV5_PREFETCH || TARGET_CPU_EV6"
+{
+ /* Interpret "no temporal locality" as this data should be evicted once
+ it is used. The "evict next" alternatives load the data into the cache
+ and leave the LRU eviction counter pointing to that block. */
+ static const char * const alt[2][2] = {
+ {
+ "lds $f31,%a0", /* read, evict next */
+ "ldl $31,%a0", /* read, evict last */
+ },
+ {
+ "ldt $f31,%a0", /* write, evict next */
+ "ldq $31,%a0", /* write, evict last */
+ }
+ };
+
+ bool write = INTVAL (operands[1]) != 0;
+ bool lru = INTVAL (operands[2]) != 0;
+
+ return alt[write][lru];
+}
+ [(set_attr "type" "ild")])
+
+;; Close the trap shadow of preceding instructions. This is generated
;; by alpha_reorg.
(define_insn "trapb"
- [(unspec_volatile [(const_int 0)] 4)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)]
""
"trapb"
[(set_attr "type" "misc")])
-;; No-op instructions used by machine-dependant reorg to preserve
+;; No-op instructions used by machine-dependent reorg to preserve
;; alignment for instruction issue.
+;; The Unicos/Mk assembler does not support these opcodes.
(define_insn "nop"
[(const_int 0)]
""
- "nop"
+ "bis $31,$31,$31"
[(set_attr "type" "ilog")])
(define_insn "fnop"
[(const_int 1)]
"TARGET_FP"
- "fnop"
+ "cpys $f31,$f31,$f31"
[(set_attr "type" "fcpys")])
(define_insn "unop"
[(const_int 2)]
""
- "unop")
+ "ldq_u $31,0($30)")
+
+;; On Unicos/Mk we use a macro for aligning code.
(define_insn "realign"
- [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)]
+ [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
+ UNSPECV_REALIGN)]
""
- ".align %0 #realign")
-
-;; Peepholes go at the end.
+{
+ if (TARGET_ABI_UNICOSMK)
+ return "gcc@code@align %0";
+ else
+ return ".align %0 #realign";
+})
+
+;; The call patterns are at the end of the file because their
+;; wildcard operand0 interferes with nice recognition.
+
+(define_insn "*call_value_osf_1_er"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
+ (match_operand 2 "" "")))
+ (use (reg:DI 29))
+ (clobber (reg:DI 26))]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "@
+ jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
+ bsr $26,$%1..ng
+ ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "12,*,16")])
+
+;; We must use peep2 instead of a split because we need accurate life
+;; information for $gp. Consider the case of { bar(); while (1); }.
+(define_peephole2
+ [(parallel [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "call_operand" ""))
+ (match_operand 2 "" "")))
+ (use (reg:DI 29))
+ (clobber (reg:DI 26))])]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
+ && ! current_file_function_operand (operands[1], Pmode)
+ && peep2_regno_dead_p (1, 29)"
+ [(parallel [(set (match_dup 0)
+ (call (mem:DI (match_dup 3))
+ (match_dup 2)))
+ (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
+ (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (use (match_dup 1))
+ (use (match_dup 4))])]
+{
+ if (CONSTANT_P (operands[1]))
+ {
+ operands[3] = gen_rtx_REG (Pmode, 27);
+ operands[4] = GEN_INT (alpha_next_sequence_number++);
+ emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
+ operands[1], operands[4]));
+ }
+ else
+ {
+ operands[3] = operands[1];
+ operands[1] = const0_rtx;
+ operands[4] = const0_rtx;
+ }
+})
+
+(define_peephole2
+ [(parallel [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "call_operand" ""))
+ (match_operand 2 "" "")))
+ (use (reg:DI 29))
+ (clobber (reg:DI 26))])]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
+ && ! current_file_function_operand (operands[1], Pmode)
+ && ! peep2_regno_dead_p (1, 29)"
+ [(parallel [(set (match_dup 0)
+ (call (mem:DI (match_dup 3))
+ (match_dup 2)))
+ (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
+ (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (use (match_dup 1))
+ (use (match_dup 5))])
+ (set (reg:DI 29)
+ (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
+ (set (reg:DI 29)
+ (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
+{
+ if (CONSTANT_P (operands[1]))
+ {
+ operands[3] = gen_rtx_REG (Pmode, 27);
+ operands[5] = GEN_INT (alpha_next_sequence_number++);
+ emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
+ operands[1], operands[5]));
+ }
+ else
+ {
+ operands[3] = operands[1];
+ operands[1] = const0_rtx;
+ operands[5] = const0_rtx;
+ }
+ operands[4] = GEN_INT (alpha_next_sequence_number++);
+})
+
+;; We add a blockage unspec_volatile to prevent insns from moving down
+;; from above the call to in between the call and the ldah gpdisp.
+(define_insn "*call_value_osf_2_er"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
+ (match_operand 2 "" "")))
+ (set (reg:DI 26)
+ (plus:DI (pc) (const_int 4)))
+ (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (use (match_operand 3 "" ""))
+ (use (match_operand 4 "const_int_operand" ""))]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "jsr $26,(%1),%3%J4"
+ [(set_attr "type" "jsr")])
+
+(define_insn "*call_value_osf_1_noreturn"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
+ (match_operand 2 "" "")))
+ (use (reg:DI 29))
+ (clobber (reg:DI 26))]
+ "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ "@
+ jsr $26,($27),0
+ bsr $26,$%1..ng
+ jsr $26,%1"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "*,*,8")])
+
+(define_insn "*call_value_osf_1"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
+ (match_operand 2 "" "")))
+ (use (reg:DI 29))
+ (clobber (reg:DI 26))]
+ "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "@
+ jsr $26,($27),0\;ldgp $29,0($26)
+ bsr $26,$%1..ng
+ jsr $26,%1\;ldgp $29,0($26)"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "12,*,16")])
+
+(define_insn "*sibcall_value_osf_1_er"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
+ (match_operand 2 "" "")))
+ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "@
+ br $31,$%1..ng
+ ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "*,8")])
+
+(define_insn "*sibcall_value_osf_1"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
+ (match_operand 2 "" "")))
+ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
+ "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "@
+ br $31,$%1..ng
+ lda $27,%1\;jmp $31,($27),%1"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "*,8")])
+
+(define_insn "*call_value_nt_1"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,s"))
+ (match_operand 2 "" "")))
+ (clobber (reg:DI 26))]
+ "TARGET_ABI_WINDOWS_NT"
+ "@
+ jsr $26,(%1)
+ bsr $26,%1
+ jsr $26,%1"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "*,*,12")])
+
+(define_insn "*call_value_vms_1"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
+ (match_operand 2 "" "")))
+ (use (match_operand:DI 3 "nonimmediate_operand" "r,m"))
+ (use (reg:DI 25))
+ (use (reg:DI 26))
+ (clobber (reg:DI 27))]
+ "TARGET_ABI_OPEN_VMS"
+ "@
+ mov %3,$27\;jsr $26,0\;ldq $27,0($29)
+ ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "12,16")])
+
+(define_insn "*call_value_umk"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "call_operand" "r"))
+ (match_operand 2 "" "")))
+ (use (reg:DI 25))
+ (clobber (reg:DI 26))]
+ "TARGET_ABI_UNICOSMK"
+ "jsr $26,(%1)"
+ [(set_attr "type" "jsr")])
-;; Optimize sign-extension of SImode loads. This shows up in the wake of
-;; reload when converting fp->int.
-;;
-;; ??? What to do now that we actually care about the packing and
-;; alignment of instructions? Perhaps reload can be enlightened, or
-;; the peephole pass moved up after reload but before sched2?
-;
-;(define_peephole
-; [(set (match_operand:SI 0 "register_operand" "=r")
-; (match_operand:SI 1 "memory_operand" "m"))
-; (set (match_operand:DI 2 "register_operand" "=r")
-; (sign_extend:DI (match_dup 0)))]
-; "dead_or_set_p (insn, operands[0])"
-; "ldl %2,%1")
-;
-;(define_peephole
-; [(set (match_operand:SI 0 "register_operand" "=r")
-; (match_operand:SI 1 "hard_fp_register_operand" "f"))
-; (set (match_operand:DI 2 "register_operand" "=r")
-; (sign_extend:DI (match_dup 0)))]
-; "TARGET_FIX && dead_or_set_p (insn, operands[0])"
-; "ftois %1,%2")
diff --git a/contrib/gcc/config/alpha/alpha32.h b/contrib/gcc/config/alpha/alpha32.h
index 3cbcfe1..8d9df0b 100644
--- a/contrib/gcc/config/alpha/alpha32.h
+++ b/contrib/gcc/config/alpha/alpha32.h
@@ -30,13 +30,13 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#undef TARGET_WINDOWS_NT
-#define TARGET_WINDOWS_NT 1
+#undef TARGET_ABI_WINDOWS_NT
+#define TARGET_ABI_WINDOWS_NT 1
/* WinNT (and thus Interix) use unsigned int */
#define SIZE_TYPE "unsigned int"
-/* Pointer is 32 bits but the hardware has 64-bit addresses, sign extended. */
+/* Pointer is 32 bits but the hardware has 64-bit addresses, sign extended. */
#undef POINTER_SIZE
#define POINTER_SIZE 32
#define POINTERS_EXTEND_UNSIGNED 0
@@ -71,34 +71,15 @@ Boston, MA 02111-1307, USA. */
#undef TRAMPOLINE_SIZE
#define TRAMPOLINE_SIZE 24
+/* The alignment of a trampoline, in bits. */
+
+#undef TRAMPOLINE_ALIGNMENT
+#define TRAMPOLINE_ALIGNMENT 32
+
/* 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. */
+ CXT is an RTX for the static chain value for the function. */
#undef INITIALIZE_TRAMPOLINE
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 20, 16, 12)
-
-/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
- Used for C++ multiple inheritance. */
-
-#undef ASM_OUTPUT_MI_THUNK
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-do { \
- char *op, *fn_name = XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0); \
- int reg; \
- \
- /* Mark end of prologue. */ \
- output_end_prologue (FILE); \
- \
- /* Rely on the assembler to macro expand a large delta. */ \
- reg = aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION))) ? 17 : 16; \
- fprintf (FILE, "\tlda $%d,%ld($%d)\n", reg, (long)(DELTA), reg); \
- \
- op = "jsr"; \
- if (current_file_function_operand (XEXP (DECL_RTL (FUNCTION), 0))) \
- op = "br"; \
- fprintf (FILE, "\t%s $31,", op); \
- assemble_name (FILE, fn_name); \
- fputc ('\n', FILE); \
-} while (0)
diff --git a/contrib/gcc/config/alpha/crtfastmath.c b/contrib/gcc/config/alpha/crtfastmath.c
new file mode 100644
index 0000000..4651ee7
--- /dev/null
+++ b/contrib/gcc/config/alpha/crtfastmath.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ * Contributed by Richard Henderson (rth@redhat.com)
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * In addition to the permissions in the GNU General Public License, the
+ * Free Software Foundation gives you unlimited permission to link the
+ * compiled version of this file with other programs, and to distribute
+ * those programs without any restriction coming from the use of this
+ * file. (The General Public License restrictions do apply in other
+ * respects; for example, they cover modification of the file, and
+ * distribution when not linked into another program.)
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * As a special exception, if you link this library with files
+ * compiled with GCC to produce an executable, this does not cause
+ * the resulting executable to be covered by the GNU General Public License.
+ * This exception does not however invalidate any other reasons why
+ * the executable file might be covered by the GNU General Public License.
+ */
+
+/* Assume OSF/1 compatible interfaces. */
+
+extern void __ieee_set_fp_control (unsigned long int);
+
+#define IEEE_MAP_DMZ (1UL<<12) /* Map denorm inputs to zero */
+#define IEEE_MAP_UMZ (1UL<<13) /* Map underflowed outputs to zero */
+
+static void __attribute__((constructor))
+set_fast_math (void)
+{
+ __ieee_set_fp_control (IEEE_MAP_DMZ | IEEE_MAP_UMZ);
+}
diff --git a/contrib/gcc/config/alpha/lib1funcs.asm b/contrib/gcc/config/alpha/lib1funcs.asm
index e63180a..6bea231 100644
--- a/contrib/gcc/config/alpha/lib1funcs.asm
+++ b/contrib/gcc/config/alpha/lib1funcs.asm
@@ -8,11 +8,12 @@ later version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
-compiled version of this file with other programs, and to distribute
-those programs without any restriction coming from the use of this
-file. (The General Public License restrictions do apply in other
-respects; for example, they cover modification of the file, and
-distribution when not linked into another program.)
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -21,14 +22,8 @@ General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* This had to be written in assembler because the division functions
use a non-standard calling convention.
diff --git a/contrib/gcc/config/alpha/linux-elf.h b/contrib/gcc/config/alpha/linux-elf.h
index fc07127..6430059 100644
--- a/contrib/gcc/config/alpha/linux-elf.h
+++ b/contrib/gcc/config/alpha/linux-elf.h
@@ -37,11 +37,6 @@ Boston, MA 02111-1307, USA. */
#endif
#ifndef USE_GNULIBC_1
-#undef DEFAULT_VTABLE_THUNKS
-#define DEFAULT_VTABLE_THUNKS 1
-#endif
-
-#ifndef USE_GNULIBC_1
#undef LIB_SPEC
#define LIB_SPEC \
"%{shared:-lc}%{!shared:%{pthread:-lpthread }%{profile:-lc_p}%{!profile:-lc}} "
diff --git a/contrib/gcc/config/alpha/linux.h b/contrib/gcc/config/alpha/linux.h
index b8eb9e9..8a1b93f 100644
--- a/contrib/gcc/config/alpha/linux.h
+++ b/contrib/gcc/config/alpha/linux.h
@@ -25,22 +25,84 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
-"-Dlinux -Dunix -Asystem(linux) -D_LONGLONG -D__alpha__ " \
+"-Dlinux -Dunix -Asystem=linux -D_LONGLONG -D__alpha__ " \
SUB_CPP_PREDEFINES
-#undef LIB_SPEC
-#define LIB_SPEC "%{pg:-lgmon} %{pg:-lc_p} %{!pg:-lc}"
-
-/* Generate calls to memcpy, etc., not bcopy, etc. */
-#define TARGET_MEM_FUNCTIONS 1
+/* The GNU C++ standard library requires that these macros be defined. */
+#undef CPLUSPLUS_CPP_SPEC
+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-#undef FUNCTION_PROFILER
-#define FUNCTION_PROFILER(FILE, LABELNO) \
- fputs ("\tlda $28,_mcount\n\tjsr $28,($28),_mcount\n", (FILE))
+#undef LIB_SPEC
+#define LIB_SPEC \
+ "%{shared: -lc} \
+ %{!shared: %{pthread:-lpthread} \
+ %{profile:-lc_p} %{!profile: -lc}}"
/* Show that we need a GP when profiling. */
+#undef TARGET_PROFILING_NEEDS_GP
#define TARGET_PROFILING_NEEDS_GP 1
/* Don't care about faults in the prologue. */
#undef TARGET_CAN_FAULT_IN_PROLOGUE
#define TARGET_CAN_FAULT_IN_PROLOGUE 1
+
+/* OS fixes up EV5 data fault on prefetch. */
+#undef TARGET_FIXUP_EV5_PREFETCH
+#define TARGET_FIXUP_EV5_PREFETCH 1
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+
+/* Define this so that all GNU/Linux targets handle the same pragmas. */
+#define HANDLE_PRAGMA_PACK_PUSH_POP
+
+/* Do code reading to identify a signal frame, and set the frame
+ state data appropriately. See unwind-dw2.c for the structs. */
+
+#ifdef IN_LIBGCC2
+#include <signal.h>
+#include <sys/ucontext.h>
+#endif
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
+ do { \
+ unsigned int *pc_ = (CONTEXT)->ra; \
+ struct sigcontext *sc_; \
+ long new_cfa_, i_; \
+ \
+ if (pc_[0] != 0x47fe0410 /* mov $30,$16 */ \
+ || pc_[2] != 0x00000083 /* callsys */) \
+ break; \
+ if (pc_[1] == 0x201f0067) /* lda $0,NR_sigreturn */ \
+ sc_ = (CONTEXT)->cfa; \
+ else if (pc_[1] == 0x201f015f) /* lda $0,NR_rt_sigreturn */ \
+ { \
+ struct rt_sigframe { \
+ struct siginfo info; \
+ struct ucontext uc; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->uc.uc_mcontext; \
+ } \
+ else \
+ break; \
+ new_cfa_ = sc_->sc_regs[30]; \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->cfa_reg = 30; \
+ (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
+ for (i_ = 0; i_ < 30; ++i_) \
+ { \
+ (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_].loc.offset \
+ = (long)&sc_->sc_regs[i_] - new_cfa_; \
+ } \
+ for (i_ = 0; i_ < 31; ++i_) \
+ { \
+ (FS)->regs.reg[i_+32].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_+32].loc.offset \
+ = (long)&sc_->sc_fpregs[i_] - new_cfa_; \
+ } \
+ (FS)->regs.reg[31].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[31].loc.offset = (long)&sc_->sc_pc - new_cfa_; \
+ (FS)->retaddr_column = 31; \
+ goto SUCCESS; \
+ } while (0)
diff --git a/contrib/gcc/config/alpha/netbsd.h b/contrib/gcc/config/alpha/netbsd.h
index 5189064..7eacce2 100644
--- a/contrib/gcc/config/alpha/netbsd.h
+++ b/contrib/gcc/config/alpha/netbsd.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler,
for Alpha NetBSD systems.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -23,17 +23,75 @@ Boston, MA 02111-1307, USA. */
#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)
#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D_LONGLONG -Dnetbsd -Dunix " SUB_CPP_PREDEFINES
+#define CPP_PREDEFINES \
+ "-D__NetBSD__ -D__ELF__ -Asystem=unix -Asystem=NetBSD"
-#undef LIB_SPEC
-#define LIB_SPEC "%{pg:-lgmon} %{pg:-lc_p} %{!pg:-lc}"
-/* Generate calls to memcpy, etc., not bcopy, etc. */
-#define TARGET_MEM_FUNCTIONS
+/* Show that we need a GP when profiling. */
+#undef TARGET_PROFILING_NEEDS_GP
+#define TARGET_PROFILING_NEEDS_GP 1
-#undef FUNCTION_PROFILER
-#define FUNCTION_PROFILER(FILE, LABELNO) \
- fputs ("\tlda $28,_mcount\n\tjsr $28,($28),_mcount\n", (FILE))
-/* Show that we need a GP when profiling. */
-#define TARGET_PROFILING_NEEDS_GP
+/* Provide a CPP_SPEC appropriate for NetBSD/alpha. In addition to
+ the standard NetBSD specs, we also handle Alpha FP mode indications. */
+
+#undef CPP_SPEC
+#define CPP_SPEC \
+ "%{mieee:-D_IEEE_FP} \
+ %{mieee-with-inexact:-D_IEEE_FP -D_IEEE_FP_INEXACT} \
+ %(cpp_cpu) %(cpp_subtarget)"
+
+#undef CPP_SUBTARGET_SPEC
+#define CPP_SUBTARGET_SPEC \
+ "%{posix:-D_POSIX_SOURCE}"
+
+
+/* Provide a LINK_SPEC appropriate for a NetBSD/alpha ELF target.
+ This is a copy of LINK_SPEC from <netbsd-elf.h> tweaked for
+ the alpha target. */
+
+#undef LINK_SPEC
+#define LINK_SPEC \
+ "%{G*} %{relax:-relax} \
+ %{O*:-O3} %{!O*:-O1} \
+ %{assert*} %{R*} \
+ %{shared:-shared} \
+ %{!shared: \
+ -dc -dp \
+ %{!nostdlib: \
+ %{!r*: \
+ %{!e*:-e __start}}} \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /usr/libexec/ld.elf_so}} \
+ %{static:-static}}"
+
+
+/* Provide an ENDFILE_SPEC appropriate for NetBSD/alpha ELF. Here we
+ add crtend.o, which provides part of the support for getting
+ C++ file-scope static objects deconstructed after exiting "main".
+
+ We also need to handle the GCC option `-ffast-math'. */
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "%{ffast-math|funsafe-math-optimizations:crtfm%O%s} \
+ %{!shared:crtend%O%s} %{shared:crtendS%O%s}"
+
+
+/* Make gcc agree with <machine/ansi.h> */
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+
+#undef WCHAR_UNSIGNED
+#define WCHAR_UNSIGNED 0
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE 32
+
+#undef WINT_TYPE
+#define WINT_TYPE "int"
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (NetBSD/alpha ELF)");
diff --git a/contrib/gcc/config/alpha/openbsd.h b/contrib/gcc/config/alpha/openbsd.h
index 60591d5..3424112 100644
--- a/contrib/gcc/config/alpha/openbsd.h
+++ b/contrib/gcc/config/alpha/openbsd.h
@@ -41,7 +41,7 @@ Boston, MA 02111-1307, USA. */
"%{!nostdlib:%{!r*:%{!e*:-e __start}}} -dc -dp %{assert*}"
/* run-time target specifications */
-#define CPP_PREDEFINES "-D__unix__ -D__ANSI_COMPAT -Asystem(unix) \
+#define CPP_PREDEFINES "-D__unix__ -D__ANSI_COMPAT -Asystem=unix \
-D__OpenBSD__ -D__alpha__ -D__alpha"
/* Layout of source language data types. */
@@ -100,8 +100,8 @@ Boston, MA 02111-1307, USA. */
fprintf (FILE, "\t.set noat\n"); \
if (TARGET_SUPPORT_ARCH) \
fprintf (FILE, "\t.arch %s\n", \
- alpha_cpu == PROCESSOR_EV6 ? "ev6" \
- : (alpha_cpu == PROCESSOR_EV5 \
+ TARGET_CPU_EV6 ? "ev6" \
+ : (TARGET_CPU_EV5 \
? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5") \
: "ev4")); \
\
diff --git a/contrib/gcc/config/alpha/osf.h b/contrib/gcc/config/alpha/osf.h
index 5054444..250974c 100644
--- a/contrib/gcc/config/alpha/osf.h
+++ b/contrib/gcc/config/alpha/osf.h
@@ -1,5 +1,6 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha on OSF/1.
- Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001
+ Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
@@ -24,11 +25,21 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_AS_CAN_SUBTRACT_LABELS
#define TARGET_AS_CAN_SUBTRACT_LABELS 1
+/* The GEM libraries for X_float are present, though not used by C. */
+
+#undef TARGET_HAS_XFLOATING_LIBS
+#define TARGET_HAS_XFLOATING_LIBS 1
+
/* Names to predefine in the preprocessor for this target machine. */
#define CPP_PREDEFINES "\
-Dunix -D__osf__ -D_LONGLONG -DSYSTYPE_BSD \
--D_SYSTYPE_BSD -Asystem(unix) -Asystem(xpg4)"
+-D_SYSTYPE_BSD -Asystem=unix -Asystem=xpg4"
+
+/* Tru64 UNIX V5 requires additional definitions for 16 byte long double
+ support. Empty by default. */
+
+#define CPP_XFLOAT_SPEC ""
/* Accept DEC C flags for multithreaded programs. We use _PTHREAD_USE_D4
instead of PTHREAD_USE_D4 since both have the same effect and the former
@@ -36,7 +47,7 @@ Boston, MA 02111-1307, USA. */
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC \
-"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4}"
+"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4} %(cpp_xfloat)"
/* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf. */
@@ -46,15 +57,20 @@ Boston, MA 02111-1307, USA. */
/* Pass "-G 8" to ld because Alpha's CC does. Pass -O3 if we are
optimizing, -O1 if we are not. Pass -shared, -non_shared or
- -call_shared as appropriate. Also pass -pg. */
+ -call_shared as appropriate. Pass -hidden_symbol so that our
+ constructor and call-frame data structures are not accidentally
+ overridden. */
#define LINK_SPEC \
"-G 8 %{O*:-O3} %{!O*:-O1} %{static:-non_shared} \
- %{!static:%{shared:-shared} %{!shared:-call_shared}} %{pg} %{taso} \
- %{rpath*}"
+ %{!static:%{shared:-shared -hidden_symbol _GLOBAL_*} \
+ %{!shared:-call_shared}} %{pg} %{taso} %{rpath*}"
#define STARTFILE_SPEC \
"%{!shared:%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}"
+#define ENDFILE_SPEC \
+ "%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
+
#define MD_STARTFILE_PREFIX "/usr/lib/cmplrs/cc/"
#define ASM_FILE_START(FILE) \
@@ -65,18 +81,22 @@ Boston, MA 02111-1307, USA. */
fprintf (FILE, "\t.set noat\n"); \
if (TARGET_SUPPORT_ARCH) \
fprintf (FILE, "\t.arch %s\n", \
- alpha_cpu == PROCESSOR_EV6 ? "ev6" \
- : (alpha_cpu == PROCESSOR_EV5 \
+ TARGET_CPU_EV6 ? "ev6" \
+ : (TARGET_CPU_EV5 \
? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5") \
: "ev4")); \
\
ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
}
+/* Tru64 UNIX V5.1 requires a special as flag. Empty by default. */
+
+#define ASM_OLDAS_SPEC ""
+
/* No point in running CPP on our assembler output. */
#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GAS) != 0
/* Don't pass -g to GNU as, because some versions don't accept this option. */
-#define ASM_SPEC "%{malpha-as:-g} -nocpp %{pg}"
+#define ASM_SPEC "%{malpha-as:-g %(asm_oldas)} -nocpp %{pg}"
#else
/* In OSF/1 v3.2c, the assembler by default does not output file names which
causes mips-tfile to fail. Passing -g to the assembler fixes this problem.
@@ -85,7 +105,7 @@ Boston, MA 02111-1307, USA. */
if the user does not specify -g. If we don't pass -g, then mips-tfile
will need to be fixed to work in this case. Pass -O0 since some
optimization are broken and don't help us anyway. */
-#define ASM_SPEC "%{!mgas:-g} -nocpp %{pg} -O0"
+#define ASM_SPEC "%{!mgas:-g %(asm_oldas)} -nocpp %{pg} -O0"
#endif
/* Specify to run a post-processor, mips-tfile after the assembler
@@ -114,6 +134,11 @@ Boston, MA 02111-1307, USA. */
#endif
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "cpp_xfloat", CPP_XFLOAT_SPEC }, \
+ { "asm_oldas", ASM_OLDAS_SPEC }
+
/* Indicate that we have a stamp.h to use. */
#ifndef CROSS_COMPILE
#define HAVE_STAMP_H 1
@@ -122,10 +147,13 @@ Boston, MA 02111-1307, USA. */
/* Attempt to turn on access permissions for the stack. */
#define TRANSFER_FROM_TRAMPOLINE \
+extern void __enable_execute_stack PARAMS ((void *)); \
+ \
void \
__enable_execute_stack (addr) \
void *addr; \
{ \
+ extern int mprotect PARAMS ((const void *, size_t, int)); \
long size = getpagesize (); \
long mask = ~(size-1); \
char *page = (char *) (((long) addr) & mask); \
@@ -135,3 +163,49 @@ __enable_execute_stack (addr) \
if (mprotect (page, end - page, 7) < 0) \
perror ("mprotect of trampoline code"); \
}
+
+/* Digital UNIX V4.0E (1091)/usr/include/sys/types.h 4.3.49.9 1997/08/14 */
+#define SIZE_TYPE "long unsigned int"
+#define PTRDIFF_TYPE "long int"
+
+/* The linker will stick __main into the .init section. */
+#define HAS_INIT_SECTION
+#define LD_INIT_SWITCH "-init"
+#define LD_FINI_SWITCH "-fini"
+
+/* Select a format to encode pointers in exception handling data. CODE
+ is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
+ true if the symbol may be affected by dynamic relocations.
+
+ We really ought to be using the SREL32 relocations that ECOFF has,
+ but no version of the native assembler supports creating such things,
+ and Compaq has no plans to rectify this. Worse, the dynamic loader
+ cannot handle unaligned relocations, so we have to make sure that
+ things get padded appropriately. */
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
+ (TARGET_GAS \
+ ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) \
+ : DW_EH_PE_aligned)
+
+/* This is how we tell the assembler that a symbol is weak. */
+
+#define ASM_OUTPUT_WEAK_ALIAS(FILE, NAME, VALUE) \
+ do \
+ { \
+ ASM_GLOBALIZE_LABEL (FILE, NAME); \
+ fputs ("\t.weakext\t", FILE); \
+ assemble_name (FILE, NAME); \
+ if (VALUE) \
+ { \
+ fputc (' ', FILE); \
+ assemble_name (FILE, VALUE); \
+ } \
+ fputc ('\n', FILE); \
+ } \
+ while (0)
+
+#define ASM_WEAKEN_LABEL(FILE, NAME) ASM_OUTPUT_WEAK_ALIAS(FILE, NAME, 0)
+
+/* Handle #pragma weak and #pragma pack. */
+#undef HANDLE_SYSV_PRAGMA
+#define HANDLE_SYSV_PRAGMA 1
diff --git a/contrib/gcc/config/alpha/osf2or3.h b/contrib/gcc/config/alpha/osf2or3.h
index 5abdb0e..9d8c8f5 100644
--- a/contrib/gcc/config/alpha/osf2or3.h
+++ b/contrib/gcc/config/alpha/osf2or3.h
@@ -24,7 +24,9 @@ Boston, MA 02111-1307, USA. */
#define LIB_SPEC "%{p:-lprof1} %{pg:-lprof1} %{a:-lprof2} -lc"
/* As of OSF 3.2, as still can't subtract adjacent labels. */
-
#undef TARGET_AS_CAN_SUBTRACT_LABELS
#define TARGET_AS_CAN_SUBTRACT_LABELS 0
+/* The frame unwind data requires the ability to subtract labels. */
+#undef DWARF2_UNWIND_INFO
+#define DWARF2_UNWIND_INFO 0
diff --git a/contrib/gcc/config/alpha/osf5.h b/contrib/gcc/config/alpha/osf5.h
new file mode 100644
index 0000000..c832c57
--- /dev/null
+++ b/contrib/gcc/config/alpha/osf5.h
@@ -0,0 +1,54 @@
+/* Definitions of target machine for GNU compiler, for DEC Alpha on Tru64 5.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+
+ This file is part of GNU CC.
+
+ GNU CC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU CC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU CC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#undef LONG_DOUBLE_TYPE_SIZE
+#define LONG_DOUBLE_TYPE_SIZE 128
+
+/* Tru64 UNIX V5 has a 16 byte long double type and requires __X_FLOAT to be
+ defined to get the appropriate prototypes for the long double functions
+ in <math.h>. */
+
+#undef CPP_XFLOAT_SPEC
+#define CPP_XFLOAT_SPEC "-D__X_FLOAT"
+
+/* In Tru64 UNIX V5.1, Compaq introduced a new assembler
+ (/usr/lib/cmplrs/cc/adu) which currently (versions between 3.04.29 and
+ 3.04.32) breaks mips-tfile. Passing the undocumented -oldas flag reverts
+ to using the old assembler (/usr/lib/cmplrs/cc/as[01]).
+
+ The V5.0 and V5.0A assemblers silently ignore -oldas, so it can be
+ specified here.
+
+ It is clearly not desirable to depend on this undocumented flag, and
+ Compaq wants -oldas to go away soon, but until they have released a
+ new adu that works with mips-tfile, this is the only option.
+
+ In some versions of the DTK, the assembler driver invokes ld after
+ assembly. This has been fixed in current versions, but adding -c
+ works as expected for all versions. */
+
+#undef ASM_OLDAS_SPEC
+#define ASM_OLDAS_SPEC "-oldas -c"
+
+/* The linker appears to perform invalid code optimizations that result
+ in the ldgp emitted for the exception_receiver pattern being incorrectly
+ linked. */
+#undef TARGET_LD_BUGGY_LDGP
+#define TARGET_LD_BUGGY_LDGP 1
diff --git a/contrib/gcc/config/alpha/qrnnd.asm b/contrib/gcc/config/alpha/qrnnd.asm
new file mode 100644
index 0000000..d6373ec
--- /dev/null
+++ b/contrib/gcc/config/alpha/qrnnd.asm
@@ -0,0 +1,163 @@
+ # Alpha 21064 __udiv_qrnnd
+ # Copyright (C) 1992, 1994, 1995, 2000 Free Software Foundation, Inc.
+
+ # This file is part of GCC.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License as published by
+ # the Free Software Foundation; either version 2 of the License, or (at your
+ # option) any later version.
+
+ # In addition to the permissions in the GNU General Public License, the
+ # Free Software Foundation gives you unlimited permission to link the
+ # compiled version of this file with other programs, and to distribute
+ # those programs without any restriction coming from the use of this
+ # file. (The General Public License restrictions do apply in other
+ # respects; for example, they cover modification of the file, and
+ # distribution when not linked into another program.)
+
+ # This file is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU General Public License
+ # along with GCC; see the file COPYING. If not, write to the
+ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+ .set noreorder
+ .set noat
+
+ .text
+
+ .globl __udiv_qrnnd
+ .ent __udiv_qrnnd
+__udiv_qrnnd:
+ .frame $30,0,$26,0
+ .prologue 0
+
+#define cnt $2
+#define tmp $3
+#define rem_ptr $16
+#define n1 $17
+#define n0 $18
+#define d $19
+#define qb $20
+#define AT $at
+
+ ldiq cnt,16
+ blt d,$largedivisor
+
+$loop1: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,$loop1
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+$largedivisor:
+ and n0,1,$4
+
+ srl n0,1,n0
+ sll n1,63,tmp
+ or tmp,n0,n0
+ srl n1,1,n1
+
+ and d,1,$6
+ srl d,1,$5
+ addq $5,$6,$5
+
+$loop2: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,$loop2
+
+ addq n1,n1,n1
+ addq $4,n1,n1
+ bne $6,$Odd
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+$Odd:
+ /* q' in n0. r' in n1 */
+ addq n1,n0,n1
+
+ cmpult n1,n0,tmp # tmp := carry from addq
+ subq n1,d,AT
+ addq n0,tmp,n0
+ cmovne tmp,AT,n1
+
+ cmpult n1,d,tmp
+ addq n0,1,AT
+ cmoveq tmp,AT,n0
+ subq n1,d,AT
+ cmoveq tmp,AT,n1
+
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+ .end __udiv_qrnnd
diff --git a/contrib/gcc/config/alpha/t-alpha b/contrib/gcc/config/alpha/t-alpha
new file mode 100644
index 0000000..d0b58d6
--- /dev/null
+++ b/contrib/gcc/config/alpha/t-alpha
@@ -0,0 +1,2 @@
+# This is a support routine for longlong.h, used by libgcc2.c.
+LIB2FUNCS_EXTRA = $(srcdir)/config/alpha/qrnnd.asm
diff --git a/contrib/gcc/config/alpha/t-crtfm b/contrib/gcc/config/alpha/t-crtfm
new file mode 100644
index 0000000..7076b51
--- /dev/null
+++ b/contrib/gcc/config/alpha/t-crtfm
@@ -0,0 +1,4 @@
+EXTRA_PARTS += crtfastmath.o
+
+crtfastmath.o: $(srcdir)/config/alpha/crtfastmath.c $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtfastmath.o $(srcdir)/config/alpha/crtfastmath.c
diff --git a/contrib/gcc/config/alpha/t-ieee b/contrib/gcc/config/alpha/t-ieee
index a1f93db..fe549df 100644
--- a/contrib/gcc/config/alpha/t-ieee
+++ b/contrib/gcc/config/alpha/t-ieee
@@ -1,6 +1,2 @@
# All alphas get an IEEE complaint set of libraries.
-MULTILIB_OPTIONS = mieee
-MULTILIB_DIRNAMES = ieee
-
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
+TARGET_LIBGCC2_CFLAGS += -mieee
diff --git a/contrib/gcc/config/alpha/t-interix b/contrib/gcc/config/alpha/t-interix
index d6d80e9..3d570c6 100644
--- a/contrib/gcc/config/alpha/t-interix
+++ b/contrib/gcc/config/alpha/t-interix
@@ -1,16 +1,7 @@
# t-interix
# System headers will track gcc's needs.
-# Even LANG_EXTRA_HEADERS may be temporary.
-USER_H=$(LANG_EXTRA_HEADERS)
-
-# We don't want this one either.
-INSTALL_ASSERT_H=
-
-
-
-CROSS_LIBGCC1 = libgcc1-asm.a
-LIBGCC1 = libgcc1-asm.a
+USER_H=
LIB1ASMSRC = alpha/lib1funcs.asm
LIB1ASMFUNCS = _divqu _divq _divlu _divl _remqu _remq _remlu _reml
diff --git a/contrib/gcc/config/alpha/t-osf4 b/contrib/gcc/config/alpha/t-osf4
new file mode 100644
index 0000000..e9c451b
--- /dev/null
+++ b/contrib/gcc/config/alpha/t-osf4
@@ -0,0 +1,22 @@
+# Compile crtbeginS.o and crtendS.o with pic.
+CRTSTUFF_T_CFLAGS_S = -fPIC
+
+# Compile libgcc2.a with pic.
+TARGET_LIBGCC2_CFLAGS = -fPIC
+
+# Build a shared libgcc library.
+SHLIB_EXT = .so
+SHLIB_NAME = @shlib_base_name@.so
+SHLIB_SONAME = @shlib_base_name@.so.1
+SHLIB_OBJS = @shlib_objs@
+
+SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
+ -Wl,-msym -Wl,-set_version,gcc.1 -Wl,-soname,$(SHLIB_SONAME) \
+ -o $(SHLIB_NAME) @multilib_flags@ $(SHLIB_OBJS) -lc && \
+ rm -f $(SHLIB_SONAME) && \
+ $(LN_S) $(SHLIB_NAME) $(SHLIB_SONAME)
+# $(slibdir) double quoted to protect it from expansion while building
+# libgcc.mk. We want this delayed until actual install time.
+SHLIB_INSTALL = $(INSTALL_DATA) $(SHLIB_NAME) $$(slibdir)/$(SHLIB_SONAME); \
+ rm -f $$(slibdir)/$(SHLIB_NAME); \
+ $(LN_S) $(SHLIB_SONAME) $$(slibdir)/$(SHLIB_NAME)
diff --git a/contrib/gcc/config/alpha/t-unicosmk b/contrib/gcc/config/alpha/t-unicosmk
new file mode 100644
index 0000000..9c52b98
--- /dev/null
+++ b/contrib/gcc/config/alpha/t-unicosmk
@@ -0,0 +1,2 @@
+# This file is empty for now.
+
diff --git a/contrib/gcc/config/alpha/t-vms b/contrib/gcc/config/alpha/t-vms
index 12ac240..5057c31 100644
--- a/contrib/gcc/config/alpha/t-vms
+++ b/contrib/gcc/config/alpha/t-vms
@@ -1,6 +1,22 @@
-# Do not build libgcc1.
-LIBGCC1 =
-CROSS_LIBGCC1 =
+LIB2FUNCS_EXTRA = $(srcdir)/config/alpha/vms_tramp.asm
-LIB2FUNCS_EXTRA = tramp.s
+# VMS_EXTRA_PARTS is defined in x-vms and represent object files that
+# are only needed for VMS targets, but can only be compiled on a VMS host
+# (because they need DEC C).
+EXTRA_PARTS = vms-dwarf2.o vms-dwarf2eh.o $(VMS_EXTRA_PARTS)
+
+# This object must be linked with in order to make the executable debuggable.
+# vms-ld handles it automatically when passed -g.
+vms-dwarf2.o : $(srcdir)/config/alpha/vms-dwarf2.asm
+ gcc -c -x assembler $< -o $@
+
+vms-dwarf2eh.o : $(srcdir)/config/alpha/vms-dwarf2eh.asm
+ gcc -c -x assembler $< -o $@
+
+# Assemble startup files.
+vcrt0.o: $(CRT0_S) $(GCC_PASSES)
+ decc -c /names=as_is $(srcdir)/config/alpha/vms-crt0.c -o vcrt0.o
+
+pcrt0.o: $(CRT0_S) $(GCC_PASSES)
+ decc -c /names=as_is $(srcdir)/config/alpha/vms-psxcrt0.c -o pcrt0.o
diff --git a/contrib/gcc/config/alpha/t-vms64 b/contrib/gcc/config/alpha/t-vms64
new file mode 100644
index 0000000..e3fc3be
--- /dev/null
+++ b/contrib/gcc/config/alpha/t-vms64
@@ -0,0 +1,8 @@
+# Assemble startup files.
+vcrt0.o: $(CRT0_S) $(GCC_PASSES)
+ decc -c /names=as_is /pointer_size=64 \
+ $(srcdir)/config/alpha/vms-crt0-64.c -o vcrt0.o
+
+pcrt0.o: $(CRT0_S) $(GCC_PASSES)
+ decc -c /names=as_is /pointer_size=64 \
+ $(srcdir)/config/alpha/vms-psxcrt0-64.c -o pcrt0.o
diff --git a/contrib/gcc/config/alpha/unicosmk.h b/contrib/gcc/config/alpha/unicosmk.h
new file mode 100644
index 0000000..65ab319
--- /dev/null
+++ b/contrib/gcc/config/alpha/unicosmk.h
@@ -0,0 +1,626 @@
+/* Definitions of target machine for GNU compiler, for DEC Alpha on Cray
+ T3E running Unicos/Mk.
+ Copyright (C) 2001
+ Free Software Foundation, Inc.
+ Contributed by Roman Lechtchinsky (rl@cs.tu-berlin.de)
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_ABI_UNICOSMK
+#define TARGET_ABI_UNICOSMK 1
+
+/* CAM requires a slash before floating-pointing instruction suffixes. */
+
+#undef TARGET_AS_SLASH_BEFORE_SUFFIX
+#define TARGET_AS_SLASH_BEFORE_SUFFIX 1
+
+/* The following defines are necessary for the standard headers to work
+ correctly. */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-D__unix=1 -D_UNICOS=205 -D_CRAY=1 -D_CRAYT3E=1 -D_CRAYMPP=1 -D_CRAYIEEE=1 -D_ADDR64=1 -D_LD64=1 -D__UNICOSMK__ -D__INT_MAX__=9223372036854775807 -D__SHRT_MAX__=2147483647"
+
+/* Disable software floating point emulation because it requires a 16-bit
+ type which we do not have. */
+
+#ifndef __GNUC__
+#undef REAL_ARITHMETIC
+#endif
+
+#define SHORT_TYPE_SIZE 32
+
+#undef INT_TYPE_SIZE
+#define INT_TYPE_SIZE 64
+
+/* This is consistent with the definition Cray CC uses. */
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE 64
+
+/*
+#define SIZE_TYPE "unsigned int"
+#define PTRDIFF_TYPE "int"
+*/
+
+/* Alphas are operated in big endian mode on the Cray T3E. */
+
+#undef BITS_BIG_ENDIAN
+#undef BYTES_BIG_ENDIAN
+#undef WORDS_BIG_ENDIAN
+#define BITS_BIG_ENDIAN 0
+#define BYTES_BIG_ENDIAN 1
+#define WORDS_BIG_ENDIAN 1
+
+
+/* Every structure's size must be a multiple of this. */
+
+#undef STRUCTURE_SIZE_BOUNDARY
+#define STRUCTURE_SIZE_BOUNDARY 64
+
+/* No data type wants to be aligned rounder than this. */
+
+#undef BIGGEST_ALIGNMENT
+#define BIGGEST_ALIGNMENT 256
+
+/* Include the frame pointer in fixed_regs and call_used_regs as it can't be
+ used as a general-purpose register even in frameless functions.
+ ??? The global_regs hack is needed for now because -O2 sometimes tries to
+ eliminate $15 increments/decrements in frameless functions. */
+
+#undef CONDITIONAL_REGISTER_USAGE
+#define CONDITIONAL_REGISTER_USAGE \
+ do { \
+ fixed_regs[15] = 1; \
+ call_used_regs[15] = 1; \
+ global_regs[15] = 1; \
+ } while(0)
+
+/* The stack frame grows downward. */
+
+#define FRAME_GROWS_DOWNWARD
+
+/* Define the offset between two registers, one to be eliminated, and the
+ other its replacement, at the start of a routine. This is somewhat
+ complicated on the T3E which is why we use a function. */
+
+extern int unicosmk_initial_elimination_offset PARAMS ((int, int));
+
+#undef INITIAL_ELIMINATION_OFFSET
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ do { \
+ (OFFSET) = unicosmk_initial_elimination_offset ((FROM), (TO)); \
+ } while (0)
+
+
+/* Define this if stack space is still allocated for a parameter passed
+ in a register. On the T3E, stack space is preallocated for all outgoing
+ arguments, including those passed in registers. To avoid problems, we
+ assume that at least 48 bytes (i.e. enough space for all arguments passed
+ in registers) are allocated. */
+
+#define REG_PARM_STACK_SPACE(DECL) 48
+#define OUTGOING_REG_PARM_STACK_SPACE
+
+/* If an argument can't be passed in registers even though not all argument
+ registers have been used yet, it is passed on the stack in the space
+ preallocated for these registers. */
+
+#define STACK_PARMS_IN_REG_PARM_AREA
+
+/* This evaluates to nonzero if we do not know how to pass TYPE solely in
+ registers. This is the case for all arguments that do not fit in two
+ registers. */
+
+#define MUST_PASS_IN_STACK(MODE,TYPE) \
+ ((TYPE) != 0 \
+ && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
+ || (TREE_ADDRESSABLE (TYPE) || ALPHA_ARG_SIZE (MODE, TYPE, 0) > 2)))
+
+/* Define a data type for recording info about an argument list
+ during the scan of that argument list. This data type should
+ hold all necessary information about the function itself
+ and about the args processed so far, enough to enable macros
+ such as FUNCTION_ARG to determine where the next arg should go.
+
+ On Unicos/Mk, this is a structure that contains various information for
+ the static subroutine information block (SSIB) and the call information
+ word (CIW). */
+
+typedef struct {
+
+ /* The overall number of arguments. */
+ int num_args;
+
+ /* The overall size of the arguments in words. */
+ int num_arg_words;
+
+ /* The number of words passed in registers. */
+ int num_reg_words;
+
+ /* If an argument must be passed in the stack, all subsequent arguments
+ must be passed there, too. This flag indicates whether this is the
+ case. */
+ int force_stack;
+
+ /* This array indicates whether a word is passed in an integer register or
+ a floating point one. */
+
+ /* For each of the 6 register arguments, the corresponding flag in this
+ array indicates whether the argument is passed in an integer or a
+ floating point register. */
+ int reg_args_type[6];
+
+} unicosmk_arg_info;
+
+#undef CUMULATIVE_ARGS
+#define CUMULATIVE_ARGS unicosmk_arg_info
+
+/* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a
+ function whose data type is FNTYPE. For a library call, FNTYPE is 0. */
+
+#undef INIT_CUMULATIVE_ARGS
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
+ do { (CUM).num_args = 0; \
+ (CUM).num_arg_words = 0; \
+ (CUM).num_reg_words = 0; \
+ (CUM).force_stack = 0; \
+ } while(0)
+
+/* Update the data in CUM to advance over an argument of mode MODE and data
+ type TYPE. (TYPE is null for libcalls where that information may not be
+ available.)
+
+ On Unicos/Mk, at most 6 words can be passed in registers. Structures
+ which fit in two words are passed in registers, larger structures are
+ passed on stack. */
+
+#undef FUNCTION_ARG_ADVANCE
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
+do { \
+ int size; \
+ \
+ size = ALPHA_ARG_SIZE (MODE, TYPE, NAMED); \
+ \
+ if (size > 2 || MUST_PASS_IN_STACK (MODE, TYPE) \
+ || (CUM).num_reg_words + size > 6) \
+ (CUM).force_stack = 1; \
+ \
+ if (! (CUM).force_stack) \
+ { \
+ int i; \
+ int isfloat; \
+ isfloat = (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
+ || GET_MODE_CLASS (MODE) == MODE_FLOAT); \
+ for (i = 0; i < size; i++) \
+ { \
+ (CUM).reg_args_type[(CUM).num_reg_words] = isfloat; \
+ ++(CUM).num_reg_words; \
+ } \
+ } \
+ (CUM).num_arg_words += size; \
+ ++(CUM).num_args; \
+} while(0)
+
+/* We want the default definition for this.
+ ??? In fact, we should delete the definition from alpha.h as it
+ corresponds to the default definition for little-endian machines. */
+
+#undef FUNCTION_ARG_PADDING
+
+/* An argument is passed either entirely in registers or entirely on stack. */
+
+#undef FUNCTION_ARG_PARTIAL_NREGS
+/* #define FUNCTION_ARG_PARTIAL_NREGS(CUM,MODE,TYPE,NAMED) 0 */
+
+/* Perform any needed actions needed for a function that is receiving a
+ variable number of arguments.
+
+ On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
+ arguments on the stack. Unfortunately, it doesn't always store the first
+ one (i.e. the one that arrives in $16 or $f16). This is not a problem
+ with stdargs as we always have at least one named argument there. This is
+ not always the case when varargs.h is used, however. In such cases, we
+ have to store the first argument ourselves. We use the information from
+ the CIW to determine whether the first argument arrives in $16 or $f16. */
+
+#undef SETUP_INCOMING_VARARGS
+#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
+{ if ((CUM).num_reg_words < 6) \
+ { \
+ if (! (NO_RTL)) \
+ { \
+ int start; \
+ \
+ start = (CUM).num_reg_words; \
+ if (!current_function_varargs || start == 0) \
+ ++start; \
+ \
+ emit_insn (gen_umk_mismatch_args (GEN_INT (start))); \
+ if (current_function_varargs && (CUM).num_reg_words == 0) \
+ { \
+ rtx tmp; \
+ rtx int_label, end_label; \
+ \
+ tmp = gen_reg_rtx (DImode); \
+ emit_move_insn (tmp, \
+ gen_rtx_ZERO_EXTRACT (DImode, \
+ gen_rtx_REG (DImode, 2),\
+ (GEN_INT (1)), \
+ (GEN_INT (7)))); \
+ int_label = gen_label_rtx (); \
+ end_label = gen_label_rtx (); \
+ emit_insn (gen_cmpdi (tmp, GEN_INT (0))); \
+ emit_jump_insn (gen_beq (int_label)); \
+ emit_move_insn (gen_rtx_MEM (DFmode, virtual_incoming_args_rtx),\
+ gen_rtx_REG (DFmode, 48)); \
+ emit_jump (end_label); \
+ emit_label (int_label); \
+ emit_move_insn (gen_rtx_MEM (DImode, virtual_incoming_args_rtx),\
+ gen_rtx_REG (DImode, 16)); \
+ emit_label (end_label); \
+ } \
+ emit_insn (gen_arg_home_umk ()); \
+ } \
+ \
+ PRETEND_SIZE = 0; \
+ } \
+}
+
+/* This ensures that $15 increments/decrements in leaf functions won't get
+ eliminated. */
+
+#undef EPILOGUE_USES
+#define EPILOGUE_USES(REGNO) ((REGNO) == 26 || (REGNO) == 15)
+
+/* Machine-specific function data. */
+
+struct machine_function
+{
+ /* List of call information words for calls from this function. */
+ struct rtx_def *first_ciw;
+ struct rtx_def *last_ciw;
+ int ciw_count;
+
+ /* List of deferred case vectors. */
+ struct rtx_def *addr_list;
+};
+
+/* Would have worked, only the stack doesn't seem to be executable
+#undef TRAMPOLINE_TEMPLATE
+#define TRAMPOLINE_TEMPLATE(FILE) \
+do { fprintf (FILE, "\tbr $1,0\n"); \
+ fprintf (FILE, "\tldq $0,12($1)\n"); \
+ fprintf (FILE, "\tldq $1,20($1)\n"); \
+ fprintf (FILE, "\tjmp $31,(r0)\n"); \
+ fprintf (FILE, "\tbis $31,$31,$31\n"); \
+ fprintf (FILE, "\tbis $31,$31,$31\n"); \
+} while (0) */
+
+/* We don't support nested functions (yet). */
+
+#undef TRAMPOLINE_TEMPLATE
+#define TRAMPOLINE_TEMPLATE(FILE) abort ()
+
+/* Specify the machine mode that this machine uses for the index in the
+ tablejump instruction. On Unicos/Mk, we don't support relative case
+ vectors yet, thus the entries should be absolute addresses. */
+
+#undef CASE_VECTOR_MODE
+#define CASE_VECTOR_MODE DImode
+
+#undef CASE_VECTOR_PC_RELATIVE
+
+/* Define this as 1 if `char' should by default be signed; else as 0. */
+/* #define DEFAULT_SIGNED_CHAR 1 */
+
+/* The Cray assembler is really weird with respect to sections. It has only
+ named sections and you can't reopen a section once it has been closed.
+ This means that we have to generate unique names whenever we want to
+ reenter the text or the data section. The following is a rather bad hack
+ as TEXT_SECTION_ASM_OP and DATA_SECTION_ASM_OP are supposed to be
+ constants. */
+
+#undef TEXT_SECTION_ASM_OP
+#define TEXT_SECTION_ASM_OP unicosmk_text_section ()
+
+#undef DATA_SECTION_ASM_OP
+#define DATA_SECTION_ASM_OP unicosmk_data_section ()
+
+/* There are ni read-only sections on Unicos/Mk. */
+
+#undef READONLY_DATA_SECTION
+#define READONLY_DATA_SECTION data_section
+
+/* Define extra sections for common data and SSIBs (static subroutine
+ information blocks). The actual section header is output by the callers
+ of these functions. */
+
+#undef EXTRA_SECTIONS
+#undef EXTRA_SECTION_FUNCTIONS
+
+#define EXTRA_SECTIONS in_common, in_ssib
+#define EXTRA_SECTION_FUNCTIONS \
+COMMON_SECTION \
+SSIB_SECTION
+
+extern void common_section PARAMS ((void));
+#define COMMON_SECTION \
+void \
+common_section () \
+{ \
+ in_section = in_common; \
+}
+
+extern void ssib_section PARAMS ((void));
+#define SSIB_SECTION \
+void \
+ssib_section () \
+{ \
+ in_section = in_ssib; \
+}
+
+/* A C expression which evaluates to true if declshould be placed into a
+ unique section for some target-specific reason. On Unicos/Mk, functions
+ and public variables are always placed in unique sections. */
+
+/*
+#define UNIQUE_SECTION_P(DECL) (TREE_PUBLIC (DECL) \
+ || TREE_CODE (DECL) == FUNCTION_DECL)
+*/
+#define UNIQUE_SECTION(DECL, RELOC) unicosmk_unique_section (DECL, RELOC)
+
+/* This outputs text to go at the start of an assembler file. */
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) unicosmk_asm_file_start (FILE)
+
+/* This outputs text to go at the end of an assembler file. */
+
+#undef ASM_FILE_END
+#define ASM_FILE_END(FILE) unicosmk_asm_file_end (FILE)
+
+/* We take care of that in ASM_FILE_START. */
+
+#undef ASM_OUTPUT_SOURCE_FILENAME
+
+/* There is no directive for declaring a label as global. Instead, an
+ additional colon must be appended when the label is defined. */
+
+#undef ASM_GLOBALIZE_LABEL
+#define ASM_GLOBALIZE_LABEL(FILE,NAME)
+
+/* This is how to output a label for a jump table. Arguments are the same as
+ for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
+ passed. */
+
+#undef ASM_OUTPUT_CASE_LABEL
+#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
+ ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM)
+
+/* CAM has some restrictions with respect to string literals. It won't
+ accept lines with more that 256 characters which means that we have
+ to split long strings. Moreover, it only accepts escape sequences of
+ the form \nnn in the range 0 to 127. We generate .byte directives for
+ escapes characters greater than 127. And finally, ` must be escaped. */
+
+#undef ASM_OUTPUT_ASCII
+#define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
+ do { \
+ FILE *_hide_asm_out_file = (MYFILE); \
+ 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; \
+ const unsigned char *p = _hide_p; \
+ int thissize = _hide_thissize; \
+ int in_ascii = 0; \
+ int i; \
+ \
+ for (i = 0; i < thissize; i++) \
+ { \
+ register int c = p[i]; \
+ \
+ if (c > 127) \
+ { \
+ if (in_ascii) \
+ { \
+ fprintf (asm_out_file, "\"\n"); \
+ in_ascii = 0; \
+ } \
+ \
+ fprintf (asm_out_file, "\t.byte\t%d\n", c); \
+ } \
+ else \
+ { \
+ if (! in_ascii) \
+ { \
+ fprintf (asm_out_file, "\t.ascii\t\""); \
+ in_ascii = 1; \
+ _size_so_far = 0; \
+ } \
+ else if (_size_so_far >= 64) \
+ { \
+ fprintf (asm_out_file, "\"\n\t.ascii\t\""); \
+ _size_so_far = 0; \
+ } \
+ \
+ if (c == '\"' || c == '\\' || c == '`') \
+ putc ('\\', asm_out_file); \
+ if (c >= ' ') \
+ putc (c, asm_out_file); \
+ else \
+ fprintf (asm_out_file, "\\%.3o", c); \
+ ++ _size_so_far; \
+ } \
+ } \
+ if (in_ascii) \
+ fprintf (asm_out_file, "\"\n"); \
+ } \
+ } while(0)
+
+/* This is how to output an element of a case-vector that is absolute. */
+
+#undef ASM_OUTPUT_ADDR_VEC_ELT
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+ fprintf (FILE, "\t.quad $L%d\n", (VALUE))
+
+/* This is how to output an element of a case-vector that is relative.
+ (Unicos/Mk does not use such vectors yet). */
+
+#undef ASM_OUTPUT_ADDR_DIFF_ELT
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort ()
+
+/* We can't output case vectors in the same section as the function code
+ because CAM doesn't allow data definitions in code sections. Thus, we
+ simply record the case vectors and put them in a separate section after
+ the function. */
+
+#define ASM_OUTPUT_ADDR_VEC(LAB,VEC) \
+ unicosmk_defer_case_vector ((LAB),(VEC))
+
+#define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,VEC) abort ()
+
+/* This is how to output an assembler line that says to advance the location
+ counter to a multiple of 2**LOG bytes. Annoyingly, CAM always uses zeroes
+ to fill the unused space which does not work in code sections. We have to
+ be careful not to use the .align directive in code sections. */
+
+#undef ASM_OUTPUT_ALIGN
+#define ASM_OUTPUT_ALIGN(STREAM,LOG) unicosmk_output_align (STREAM, LOG)
+
+/* This is how to advance the location counter by SIZE bytes. */
+
+#undef ASM_OUTPUT_SKIP
+#define ASM_OUTPUT_SKIP(STREAM,SIZE) \
+ fprintf ((STREAM), "\t.byte\t0:%d\n", (SIZE));
+
+/* This says how to output an assembler line to define a global common
+ symbol. We need the alignment information because it has to be supplied
+ in the section header. */
+
+#undef ASM_OUTPUT_COMMON
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
+ unicosmk_output_common ((FILE), (NAME), (SIZE), (ALIGN))
+
+/* This says how to output an assembler line to define a local symbol. */
+
+#undef ASM_OUTPUT_LOCAL
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
+ do { data_section (); \
+ fprintf (FILE, "\t.align\t%d\n", floor_log2 ((ALIGN) / BITS_PER_UNIT));\
+ ASM_OUTPUT_LABEL ((FILE), (NAME)); \
+ fprintf (FILE, "\t.byte 0:%d\n", SIZE); \
+ } while (0)
+
+/* CAM does not allow us to declare a symbol as external first and then
+ define it in the same file later. Thus, we keep a list of all external
+ references, remove all symbols defined locally from it and output it at
+ the end of the asm file. */
+
+#define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME) \
+ unicosmk_add_extern ((NAME))
+
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(STREAM,SYMREF) \
+ unicosmk_add_extern (XSTR ((SYMREF), 0))
+
+/* This is how to declare an object. We don't have to output anything if
+ it is a global variable because those go into unique `common' sections
+ and the section name is globally visible. For local variables, we simply
+ output the label. In any case, we have to record that no extern
+ declaration should be generated for the symbol. */
+
+#define ASM_DECLARE_OBJECT_NAME(STREAM,NAME,DECL) \
+ do { tree name_tree; \
+ name_tree = get_identifier ((NAME)); \
+ TREE_ASM_WRITTEN (name_tree) = 1; \
+ if (!TREE_PUBLIC (DECL)) \
+ { \
+ assemble_name (STREAM, NAME); \
+ fputs (":\n", STREAM); \
+ } \
+ } while(0)
+
+/*
+#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
+ unicosmk_output_section_name ((STREAM), (DECL), (NAME), (RELOC))
+*/
+
+/* Switch into a generic section. */
+#define TARGET_ASM_NAMED_SECTION unicosmk_asm_named_section
+
+#undef ASM_OUTPUT_MAX_SKIP_ALIGN
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM,POWER,MAXSKIP)
+
+/* We have to define these because we do not use the floating-point
+ emulation. Unfortunately, atof does not accept hex literals. */
+
+#ifndef REAL_ARITHMETIC
+#define REAL_VALUE_ATOF(x,s) atof(x)
+#define REAL_VALUE_HTOF(x,s) atof(x)
+#endif
+
+#undef NM_FLAGS
+
+#undef OBJECT_FORMAT_COFF
+
+/* We cannot generate debugging information on Unicos/Mk. */
+
+#undef SDB_DEBUGGING_INFO
+#undef MIPS_DEBUGGING_INFO
+#undef DBX_DEBUGGING_INFO
+#undef DWARF_DEBUGGING_INFO
+#undef DWARF2_DEBUGGING_INFO
+#undef DWARF2_UNWIND_INFO
+#undef INCOMING_RETURN_ADDR_RTX
+
+
+/* We use the functions provided by the system library for integer
+ division. */
+
+#undef UDIVDI3_LIBCALL
+#undef DIVDI3_LIBCALL
+#define UDIVDI3_LIBCALL "$uldiv"
+#define DIVDI3_LIBCALL "$sldiv"
+
+/* This is necessary to prevent gcc from generating calls to __divsi3. */
+
+#define INIT_TARGET_OPTABS \
+ do { \
+ sdiv_optab->handlers[(int) SImode].libfunc = NULL_RTX; \
+ udiv_optab->handlers[(int) SImode].libfunc = NULL_RTX; \
+ } while (0)
+
+#undef ASM_OUTPUT_SOURCE_LINE
+
+/* We don't need a start file. */
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC ""
+
+/* These are the libraries we have to link with.
+ ??? The Craylibs directory should be autoconfed. */
+#undef LIB_SPEC
+#define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma"
+
+#undef BUILD_VA_LIST_TYPE
+#undef EXPAND_BUILTIN_VA_START
+#undef EXPAND_BUILTIN_VA_ARG
+
+#define EH_FRAME_IN_DATA_SECTION 1
diff --git a/contrib/gcc/config/alpha/va_list.h b/contrib/gcc/config/alpha/va_list.h
index c9ab2b0..df58ed0 100644
--- a/contrib/gcc/config/alpha/va_list.h
+++ b/contrib/gcc/config/alpha/va_list.h
@@ -1,6 +1,9 @@
/* A replacement for Digital Unix's <va_list.h>. */
-#include <va-alpha.h>
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+typedef __builtin_va_list __gnuc_va_list;
+#endif
#if !defined(_VA_LIST) && !defined(_HIDDEN_VA_LIST)
#define _VA_LIST
diff --git a/contrib/gcc/config/alpha/vms-cc.c b/contrib/gcc/config/alpha/vms-cc.c
new file mode 100644
index 0000000..a171b1c
--- /dev/null
+++ b/contrib/gcc/config/alpha/vms-cc.c
@@ -0,0 +1,379 @@
+/* VMS DEC C wrapper.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Douglas B. Rupp (rupp@gnat.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This program is a wrapper around the VMS DEC C compiler.
+ It translates Unix style command line options into corresponding
+ VMS style qualifiers and then spawns the DEC C compiler. */
+
+#include "config.h"
+#include "system.h"
+
+#undef PATH_SEPARATOR
+#undef PATH_SEPARATOR_STR
+#define PATH_SEPARATOR ','
+#define PATH_SEPARATOR_STR ","
+
+/* These can be set by command line arguments */
+int verbose = 0;
+int save_temps = 0;
+
+int comp_arg_max = -1;
+const char **comp_args = 0;
+int comp_arg_index = -1;
+char *objfilename = 0;
+
+char *system_search_dirs = (char *) "";
+char *search_dirs;
+
+char *default_defines = (char *) "";
+char *defines;
+
+/* Translate a Unix syntax directory specification into VMS syntax.
+ If indicators of VMS syntax found, return input string. */
+static char *to_host_dir_spec PARAMS ((char *));
+
+/* Translate a Unix syntax file specification into VMS syntax.
+ If indicators of VMS syntax found, return input string. */
+static char *to_host_file_spec PARAMS ((char *));
+
+/* Add a translated arg to the list to be passed to DEC CC */
+static void addarg PARAMS ((const char *));
+
+/* Preprocess the number of args in P_ARGC and contained in ARGV.
+ Look for special flags, etc. that must be handled first. */
+static void preprocess_args PARAMS ((int *, char **));
+
+/* Process the number of args in P_ARGC and contained in ARGV. Look
+ for special flags, etc. that must be handled for the VMS compiler. */
+static void process_args PARAMS ((int *, char **));
+
+/* Action routine called by decc$to_vms */
+static int translate_unix PARAMS ((char *, int));
+
+int main PARAMS ((int, char **));
+
+/* Add the argument contained in STR to the list of arguments to pass to the
+ compiler. */
+
+static void
+addarg (str)
+ const char *str;
+{
+ int i;
+
+ if (++comp_arg_index >= comp_arg_max)
+ {
+ const char **new_comp_args
+ = (const char **) xcalloc (comp_arg_max + 1000, sizeof (char *));
+
+ for (i = 0; i <= comp_arg_max; i++)
+ new_comp_args [i] = comp_args [i];
+
+ if (comp_args)
+ free (comp_args);
+
+ comp_arg_max += 1000;
+ comp_args = new_comp_args;
+ }
+
+ comp_args [comp_arg_index] = str;
+}
+
+static void
+preprocess_args (p_argc, argv)
+ int *p_argc;
+ char *argv[];
+{
+ int i;
+
+ for (i = 1; i < *p_argc; i++)
+ {
+ if (strcmp (argv[i], "-o") == 0)
+ {
+ char *buff, *ptr;
+ int out_len;
+
+ i++;
+ ptr = to_host_file_spec (argv[i]);
+ objfilename = xstrdup (ptr);
+ out_len = strlen (ptr);
+ buff = xmalloc (out_len + 6);
+
+ strcpy (buff, "/obj=");
+ strcat (buff, ptr);
+ addarg (buff);
+ }
+ }
+}
+
+static void
+process_args (p_argc, argv)
+ int *p_argc;
+ char *argv[];
+{
+ int i;
+
+ for (i = 1; i < *p_argc; i++)
+ {
+ if (strlen (argv[i]) < 2)
+ continue;
+
+ if (strncmp (argv[i], "-I", 2) == 0)
+ {
+ char *ptr;
+ int new_len, search_dirs_len;
+
+ ptr = to_host_dir_spec (&argv[i][2]);
+ new_len = strlen (ptr);
+ search_dirs_len = strlen (search_dirs);
+
+ search_dirs = xrealloc (search_dirs, search_dirs_len + new_len + 2);
+ if (search_dirs_len > 0)
+ strcat (search_dirs, PATH_SEPARATOR_STR);
+ strcat (search_dirs, ptr);
+ }
+ else if (strncmp (argv[i], "-D", 2) == 0)
+ {
+ char *ptr;
+ int new_len, defines_len;
+
+ ptr = &argv[i][2];
+ new_len = strlen (ptr);
+ defines_len = strlen (defines);
+
+ defines = xrealloc (defines, defines_len + new_len + 4);
+ if (defines_len > 0)
+ strcat (defines, ",");
+
+ strcat (defines, "\"");
+ strcat (defines, ptr);
+ strcat (defines, "\"");
+ }
+ else if (strcmp (argv[i], "-v") == 0)
+ verbose = 1;
+ else if (strcmp (argv[i], "-g0") == 0)
+ addarg ("/nodebug");
+ else if (strcmp (argv[i], "-O0") == 0)
+ addarg ("/noopt");
+ else if (strncmp (argv[i], "-g", 2) == 0)
+ addarg ("/debug");
+ else if (strcmp (argv[i], "-E") == 0)
+ addarg ("/preprocess");
+ else if (strcmp (argv[i], "-save-temps") == 0)
+ save_temps = 1;
+ }
+}
+
+/* The main program. Spawn the VMS DEC C compiler after fixing up the
+ Unix-like flags and args to be what VMS DEC C wants. */
+
+typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+ char cwdev [128], *devptr;
+ int devlen;
+ char *cwd = getcwd (0, 1024);
+
+ devptr = strchr (cwd, ':');
+ devlen = (devptr - cwd) + 1;
+ strncpy (cwdev, cwd, devlen);
+ cwdev [devlen] = '\0';
+
+ search_dirs = xmalloc (strlen (system_search_dirs) + 1);
+ strcpy (search_dirs, system_search_dirs);
+
+ defines = xmalloc (strlen (default_defines) + 1);
+ strcpy (defines, default_defines);
+
+ addarg ("cc");
+ preprocess_args (&argc , argv);
+ process_args (&argc , argv);
+
+ if (strlen (search_dirs) > 0)
+ {
+ addarg ("/include=(");
+ addarg (search_dirs);
+ addarg (")");
+ }
+
+ if (strlen (defines) > 0)
+ {
+ addarg ("/define=(");
+ addarg (defines);
+ addarg (")");
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ int arg_len = strlen (argv[i]);
+
+ if (strcmp (argv[i], "-o") == 0)
+ i++;
+ else if (strcmp (argv[i], "-v" ) == 0
+ || strcmp (argv[i], "-E") == 0
+ || strcmp (argv[i], "-c") == 0
+ || strncmp (argv[i], "-g", 2 ) == 0
+ || strncmp (argv[i], "-O", 2 ) == 0
+ || strcmp (argv[i], "-save-temps") == 0
+ || (arg_len > 2 && strncmp (argv[i], "-I", 2) == 0)
+ || (arg_len > 2 && strncmp (argv[i], "-D", 2) == 0))
+ ;
+
+ /* Unix style file specs and VMS style switches look alike, so assume
+ an arg consisting of one and only one slash, and that being first, is
+ really a switch. */
+ else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0))
+ addarg (argv[i]);
+ else
+ {
+ /* Assume filename arg */
+ char buff [256], *ptr;
+ int buff_len;
+
+ ptr = to_host_file_spec (argv[i]);
+ arg_len = strlen (ptr);
+
+ if (ptr[0] == '[')
+ sprintf (buff, "%s%s", cwdev, ptr);
+ else if (strchr (ptr, ':'))
+ sprintf (buff, "%s", ptr);
+ else
+ sprintf (buff, "%s%s", cwd, ptr);
+
+ buff_len = strlen (buff);
+ ptr = xmalloc (buff_len + 1);
+
+ strcpy (ptr, buff);
+ addarg (ptr);
+ }
+ }
+
+ addarg (NULL);
+
+ if (verbose)
+ {
+ int i;
+
+ for (i = 0; i < comp_arg_index; i++)
+ printf ("%s ", comp_args [i]);
+
+ putchar ('\n');
+ }
+
+ {
+ int i;
+ int len = 0;
+
+ for (i = 0; comp_args[i]; i++)
+ len = len + strlen (comp_args[i]) + 1;
+
+ {
+ char *allargs = (char *) alloca (len + 1);
+ Descr cmd;
+ int status;
+ int status1 = 1;
+
+ for (i = 0; i < len + 1; i++)
+ allargs [i] = 0;
+
+ for (i = 0; comp_args [i]; i++)
+ {
+ strcat (allargs, comp_args [i]);
+ strcat (allargs, " ");
+ }
+
+ cmd.adr = allargs;
+ cmd.len = len;
+ cmd.mbz = 0;
+
+ i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status);
+
+ if ((i & 1) != 1)
+ {
+ LIB$SIGNAL (i);
+ exit (1);
+ }
+
+ if ((status & 1) == 1 && (status1 & 1) == 1)
+ exit (0);
+
+ exit (1);
+ }
+ }
+}
+
+static char new_host_filespec [255];
+static char new_host_dirspec [255];
+static char filename_buff [256];
+
+static int
+translate_unix (name, type)
+ char *name;
+ int type ATTRIBUTE_UNUSED;
+{
+ strcpy (filename_buff, name);
+ return 0;
+}
+
+static char *
+to_host_dir_spec (dirspec)
+ char *dirspec;
+{
+ int len = strlen (dirspec);
+
+ strcpy (new_host_dirspec, dirspec);
+
+ if (strchr (new_host_dirspec, ']') || strchr (new_host_dirspec, ':'))
+ return new_host_dirspec;
+
+ while (len > 1 && new_host_dirspec [len-1] == '/')
+ {
+ new_host_dirspec [len-1] = 0;
+ len--;
+ }
+
+ decc$to_vms (new_host_dirspec, translate_unix, 1, 2);
+ strcpy (new_host_dirspec, filename_buff);
+
+ return new_host_dirspec;
+
+}
+
+static char *
+to_host_file_spec (filespec)
+ char *filespec;
+{
+ strcpy (new_host_filespec, "");
+ if (strchr (filespec, ']') || strchr (filespec, ':'))
+ strcpy (new_host_filespec, filespec);
+ else
+ {
+ decc$to_vms (filespec, translate_unix, 1, 1);
+ strcpy (new_host_filespec, filename_buff);
+ }
+
+ return new_host_filespec;
+}
diff --git a/contrib/gcc/config/alpha/vms-crt0-64.c b/contrib/gcc/config/alpha/vms-crt0-64.c
new file mode 100644
index 0000000..4120a6b
--- /dev/null
+++ b/contrib/gcc/config/alpha/vms-crt0-64.c
@@ -0,0 +1,99 @@
+/* VMS 64bit crt0 returning VMS style condition codes .
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Douglas B. Rupp (rupp@gnat.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#if !defined(__DECC)
+You Lose! This file can only be compiled with DEC C.
+#else
+
+/* This file can only be compiled with DEC C, due the the call to
+ lib$establish and the pragmas pointer_size. */
+
+#pragma __pointer_size short
+
+#include <stdlib.h>
+#include <string.h>
+#include <ssdef.h>
+
+extern void decc$main ();
+
+extern int main ();
+
+static int
+handler (sigargs, mechargs)
+ void *sigargs;
+ void *mechargs;
+{
+ return SS$_RESIGNAL;
+}
+
+int
+__main (arg1, arg2, arg3, image_file_desc, arg5, arg6)
+ void *arg1, *arg2, *arg3;
+ void *image_file_desc;
+ void *arg5, *arg6;
+{
+ int argc;
+ char **argv;
+ char **envp;
+
+#pragma __pointer_size long
+
+ int i;
+ char **long_argv;
+ char **long_envp;
+
+#pragma __pointer_size short
+
+ lib$establish (handler);
+ decc$main (arg1, arg2, arg3, image_file_desc,
+ arg5, arg6, &argc, &argv, &envp);
+
+#pragma __pointer_size long
+
+ /* Reallocate argv with 64 bit pointers. */
+ long_argv = (char **) malloc (sizeof (char *) * (argc + 1));
+
+ for (i = 0; i < argc; i++)
+ long_argv[i] = strdup (argv[i]);
+
+ long_argv[argc] = (char *) 0;
+
+ long_envp = (char **) malloc (sizeof (char *) * 5);
+
+ for (i = 0; envp[i]; i++)
+ long_envp[i] = strdup (envp[i]);
+
+ long_envp[i] = (char *) 0;
+
+#pragma __pointer_size short
+
+ return main (argc, long_argv, long_envp);
+}
+#endif
diff --git a/contrib/gcc/config/alpha/vms-crt0.c b/contrib/gcc/config/alpha/vms-crt0.c
new file mode 100644
index 0000000..e75bc02
--- /dev/null
+++ b/contrib/gcc/config/alpha/vms-crt0.c
@@ -0,0 +1,71 @@
+/* VMS crt0 returning VMS style condition codes .
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Douglas B. Rupp (rupp@gnat.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#if !defined(__DECC)
+You Lose! This file can only be compiled with DEC C.
+#else
+
+/* This file can only be compiled with DEC C, due the the call to
+ lib$establish. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ssdef.h>
+
+extern void decc$main ();
+
+extern int main ();
+
+static int
+handler (sigargs, mechargs)
+ void *sigargs;
+ void *mechargs;
+{
+ return SS$_RESIGNAL;
+}
+
+int
+__main (arg1, arg2, arg3, image_file_desc, arg5, arg6)
+ void *arg1, *arg2, *arg3;
+ void *image_file_desc;
+ void *arg5, *arg6;
+{
+ int argc;
+ char **argv;
+ char **envp;
+
+ lib$establish (handler);
+
+ decc$main(arg1, arg2, arg3, image_file_desc, arg5, arg6,
+ &argc, &argv, &envp);
+
+ return main (argc, argv, envp);
+}
+#endif
diff --git a/contrib/gcc/config/alpha/vms-dwarf2.asm b/contrib/gcc/config/alpha/vms-dwarf2.asm
new file mode 100644
index 0000000..a94ae24
--- /dev/null
+++ b/contrib/gcc/config/alpha/vms-dwarf2.asm
@@ -0,0 +1,82 @@
+/* VMS dwarf2 section sequentializer.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Douglas B. Rupp (rupp@gnat.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Linking with this file forces Dwarf2 debug sections to be
+ sequentially loaded by the VMS linker, enabling GDB to read them. */
+
+.section .debug_abbrev,NOWRT
+ .align 0
+ .globl $dwarf2.debug_abbrev
+$dwarf2.debug_abbrev:
+
+.section .debug_aranges,NOWRT
+ .align 0
+ .globl $dwarf2.debug_aranges
+$dwarf2.debug_aranges:
+
+.section .debug_frame,NOWRT
+ .align 0
+ .globl $dwarf2.debug_frame
+$dwarf2.debug_frame:
+
+.section .debug_info,NOWRT
+ .align 0
+ .globl $dwarf2.debug_info
+$dwarf2.debug_info:
+
+.section .debug_line,NOWRT
+ .align 0
+ .globl $dwarf2.debug_line
+$dwarf2.debug_line:
+
+.section .debug_loc,NOWRT
+ .align 0
+ .globl $dwarf2.debug_loc
+$dwarf2.debug_loc:
+
+.section .debug_macinfo,NOWRT
+ .align 0
+ .globl $dwarf2.debug_macinfo
+$dwarf2.debug_macinfo:
+
+.section .debug_pubnames,NOWRT
+ .align 0
+ .globl $dwarf2.debug_pubnames
+$dwarf2.debug_pubnames:
+
+.section .debug_str,NOWRT
+ .align 0
+ .globl $dwarf2.debug_str
+$dwarf2.debug_str:
+
+.section .debug_zzzzzz,NOWRT
+ .align 0
+ .globl $dwarf2.debug_zzzzzz
+$dwarf2.debug_zzzzzz:
diff --git a/contrib/gcc/config/alpha/vms-dwarf2eh.asm b/contrib/gcc/config/alpha/vms-dwarf2eh.asm
new file mode 100644
index 0000000..22f7050
--- /dev/null
+++ b/contrib/gcc/config/alpha/vms-dwarf2eh.asm
@@ -0,0 +1,37 @@
+/* VMS dwarf2 exception handling section sequentializer.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Douglas B. Rupp (rupp@gnat.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Linking with this file forces the Dwarf2 EH section to be
+ individually loaded by the VMS linker an the unwinder to read it. */
+
+.section .eh_frame,NOWRT
+ .align 0
+ .global __EH_FRAME_BEGIN__
+__EH_FRAME_BEGIN__:
diff --git a/contrib/gcc/config/alpha/vms-ld.c b/contrib/gcc/config/alpha/vms-ld.c
new file mode 100644
index 0000000..83ceaf9
--- /dev/null
+++ b/contrib/gcc/config/alpha/vms-ld.c
@@ -0,0 +1,777 @@
+/* VMS linker wrapper.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Contributed by Douglas B. Rupp (rupp@gnat.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This program is a wrapper around the VMS linker.
+ It translates Unix style command line options into corresponding
+ VMS style qualifiers and then spawns the VMS linker. */
+
+#include "config.h"
+#include "system.h"
+
+typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
+
+#undef PATH_SEPARATOR
+#undef PATH_SEPARATOR_STR
+#define PATH_SEPARATOR ','
+#define PATH_SEPARATOR_STR ","
+
+/* Local variable declarations. */
+
+/* File specification for vms-dwarf2.o. */
+static char *vmsdwarf2spec = 0;
+
+/* File specification for vms-dwarf2eh.o. */
+static char *vmsdwarf2ehspec = 0;
+
+/* verbose = 1 if -v passed. */
+static int verbose = 0;
+
+/* save_temps = 1 if -save-temps passed. */
+static int save_temps = 0;
+
+/* By default don't generate executable file if there are errors
+ in the link. Override with --noinhibit-exec. */
+static int inhibit_exec = 1;
+
+/* debug = 1 if -g passed. */
+static int debug = 0;
+
+/* By default prefer to link with shareable image libraries.
+ Override with -static. */
+static int staticp = 0;
+
+/* By default generate an executable, not a shareable image library.
+ Override with -shared. */
+static int share = 0;
+
+/* Remember if IDENTIFICATION given on command line. */
+static int ident = 0;
+
+/* Keep track of arg translations. */
+static int link_arg_max = -1;
+static const char **link_args = 0;
+static int link_arg_index = -1;
+
+/* Keep track of filenames */
+static char optfilefullname [267];
+static char *sharefilename = 0;
+static char *exefilename = 0;
+
+/* System search dir list. Leave blank since link handles this
+ internally. */
+static char *system_search_dirs = "";
+
+/* Search dir list passed on command line (with -L). */
+static char *search_dirs;
+
+/* Local function declarations. */
+
+/* Add STR to the list of arguments to pass to the linker. Expand the list as
+ necessary to accommodate. */
+static void addarg PARAMS ((const char *));
+
+/* Check to see if NAME is a regular file, i.e. not a directory */
+static int is_regular_file PARAMS ((char *));
+
+/* Translate a Unix syntax file specification FILESPEC into VMS syntax.
+ If indicators of VMS syntax found, return input string. */
+static char *to_host_file_spec PARAMS ((char *));
+
+/* Locate the library named LIB_NAME in the set of paths PATH_VAL. */
+static char *locate_lib PARAMS ((char *, char *));
+
+/* Given a library name NAME, i.e. foo, Look for libfoo.lib and then
+ libfoo.a in the set of directories we are allowed to search in. */
+static const char *expand_lib PARAMS ((char *));
+
+/* Preprocess the number of args P_ARGC in ARGV.
+ Look for special flags, etc. that must be handled first. */
+static void preprocess_args PARAMS ((int *, char **));
+
+/* Preprocess the number of args P_ARGC in ARGV. Look for
+ special flags, etc. that must be handled for the VMS linker. */
+static void process_args PARAMS ((int *, char **));
+
+/* Action routine called by decc$to_vms. NAME is a file name or
+ directory name. TYPE is unused. */
+static int translate_unix PARAMS ((char *, int));
+
+int main PARAMS ((int, char **));
+
+static void
+addarg (str)
+ const char *str;
+{
+ int i;
+
+ if (++link_arg_index >= link_arg_max)
+ {
+ const char **new_link_args
+ = (const char **) xcalloc (link_arg_max + 1000, sizeof (char *));
+
+ for (i = 0; i <= link_arg_max; i++)
+ new_link_args [i] = link_args [i];
+
+ if (link_args)
+ free (link_args);
+
+ link_arg_max += 1000;
+ link_args = new_link_args;
+ }
+
+ link_args [link_arg_index] = str;
+}
+
+static char *
+locate_lib (lib_name, path_val)
+ char *lib_name;
+ char *path_val;
+{
+ int lib_len = strlen (lib_name);
+ char *eptr, *sptr;
+
+ for (sptr = path_val; *sptr; sptr = eptr)
+ {
+ char *buf, *ptr;
+
+ while (*sptr == PATH_SEPARATOR)
+ sptr ++;
+
+ eptr = strchr (sptr, PATH_SEPARATOR);
+ if (eptr == 0)
+ eptr = strchr (sptr, 0);
+
+ buf = alloca ((eptr-sptr) + lib_len + 4 + 2);
+ strncpy (buf, sptr, eptr-sptr);
+ buf [eptr-sptr] = 0;
+ strcat (buf, "/");
+ strcat (buf, lib_name);
+ ptr = strchr (buf, 0);
+
+ if (debug || staticp)
+ {
+ /* For debug or static links, look for shareable image libraries
+ last. */
+ strcpy (ptr, ".a");
+ if (is_regular_file (buf))
+ return xstrdup (to_host_file_spec (buf));
+
+ strcpy (ptr, ".olb");
+ if (is_regular_file (buf))
+ return xstrdup (to_host_file_spec (buf));
+
+ strcpy (ptr, ".exe");
+ if (is_regular_file (buf))
+ return xstrdup (to_host_file_spec (buf));
+ }
+ else
+ {
+ /* Otherwise look for shareable image libraries first. */
+ strcpy (ptr, ".exe");
+ if (is_regular_file (buf))
+ return xstrdup (to_host_file_spec (buf));
+
+ strcpy (ptr, ".a");
+ if (is_regular_file (buf))
+ return xstrdup (to_host_file_spec (buf));
+
+ strcpy (ptr, ".olb");
+ if (is_regular_file (buf))
+ return xstrdup (to_host_file_spec (buf));
+ }
+ }
+
+ return 0;
+}
+
+static const char *
+expand_lib (name)
+ char *name;
+{
+ char *lib, *lib_path;
+
+ if (strcmp (name, "c") == 0)
+ /* IEEE VAX C compatible library for non-prefixed (e.g. no DECC$)
+ C RTL functions. */
+ return "sys$library:vaxcrtltx.olb";
+
+ else if (strcmp (name, "m") == 0)
+ /* No separate library for math functions */
+ return "";
+
+ else
+ {
+ lib = xmalloc (strlen (name) + 14);
+
+ strcpy (lib, "lib");
+ strcat (lib, name);
+ lib_path = locate_lib (lib, search_dirs);
+
+ if (lib_path)
+ return lib_path;
+ }
+
+ fprintf (stderr,
+ "Couldn't locate library: lib%s.exe, lib%s.a or lib%s.olb\n",
+ name, name, name);
+
+ exit (1);
+}
+
+static int
+is_regular_file (name)
+ char *name;
+{
+ int ret;
+ struct stat statbuf;
+
+ ret = stat (name, &statbuf);
+ return !ret && S_ISREG (statbuf.st_mode);
+}
+
+static void
+preprocess_args (p_argc, argv)
+ int *p_argc;
+ char **argv;
+{
+ int i;
+
+ for (i = 1; i < *p_argc; i++)
+ if (strlen (argv[i]) >= 6 && strncmp (argv[i], "-shared", 7) == 0)
+ share = 1;
+
+ for (i = 1; i < *p_argc; i++)
+ if (strcmp (argv[i], "-o") == 0)
+ {
+ char *buff, *ptr;
+ int out_len;
+ int len;
+
+ i++;
+ ptr = to_host_file_spec (argv[i]);
+ exefilename = xstrdup (ptr);
+ out_len = strlen (ptr);
+ buff = xmalloc (out_len + 18);
+
+ if (share)
+ strcpy (buff, "/share=");
+ else
+ strcpy (buff, "/exe=");
+
+ strcat (buff, ptr);
+ addarg (buff);
+
+ if (share)
+ {
+ sharefilename = xmalloc (out_len+5);
+ if (ptr == strchr (argv[i], ']'))
+ strcpy (sharefilename, ++ptr);
+ else if (ptr == strchr (argv[i], ':'))
+ strcpy (sharefilename, ++ptr);
+ else if (ptr == strrchr (argv[i], '/'))
+ strcpy (sharefilename, ++ptr);
+ else
+ strcpy (sharefilename, argv[i]);
+
+ len = strlen (sharefilename);
+ if (strncasecmp (&sharefilename[len-4], ".exe", 4) == 0)
+ sharefilename[len-4] = 0;
+
+ for (ptr = sharefilename; *ptr; ptr++)
+ *ptr = TOUPPER (*ptr);
+ }
+ }
+}
+
+static void
+process_args (p_argc, argv)
+ int *p_argc;
+ char **argv;
+{
+ int i;
+
+ for (i = 1; i < *p_argc; i++)
+ {
+ if (strlen (argv[i]) < 2)
+ continue;
+
+ if (strncmp (argv[i], "-L", 2) == 0)
+ {
+ char *nbuff, *ptr;
+ int new_len, search_dirs_len;
+
+ ptr = &argv[i][2];
+ new_len = strlen (ptr);
+ search_dirs_len = strlen (search_dirs);
+
+ nbuff = xmalloc (new_len + 1);
+ strcpy (nbuff, ptr);
+
+ /* Remove trailing slashes. */
+ while (new_len > 1 && nbuff [new_len - 1] == '/')
+ {
+ nbuff [new_len - 1] = 0;
+ new_len--;
+ }
+
+ search_dirs = xrealloc (search_dirs, search_dirs_len + new_len + 2);
+ if (search_dirs_len > 0)
+ strcat (search_dirs, PATH_SEPARATOR_STR);
+
+ strcat (search_dirs, nbuff);
+ free (nbuff);
+ }
+
+ /* -v turns on verbose option here and is passed on to gcc. */
+ else if (strcmp (argv[i], "-v") == 0)
+ verbose = 1;
+ else if (strcmp (argv[i], "-g0") == 0)
+ addarg ("/notraceback");
+ else if (strncmp (argv[i], "-g", 2) == 0)
+ {
+ addarg ("/debug");
+ debug = 1;
+ }
+ else if (strcmp (argv[i], "-static") == 0)
+ staticp = 1;
+ else if (strcmp (argv[i], "-map") == 0)
+ {
+ char *buff, *ptr;
+
+ buff = xmalloc (strlen (exefilename) + 5);
+ strcpy (buff, exefilename);
+ ptr = strchr (buff, '.');
+ if (ptr)
+ *ptr = 0;
+
+ strcat (buff, ".map");
+ addarg ("/map=");
+ addarg (buff);
+ addarg ("/full");
+ }
+ else if (strcmp (argv[i], "-save-temps") == 0)
+ save_temps = 1;
+ else if (strcmp (argv[i], "--noinhibit-exec") == 0)
+ inhibit_exec = 0;
+ }
+}
+
+/* The main program. Spawn the VMS linker after fixing up the Unix-like flags
+ and args to be what the VMS linker wants. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+ char cwdev [128], *devptr;
+ int devlen;
+ int optfd;
+ FILE *optfile;
+ char *cwd = getcwd (0, 1024);
+ char *optfilename;
+
+ devptr = strchr (cwd, ':');
+ devlen = (devptr - cwd) + 1;
+ strncpy (cwdev, cwd, devlen);
+ cwdev [devlen] = '\0';
+
+ search_dirs = xmalloc (strlen (system_search_dirs) + 1);
+ strcpy (search_dirs, system_search_dirs);
+
+ addarg ("link");
+
+ /* Pass to find args that have to be append first. */
+ preprocess_args (&argc , argv);
+
+ /* Pass to find the rest of the args. */
+ process_args (&argc , argv);
+
+ /* Create a temp file to hold args, otherwise we can easily exceed the VMS
+ command line length limits. */
+ optfilename = alloca (strlen ("LDXXXXXX") + 1);
+ strcpy (optfilename, "LDXXXXXX");
+ optfd = mkstemp (optfilename);
+ getcwd (optfilefullname, 256, 1); /* VMS style cwd. */
+ strcat (optfilefullname, optfilename);
+ strcat (optfilefullname, ".");
+ optfile = fdopen (optfd, "w");
+
+ /* Write out the IDENTIFICATION argument first so that it can be overridden
+ by an options file. */
+ for (i = 1; i < argc; i++)
+ {
+ int arg_len = strlen (argv[i]);
+
+ if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
+ {
+ /* Comes from command line. If present will always appear before
+ IDENTIFICATION=... and will override. */
+
+ if (!ident)
+ ident = 1;
+ }
+ else if (arg_len > 15
+ && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0)
+ {
+ /* Comes from pragma Ident (). */
+
+ if (!ident)
+ {
+ fprintf (optfile, "case_sensitive=yes\n");
+ fprintf (optfile, "IDENTIFICATION=\"%15.15s\"\n", &argv[i][15]);
+ fprintf (optfile, "case_sensitive=NO\n");
+ ident = 1;
+ }
+ }
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ int arg_len = strlen (argv[i]);
+
+ if (strcmp (argv[i], "-o") == 0)
+ i++;
+ else if (arg_len > 2 && strncmp (argv[i], "-l", 2) == 0)
+ {
+ const char *libname = expand_lib (&argv[i][2]);
+ const char *ext;
+ int len;
+
+ if ((len = strlen (libname)) > 0)
+ {
+ char buff [256];
+
+ if (len > 4 && strcasecmp (&libname [len-4], ".exe") == 0)
+ ext = "/shareable";
+ else
+ ext = "/library";
+
+ if (libname[0] == '[')
+ sprintf (buff, "%s%s", cwdev, libname);
+ else
+ sprintf (buff, "%s", libname);
+
+ fprintf (optfile, "%s%s\n", buff, ext);
+ }
+ }
+
+ else if (strcmp (argv[i], "-v" ) == 0
+ || strncmp (argv[i], "-g", 2 ) == 0
+ || strcmp (argv[i], "-static" ) == 0
+ || strcmp (argv[i], "-map" ) == 0
+ || strcmp (argv[i], "-save-temps") == 0
+ || strcmp (argv[i], "--noinhibit-exec") == 0
+ || (arg_len > 2 && strncmp (argv[i], "-L", 2) == 0)
+ || (arg_len >= 6 && strncmp (argv[i], "-share", 6) == 0))
+ ;
+ else if (arg_len > 1 && argv[i][0] == '@')
+ {
+ FILE *atfile;
+ char *ptr, *ptr1;
+ struct stat statbuf;
+ char *buff;
+ int len;
+
+ if (stat (&argv[i][1], &statbuf))
+ {
+ fprintf (stderr, "Couldn't open linker response file: %s\n",
+ &argv[i][1]);
+ exit (1);
+ }
+
+ buff = xmalloc (statbuf.st_size + 1);
+ atfile = fopen (&argv[i][1], "r");
+ fgets (buff, statbuf.st_size + 1, atfile);
+ fclose (atfile);
+
+ len = strlen (buff);
+ if (buff [len - 1] == '\n')
+ {
+ buff [len - 1] = 0;
+ len--;
+ }
+
+ ptr = buff;
+
+ do
+ {
+ ptr1 = strchr (ptr, ' ');
+ if (ptr1)
+ *ptr1 = 0;
+ ptr = to_host_file_spec (ptr);
+ if (ptr[0] == '[')
+ fprintf (optfile, "%s%s\n", cwdev, ptr);
+ else
+ fprintf (optfile, "%s\n", ptr);
+ ptr = ptr1 + 1;
+ } while (ptr1);
+ }
+
+ /* Unix style file specs and VMS style switches look alike, so assume an
+ arg consisting of one and only one slash, and that being first, is
+ really a switch. */
+ else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0))
+ addarg (argv[i]);
+ else if (arg_len > 4
+ && strncasecmp (&argv[i][arg_len-4], ".OPT", 4) == 0)
+ {
+ FILE *optfile1;
+ char buff [256];
+
+ optfile1 = fopen (argv[i], "r");
+ while (fgets (buff, 256, optfile1))
+ fputs (buff, optfile);
+
+ fclose (optfile1);
+ }
+ else if (arg_len > 7 && strncasecmp (argv[i], "GSMATCH", 7) == 0)
+ fprintf (optfile, "%s\n", argv[i]);
+ else if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
+ {
+ /* Comes from command line and will override pragma. */
+ fprintf (optfile, "case_sensitive=yes\n");
+ fprintf (optfile, "IDENT=\"%15.15s\"\n", &argv[i][6]);
+ fprintf (optfile, "case_sensitive=NO\n");
+ ident = 1;
+ }
+ else if (arg_len > 15
+ && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0)
+ ;
+ else
+ {
+ /* Assume filename arg. */
+ const char *addswitch = "";
+ char buff [256];
+ int buff_len;
+ int is_cld = 0;
+
+ argv[i] = to_host_file_spec (argv[i]);
+ arg_len = strlen (argv[i]);
+
+ if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".exe") == 0)
+ addswitch = "/shareable";
+
+ if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".cld") == 0)
+ {
+ addswitch = "/shareable";
+ is_cld = 1;
+ }
+
+ if (arg_len > 2 && strcasecmp (&argv[i][arg_len-2], ".a") == 0)
+ addswitch = "/lib";
+
+ if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".olb") == 0)
+ addswitch = "/lib";
+
+ if (argv[i][0] == '[')
+ sprintf (buff, "%s%s%s\n", cwdev, argv[i], addswitch);
+ else if (strchr (argv[i], ':'))
+ sprintf (buff, "%s%s\n", argv[i], addswitch);
+ else
+ sprintf (buff, "%s%s%s\n", cwd, argv[i], addswitch);
+
+ buff_len = strlen (buff);
+
+ if (buff_len >= 15
+ && strcasecmp (&buff[buff_len - 15], "vms-dwarf2eh.o\n") == 0)
+ vmsdwarf2ehspec = xstrdup (buff);
+ else if (buff_len >= 13
+ && strcasecmp (&buff[buff_len - 13],"vms-dwarf2.o\n") == 0)
+ vmsdwarf2spec = xstrdup (buff);
+ else if (is_cld)
+ {
+ addarg (buff);
+ addarg (",");
+ }
+ else
+ fprintf (optfile, buff);
+ }
+ }
+
+#if 0
+ if (share)
+ fprintf (optfile, "symbol_vector=(main=procedure)\n");
+#endif
+
+ if (vmsdwarf2ehspec)
+ {
+ fprintf (optfile, "case_sensitive=yes\n");
+ fprintf (optfile, "cluster=DWARF2eh,,,%s", vmsdwarf2ehspec);
+ fprintf (optfile, "collect=DWARF2eh,eh_frame\n");
+ fprintf (optfile, "case_sensitive=NO\n");
+ }
+
+ if (debug && vmsdwarf2spec)
+ {
+ fprintf (optfile, "case_sensitive=yes\n");
+ fprintf (optfile, "cluster=DWARF2debug,,,%s", vmsdwarf2spec);
+ fprintf (optfile, "collect=DWARF2debug,debug_abbrev,debug_aranges,-\n");
+ fprintf (optfile, " debug_frame,debug_info,debug_line,debug_loc,-\n");
+ fprintf (optfile, " debug_macinfo,debug_pubnames,debug_str,-\n");
+ fprintf (optfile, " debug_zzzzzz\n");
+ fprintf (optfile, "case_sensitive=NO\n");
+ }
+
+ if (debug && share)
+ {
+ fprintf (optfile, "case_sensitive=yes\n");
+ fprintf (optfile, "symbol_vector=(-\n");
+ fprintf (optfile,
+ "%s$DWARF2.DEBUG_ABBREV/$dwarf2.debug_abbrev=DATA,-\n",
+ sharefilename);
+ fprintf (optfile,
+ "%s$DWARF2.DEBUG_ARANGES/$dwarf2.debug_aranges=DATA,-\n",
+ sharefilename);
+ fprintf (optfile, "%s$DWARF2.DEBUG_FRAME/$dwarf2.debug_frame=DATA,-\n",
+ sharefilename);
+ fprintf (optfile, "%s$DWARF2.DEBUG_INFO/$dwarf2.debug_info=DATA,-\n",
+ sharefilename);
+ fprintf (optfile, "%s$DWARF2.DEBUG_LINE/$dwarf2.debug_line=DATA,-\n",
+ sharefilename);
+ fprintf (optfile, "%s$DWARF2.DEBUG_LOC/$dwarf2.debug_loc=DATA,-\n",
+ sharefilename);
+ fprintf (optfile,
+ "%s$DWARF2.DEBUG_MACINFO/$dwarf2.debug_macinfo=DATA,-\n",
+ sharefilename);
+ fprintf (optfile,
+ "%s$DWARF2.DEBUG_PUBNAMES/$dwarf2.debug_pubnames=DATA,-\n",
+ sharefilename);
+ fprintf (optfile, "%s$DWARF2.DEBUG_STR/$dwarf2.debug_str=DATA,-\n",
+ sharefilename);
+ fprintf (optfile, "%s$DWARF2.DEBUG_ZZZZZZ/$dwarf2.debug_zzzzzz=DATA)\n",
+ sharefilename);
+ fprintf (optfile, "case_sensitive=NO\n");
+ }
+
+ fclose (optfile);
+ addarg (optfilefullname);
+ addarg ("/opt");
+
+ addarg (NULL);
+
+ if (verbose)
+ {
+ int i;
+
+ for (i = 0; i < link_arg_index; i++)
+ printf ("%s ", link_args [i]);
+ putchar ('\n');
+ }
+
+ {
+ int i;
+ int len = 0;
+
+ for (i = 0; link_args[i]; i++)
+ len = len + strlen (link_args[i]) + 1;
+
+ {
+ char *allargs = (char *) alloca (len + 1);
+ Descr cmd;
+ int status;
+ int status1 = 1;
+
+ for (i = 0; i < len + 1; i++)
+ allargs [i] = 0;
+
+ for (i = 0; link_args [i]; i++)
+ {
+ strcat (allargs, link_args [i]);
+ strcat (allargs, " ");
+ }
+
+ cmd.adr = allargs;
+ cmd.len = len;
+ cmd.mbz = 0;
+
+ i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status);
+ if ((i & 1) != 1)
+ {
+ LIB$SIGNAL (i);
+ exit (1);
+ }
+
+ if (debug && !share)
+ {
+ strcpy (allargs, "@gnu:[bin]set_exe ");
+ strcat (allargs, exefilename);
+ strcat (allargs, " /nodebug /silent");
+ len = strlen (allargs);
+ cmd.adr = allargs;
+ cmd.len = len;
+ cmd.mbz = 0;
+
+ if (verbose)
+ printf (allargs);
+
+ i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status1);
+
+ if ((i & 1) != 1)
+ {
+ LIB$SIGNAL (i);
+ exit (1);
+ }
+ }
+
+ if (!save_temps)
+ remove (optfilefullname);
+
+ if ((status & 1) == 1 && (status1 & 1) == 1)
+ exit (0);
+
+ if (exefilename && inhibit_exec == 1)
+ remove (exefilename);
+
+ exit (1);
+ }
+ }
+}
+
+static char new_host_filespec [255];
+static char filename_buff [256];
+
+static int
+translate_unix (name, type)
+ char *name;
+ int type ATTRIBUTE_UNUSED;
+{
+ strcpy (filename_buff, name);
+ return 0;
+}
+
+static char *
+to_host_file_spec (filespec)
+ char *filespec;
+{
+ strcpy (new_host_filespec, "");
+ if (strchr (filespec, ']') || strchr (filespec, ':'))
+ strcpy (new_host_filespec, filespec);
+ else
+ {
+ decc$to_vms (filespec, translate_unix, 1, 1);
+ strcpy (new_host_filespec, filename_buff);
+ }
+
+ return new_host_filespec;
+}
diff --git a/contrib/gcc/config/alpha/vms-psxcrt0-64.c b/contrib/gcc/config/alpha/vms-psxcrt0-64.c
new file mode 100644
index 0000000..be3e70d
--- /dev/null
+++ b/contrib/gcc/config/alpha/vms-psxcrt0-64.c
@@ -0,0 +1,128 @@
+/* VMS 64bit crt0 returning Unix style condition codes .
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Douglas B. Rupp (rupp@gnat.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#if !defined(__DECC)
+You Lose! This file can only be compiled with DEC C.
+#else
+
+/* This file can only be compiled with DEC C, due the the call to
+ lib$establish and the pragmas pointer_size. */
+
+#pragma __pointer_size short
+
+#include <stdlib.h>
+#include <string.h>
+#include <ssdef.h>
+#include <stsdef.h>
+#include <errnodef.h>
+
+extern void decc$main ();
+extern int main ();
+
+static int
+handler (sigargs, mechargs)
+ void *sigargs;
+ void *mechargs;
+{
+ return SS$_RESIGNAL;
+}
+
+int
+__main (arg1, arg2, arg3, image_file_desc, arg5, arg6)
+ void *arg1, *arg2, *arg3;
+ void *image_file_desc;
+ void *arg5, *arg6)
+{
+ int argc;
+ char **argv;
+ char **envp;
+
+#pragma __pointer_size long
+
+ int i;
+ char **long_argv;
+ char **long_envp;
+ int status;
+
+#pragma __pointer_size short
+
+ lib$establish (handler);
+ decc$main (arg1, arg2, arg3, image_file_desc,
+ arg5, arg6, &argc, &argv, &envp);
+
+#pragma __pointer_size long
+
+ /* Reallocate argv with 64 bit pointers. */
+ long_argv = (char **) malloc (sizeof (char *) * (argc + 1));
+
+ for (i = 0; i < argc; i++)
+ long_argv[i] = strdup (argv[i]);
+
+ long_argv[argc] = (char *) 0;
+
+ long_envp = (char **) malloc (sizeof (char *) * 5);
+
+ for (i = 0; envp[i]; i++)
+ long_envp[i] = strdup (envp[i]);
+
+ long_envp[i] = (char *) 0;
+
+#pragma __pointer_size short
+
+ status = main (argc, long_argv, long_envp);
+
+ /* Map into a range of 0 - 255. */
+ status = status & 255;
+
+ if (status > 0)
+ {
+ int save_status = status;
+
+ status = C$_EXIT1 + ((status - 1) << STS$V_MSG_NO);
+
+ /* An exit failure status requires a "severe" error. All status values
+ are defined in errno with a successful (1) severity but can be
+ changed to an error (2) severity by adding 1. In addition for
+ compatibility with UNIX exit() routines we inhibit a run-time error
+ message from being generated on exit(1). */
+
+ if (save_status == 1)
+ {
+ status++;
+ status |= STS$M_INHIB_MSG;
+ }
+ }
+
+ if (status == 0)
+ status = SS$_NORMAL;
+
+ return status;
+}
+#endif
diff --git a/contrib/gcc/config/alpha/vms-psxcrt0.c b/contrib/gcc/config/alpha/vms-psxcrt0.c
new file mode 100644
index 0000000..cdf5ced
--- /dev/null
+++ b/contrib/gcc/config/alpha/vms-psxcrt0.c
@@ -0,0 +1,99 @@
+/* VMS crt0 returning Unix style condition codes .
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Douglas B. Rupp (rupp@gnat.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#if !defined(__DECC)
+You Lose! This file can only be compiled with DEC C.
+#else
+
+/* This file can only be compiled with DEC C, due the the call to
+ lib$establish. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ssdef.h>
+#include <stsdef.h>
+#include <errnodef.h>
+
+extern void decc$main ();
+extern int main ();
+
+static int
+handler (sigargs, mechargs)
+ void *sigargs;
+ void *mechargs;
+{
+ return SS$_RESIGNAL;
+}
+
+int
+__main (arg1, arg2, arg3, image_file_desc, arg5, arg6)
+ void *arg1, *arg2, *arg3;
+ void *image_file_desc;
+ void *arg5, *arg6;
+{
+ int argc;
+ char **argv;
+ char **envp;
+ int status;
+
+ lib$establish (handler);
+ decc$main (arg1, arg2, arg3, image_file_desc, arg5, arg6,
+ &argc, &argv, &envp);
+
+ status = main (argc, argv, envp);
+
+ /* Map into a range of 0 - 255. */
+ status = status & 255;
+
+ if (status > 0)
+ {
+ int save_status = status;
+
+ status = C$_EXIT1 + ((status - 1) << STS$V_MSG_NO);
+
+ /* An exit failure status requires a "severe" error
+ All status values are defined in errno with a successful
+ (1) severity but can be changed to an error (2) severity by adding 1.
+ In addition for compatibility with UNIX exit() routines we inhibit
+ a run-time error message from being generated on exit(1). */
+
+ if (save_status == 1)
+ {
+ status++;
+ status |= STS$M_INHIB_MSG;
+ }
+ }
+
+ if (status == 0)
+ status = SS$_NORMAL;
+
+ return status;
+}
+#endif
diff --git a/contrib/gcc/config/alpha/vms.h b/contrib/gcc/config/alpha/vms.h
index 44388b2..a01556e 100644
--- a/contrib/gcc/config/alpha/vms.h
+++ b/contrib/gcc/config/alpha/vms.h
@@ -1,5 +1,6 @@
/* Output variables, constants and external declarations, for GNU compiler.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002
+ Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -18,7 +19,8 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define OPEN_VMS 1
+#define TARGET_OBJECT_SUFFIX ".obj"
+#define TARGET_EXECUTABLE_SUFFIX ".exe"
/* This enables certain macros in alpha.h, which will make an indirect
reference to an external symbol an invalid address. This needs to be
@@ -31,7 +33,7 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
-"-D__ALPHA -Dvms -DVMS -D__vms__ -D__VMS__ -Asystem(vms)"
+"-D__ALPHA -Dvms -DVMS -D__vms__ -D__VMS__ -Asystem=vms"
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC "\
@@ -39,38 +41,13 @@ Boston, MA 02111-1307, USA. */
%{mfloat-vax:-D__G_FLOAT} \
%{!mfloat-vax:-D__IEEE_FLOAT}"
-/* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf. */
-
-#define LIB_SPEC "%{p:-lprof1 -lpdf} %{pg:-lprof1 -lpdf} %{a:-lprof2} -lc"
-
-/* Pass "-G 8" to ld because Alpha's CC does. Pass -O3 if we are
- optimizing, -O1 if we are not. Pass -shared, -non_shared or
- -call_shared as appropriate. Also pass -pg. */
-#define LINK_SPEC \
- "-G 8 %{O*:-O3} %{!O*:-O1} %{static:-non_shared} \
- %{!static:%{shared:-shared} %{!shared:-call_shared}} %{pg} %{taso} \
- %{rpath*}"
-
-/* We allow $'s in identifiers unless -ansi is used .. */
-
-#define DOLLARS_IN_IDENTIFIERS 2
-
-/* These match the definitions used in DECCRTL, the VMS C run-time library
-
-#define SIZE_TYPE "unsigned int"
-#define PTRDIFF_TYPE "int"
-*/
-
-/* Use memcpy for structure copying, and so forth. */
-#define TARGET_MEM_FUNCTIONS
-
/* By default, allow $ to be part of an identifier. */
#define DOLLARS_IN_IDENTIFIERS 2
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_FP|MASK_FPREGS|MASK_GAS)
-#undef TARGET_OPEN_VMS
-#define TARGET_OPEN_VMS 1
+#undef TARGET_ABI_OPEN_VMS
+#define TARGET_ABI_OPEN_VMS 1
#undef TARGET_NAME
#define TARGET_NAME "OpenVMS/Alpha"
@@ -82,14 +59,12 @@ Boston, MA 02111-1307, USA. */
#define STRUCT_VALUE 0
#undef PCC_STATIC_STRUCT_RETURN
-/* no floating emulation. */
-#undef REAL_ARITHMETIC
-
-/* "long" is 32 bits. */
+/* "long" is 32 bits, but 64 bits for Ada. */
#undef LONG_TYPE_SIZE
#define LONG_TYPE_SIZE 32
+#define ADA_LONG_TYPE_SIZE 64
-/* Pointer is 32 bits but the hardware has 64-bit addresses, sign extended. */
+/* Pointer is 32 bits but the hardware has 64-bit addresses, sign extended. */
#undef POINTER_SIZE
#define POINTER_SIZE 32
#define POINTERS_EXTEND_UNSIGNED 0
@@ -110,9 +85,57 @@ Boston, MA 02111-1307, USA. */
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
+/* List the order in which to allocate registers. Each register must be
+ listed once, even those in FIXED_REGISTERS.
+
+ We allocate in the following order:
+ $f1 (nonsaved floating-point register)
+ $f10-$f15 (likewise)
+ $f22-$f30 (likewise)
+ $f21-$f16 (likewise, but input args)
+ $f0 (nonsaved, but return value)
+ $f2-$f9 (saved floating-point registers)
+ $1 (nonsaved integer registers)
+ $22-$25 (likewise)
+ $28 (likewise)
+ $0 (likewise, but return value)
+ $21-$16 (likewise, but input args)
+ $27 (procedure value in OSF, nonsaved in NT)
+ $2-$8 (saved integer registers)
+ $9-$14 (saved integer registers)
+ $26 (return PC)
+ $15 (frame pointer)
+ $29 (global pointer)
+ $30, $31, $f31 (stack pointer and always zero/ap & fp) */
+
+#undef REG_ALLOC_ORDER
+#define REG_ALLOC_ORDER \
+ {33, \
+ 42, 43, 44, 45, 46, 47, \
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, \
+ 53, 52, 51, 50, 49, 48, \
+ 32, \
+ 34, 35, 36, 37, 38, 39, 40, 41, \
+ 1, \
+ 22, 23, 24, 25, \
+ 28, \
+ 0, \
+ 21, 20, 19, 18, 17, 16, \
+ 27, \
+ 2, 3, 4, 5, 6, 7, 8, \
+ 9, 10, 11, 12, 13, 14, \
+ 26, \
+ 15, \
+ 29, \
+ 30, 31, 63 }
+
#undef HARD_FRAME_POINTER_REGNUM
#define HARD_FRAME_POINTER_REGNUM 29
+/* Define registers used by the epilogue and return instruction. */
+#undef EPILOGUE_USES
+#define EPILOGUE_USES(REGNO) ((REGNO) == 26 || (REGNO) == 29)
+
#undef CAN_ELIMINATE
#define CAN_ELIMINATE(FROM, TO) \
((TO) != STACK_POINTER_REGNUM || ! alpha_using_fp ())
@@ -126,6 +149,8 @@ Boston, MA 02111-1307, USA. */
+ get_frame_size () \
+ current_function_pretend_args_size) \
- current_function_pretend_args_size); \
+ else \
+ abort(); \
if ((TO) == STACK_POINTER_REGNUM) \
(OFFSET) += ALPHA_ROUND (current_function_outgoing_args_size); \
}
@@ -143,7 +168,7 @@ Boston, MA 02111-1307, USA. */
Thus 6 or more means all following args should go on the stack. */
enum avms_arg_type {I64, FF, FD, FG, FS, FT};
-typedef struct {char num_args; enum avms_arg_type atypes[6];} avms_arg_info;
+typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
#undef CUMULATIVE_ARGS
#define CUMULATIVE_ARGS avms_arg_info
@@ -158,41 +183,6 @@ typedef struct {char num_args; enum avms_arg_type atypes[6];} avms_arg_info;
(CUM).atypes[0] = (CUM).atypes[1] = (CUM).atypes[2] = I64; \
(CUM).atypes[3] = (CUM).atypes[4] = (CUM).atypes[5] = I64;
-/* Update the data in CUM to advance over an argument
- of mode MODE and data type TYPE.
- (TYPE is null for libcalls where that information may not be available.) */
-
-extern enum avms_arg_type alpha_arg_type ();
-
-/* Determine where to put an argument to a function.
- Value is zero to push the argument on the stack,
- or a hard register in which to store the argument.
-
- MODE is the argument's machine mode (or VOIDmode for no more args).
- TYPE is the data type of the argument (as a tree).
- This is null for libcalls where that information may
- not be available.
- CUM is a variable of type CUMULATIVE_ARGS which gives info about
- the preceding args and about the function being called.
- NAMED is nonzero if this argument is a named parameter
- (otherwise it is an extra parameter matching an ellipsis).
-
- On Alpha the first 6 words of args are normally in registers
- and the rest are pushed. */
-
-extern struct rtx_def *alpha_arg_info_reg_val ();
-#undef FUNCTION_ARG
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-((MODE) == VOIDmode ? alpha_arg_info_reg_val (CUM) \
- : ((CUM.num_args) < 6 && ! MUST_PASS_IN_STACK (MODE, TYPE) \
- ? gen_rtx(REG, (MODE), \
- ((CUM).num_args + 16 \
- + ((TARGET_FPREGS \
- && (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_FLOAT)) \
- * 32))) \
- : 0))
-
#undef FUNCTION_ARG_ADVANCE
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
if (MUST_PASS_IN_STACK (MODE, TYPE)) \
@@ -234,7 +224,7 @@ extern struct rtx_def *alpha_arg_info_reg_val ();
However, if NO registers need to be saved, don't allocate any space.
This is not only because we won't need the space, but because AP includes
the current_pretend_args_size and we don't want to mess up any
- ap-relative addresses already made. */
+ ap-relative addresses already made. */
#undef SETUP_INCOMING_VARARGS
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
@@ -242,7 +232,7 @@ extern struct rtx_def *alpha_arg_info_reg_val ();
{ \
if (! (NO_RTL)) \
{ \
- emit_move_insn (gen_rtx (REG, DImode, 1), \
+ emit_move_insn (gen_rtx_REG (DImode, 1), \
virtual_incoming_args_rtx); \
emit_insn (gen_arg_home ()); \
} \
@@ -251,6 +241,10 @@ extern struct rtx_def *alpha_arg_info_reg_val ();
} \
}
+/* ABI has stack checking, but it's broken. */
+#undef STACK_CHECK_BUILTIN
+#define STACK_CHECK_BUILTIN 0
+
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
{ \
@@ -260,33 +254,14 @@ extern struct rtx_def *alpha_arg_info_reg_val ();
ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
}
-#undef ASM_OUTPUT_FLOAT
-#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
- { \
- if (REAL_VALUE_ISINF (VALUE) \
- || REAL_VALUE_ISNAN (VALUE) \
- || REAL_VALUE_MINUS_ZERO (VALUE)) \
- { \
- long t; \
- REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
- fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \
- } \
- else \
- { \
- char str[30]; \
- REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
- fprintf (FILE, "\t.%c_floating %s\n", (TARGET_FLOAT_VAX)?'f':'s', str); \
- } \
- }
-
-#define LINK_SECTION_ASM_OP ".link"
-#define READONLY_SECTION_ASM_OP ".rdata"
-#define LITERALS_SECTION_ASM_OP ".literals"
-#define CTORS_SECTION_ASM_OP ".ctors"
-#define DTORS_SECTION_ASM_OP ".dtors"
+#define LINK_SECTION_ASM_OP "\t.link"
+#define READONLY_SECTION_ASM_OP "\t.rdata"
+#define LITERALS_SECTION_ASM_OP "\t.literals"
+#define CTORS_SECTION_ASM_OP "\t.ctors"
+#define DTORS_SECTION_ASM_OP "\t.dtors"
#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_link, in_rdata, in_literals, in_ctors, in_dtors
+#define EXTRA_SECTIONS in_link, in_rdata, in_literals
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
@@ -316,26 +291,12 @@ literals_section () \
fprintf (asm_out_file, "%s\n", LITERALS_SECTION_ASM_OP); \
in_section = in_literals; \
} \
-} \
-void \
-ctors_section () \
-{ \
- if (in_section != in_ctors) \
- { \
- fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \
- in_section = in_ctors; \
- } \
-} \
-void \
-dtors_section () \
-{ \
- if (in_section != in_dtors) \
- { \
- fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \
- in_section = in_dtors; \
- } \
}
+extern void readonly_section PARAMS ((void));
+extern void link_section PARAMS ((void));
+extern void literals_section PARAMS ((void));
+
#undef ASM_OUTPUT_ADDR_DIFF_ELT
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort ()
@@ -359,17 +320,16 @@ dtors_section () \
/* This says how to output assembler code to declare an
uninitialized external linkage data object. */
-#define COMMON_ASM_OP ".comm"
+#define COMMON_ASM_OP "\t.comm\t"
#undef ASM_OUTPUT_ALIGNED_COMMON
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
do { \
- fprintf ((FILE), "\t%s\t", COMMON_ASM_OP); \
+ fprintf ((FILE), "%s", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
} while (0)
-#define NO_MD_PROTOTYPES
/* Output assembler code for a block containing the constant parts
of a trampoline, leaving space for the variable parts.
@@ -377,8 +337,7 @@ do { \
The trampoline should set the static chain pointer to value placed
into the trampoline and should branch to the specified routine.
Note that $27 has been set to the address of the trampoline, so we can
- use it for addressability of the two data items. Trampolines are always
- aligned to FUNCTION_BOUNDARY, which is 64 bits. */
+ use it for addressability of the two data items. */
#undef TRAMPOLINE_TEMPLATE
#define TRAMPOLINE_TEMPLATE(FILE) \
@@ -393,6 +352,11 @@ do { \
#undef TRAMPOLINE_SIZE
#define TRAMPOLINE_SIZE 32
+/* The alignment of a trampoline, in bits. */
+
+#undef TRAMPOLINE_ALIGNMENT
+#define TRAMPOLINE_ALIGNMENT 64
+
/* 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. */
@@ -401,35 +365,69 @@ do { \
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 16, 24, -1)
-/* A C statement (sans semicolon) to output an element in the table of
- global constructors. */
-#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
- do { \
- ctors_section (); \
- fprintf (FILE, "\t.quad "); \
- assemble_name (FILE, NAME); \
- fprintf (FILE, "\n"); \
- } while (0)
-
-/* A C statement (sans semicolon) to output an element in the table of
- global destructors. */
-#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
- do { \
- dtors_section (); \
- fprintf (FILE, "\t.quad "); \
- assemble_name (FILE, NAME); \
- fprintf (FILE, "\n"); \
- } while (0)
-
-#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \
- (vms_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS))
-extern int vms_valid_decl_attribute_p ();
+/* Control how constructors and destructors are emitted. */
+#define TARGET_ASM_CONSTRUCTOR vms_asm_out_constructor
+#define TARGET_ASM_DESTRUCTOR vms_asm_out_destructor
#undef SDB_DEBUGGING_INFO
#undef MIPS_DEBUGGING_INFO
#undef DBX_DEBUGGING_INFO
#define DWARF2_DEBUGGING_INFO
+#define VMS_DEBUGGING_INFO
+
+#define DWARF2_UNWIND_INFO 1
+
+#undef EH_RETURN_HANDLER_RTX
+#define EH_RETURN_HANDLER_RTX \
+ gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx, 8))
+
+#define LINK_EH_SPEC "vms-dwarf2eh.o%s "
+
+#ifdef IN_LIBGCC2
+#include <libicb.h>
+#include <pdscdef.h>
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
+ do { \
+ unsigned long handle; \
+ PDSCDEF *pv; \
+ INVO_CONTEXT_BLK invo; \
+ \
+ memset (&invo, 0, sizeof (INVO_CONTEXT_BLK)); \
+ \
+ invo.libicb$q_ireg [29] = *((long long *) (CONTEXT)->reg [29]); \
+ invo.libicb$q_ireg [30] = (long long) (CONTEXT)->cfa; \
+ handle = LIB$GET_INVO_HANDLE (&invo); \
+ LIB$GET_INVO_CONTEXT (handle, &invo); \
+ pv = (PDSCDEF *) invo.libicb$ph_procedure_descriptor; \
+ \
+ if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_STACK)) \
+ { \
+ int i, j; \
+ \
+ (FS)->cfa_offset = pv->pdsc$l_size; \
+ (FS)->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30; \
+ (FS)->retaddr_column = 26; \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->regs.reg[27].loc.offset = -pv->pdsc$l_size; \
+ (FS)->regs.reg[27].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[26].loc.offset \
+ = -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset); \
+ (FS)->regs.reg[26].how = REG_SAVED_OFFSET; \
+ \
+ for (i = 0, j = 0; i < 32; i++) \
+ if (1<<i & pv->pdsc$l_ireg_mask) \
+ { \
+ (FS)->regs.reg[i].loc.offset \
+ = -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset - 8 * ++j); \
+ (FS)->regs.reg[i].how = REG_SAVED_OFFSET; \
+ } \
+ \
+ goto SUCCESS; \
+ } \
+} while (0)
+#endif
/* This is how to output an assembler line
that says to advance the location counter
@@ -439,30 +437,8 @@ extern int vms_valid_decl_attribute_p ();
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
fprintf (FILE, "\t.align %d\n", LOG);
-#define ASM_OUTPUT_SECTION(FILE,SECTION) \
- (strcmp (SECTION, ".text") == 0) \
- ? text_section () \
- : named_section (NULL_TREE, SECTION, 0), \
- ASM_OUTPUT_ALIGN (FILE, 0) \
-
-#define ASM_OUTPUT_SECTION_NAME(FILE,DECL,NAME,RELOC) \
- do \
- { \
- char *flags; \
- int ovr = 0; \
- if (DECL && DECL_MACHINE_ATTRIBUTES (DECL) \
- && lookup_attribute \
- ("overlaid", DECL_MACHINE_ATTRIBUTES (DECL))) \
- flags = ",OVR", ovr = 1; \
- else if (strncmp (NAME,".debug", 6) == 0) \
- flags = ",NOWRT"; \
- else \
- flags = ""; \
- fputc ('\n', (FILE)); \
- fprintf (FILE, ".section\t%s%s\n", NAME, flags); \
- if (ovr) \
- (NAME) = ""; \
- } while (0)
+/* Switch into a generic section. */
+#define TARGET_ASM_NAMED_SECTION vms_asm_named_section
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
do { literals_section(); \
@@ -474,7 +450,7 @@ extern int vms_valid_decl_attribute_p ();
} while (0)
#undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+#define PREFERRED_DEBUGGING_TYPE VMS_AND_DWARF2_DEBUG
#undef ASM_FORMAT_PRIVATE_NAME
#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
@@ -486,10 +462,38 @@ extern int vms_valid_decl_attribute_p ();
#undef ASM_SPEC
#undef ASM_FINAL_SPEC
+
+/* The VMS convention is to always provide minimal debug info
+ for a traceback unless specifically overridden. Defaulting this here
+ is a kludge. */
+
+#define OPTIMIZATION_OPTIONS(OPTIMIZE, OPTIMIZE_SIZE) \
+{ \
+ write_symbols = VMS_DEBUG; \
+ debug_info_level = (enum debug_info_level) 1; \
+}
+
+/* Override traceback debug info on -g0. */
+#undef OVERRIDE_OPTIONS
+#define OVERRIDE_OPTIONS \
+{ \
+ if (write_symbols == NO_DEBUG) \
+ debug_info_level = (enum debug_info_level) 0; \
+ override_options (); \
+}
+
+/* Link with vms-dwarf2.o if -g (except -g0). This causes the
+ VMS link to pull all the dwarf2 debug sections together. */
#undef LINK_SPEC
+#define LINK_SPEC "%{g:-g vms-dwarf2.o%s} %{g0} %{g1:-g1 vms-dwarf2.o%s} \
+%{g2:-g2 vms-dwarf2.o%s} %{g3:-g3 vms-dwarf2.o%s} %{shared} %{v} %{map}"
+
#undef STARTFILE_SPEC
-#define ASM_SPEC "-nocpp %{pg}"
-#define LINK_SPEC "%{g3:-g3} %{g0:-g0} %{shared:-shared} %{v:-v}"
+#define STARTFILE_SPEC "%{!shared:%{mvms-return-codes:vcrt0.o%s} \
+%{!mvms-return-codes:pcrt0.o%s}}"
+
+#undef LIB_SPEC
+#define LIB_SPEC "-lc"
/* Define the names of the division and modulus functions. */
#define DIVSI3_LIBCALL "OTS$DIV_I"
@@ -501,6 +505,14 @@ extern int vms_valid_decl_attribute_p ();
#define UMODSI3_LIBCALL "OTS$REM_UI"
#define UMODDI3_LIBCALL "OTS$REM_UL"
-#define DIR_SEPARATOR ']'
+#define NAME__MAIN "__gccmain"
+#define SYMBOL__MAIN __gccmain
-#define PREFIX "GNU_ROOT:"
+/* Specify the list of include file directories. */
+#define INCLUDE_DEFAULTS \
+{ \
+ { "/gnu_gxx_include", 0, 1, 1 }, \
+ { "/gnu_cc_include", 0, 0, 0 }, \
+ { "/gnu/include", 0, 0, 0 }, \
+ { 0, 0, 0, 0 } \
+}
diff --git a/contrib/gcc/config/alpha/vms64.h b/contrib/gcc/config/alpha/vms64.h
new file mode 100644
index 0000000..3b4f587
--- /dev/null
+++ b/contrib/gcc/config/alpha/vms64.h
@@ -0,0 +1,32 @@
+/* Output variables, constants and external declarations, for GNU compiler.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Douglas Rupp (rupp@gnat.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Defaults to BITS_PER_WORD, e.g. 64 which is what is wanted.
+ This is incompatible with DEC C, but matches DEC Ada */
+#undef LONG_TYPE_SIZE
+
+/* Defaults to "long int" */
+#undef SIZE_TYPE
+#undef PTRDIFF_TYPE
+
+#undef POINTERS_EXTEND_UNSIGNED
+#undef POINTER_SIZE
+#define POINTER_SIZE 64
diff --git a/contrib/gcc/config/alpha/vms_tramp.asm b/contrib/gcc/config/alpha/vms_tramp.asm
new file mode 100644
index 0000000..9a6a1c8
--- /dev/null
+++ b/contrib/gcc/config/alpha/vms_tramp.asm
@@ -0,0 +1,52 @@
+/* VMS trampoline for nested functions
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Douglas B. Rupp (rupp@gnat.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+;# Alpha OpenVMS trampoline
+;#
+ .set noreorder
+ .set volatile
+ .set noat
+ .file 1 "vms_tramp.asm"
+.text
+ .align 3
+ .globl __tramp
+ .ent __tramp
+__tramp..en:
+
+.link
+ .align 3
+__tramp:
+ .pdesc __tramp..en,null
+.text
+ ldq $1,24($27)
+ ldq $27,16($27)
+ ldq $28,8($27)
+ jmp $31,($28),0
+ .end __tramp
diff --git a/contrib/gcc/config/alpha/vxworks.h b/contrib/gcc/config/alpha/vxworks.h
index 7ef1fee..2f711ce 100644
--- a/contrib/gcc/config/alpha/vxworks.h
+++ b/contrib/gcc/config/alpha/vxworks.h
@@ -28,8 +28,8 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "\
--D__vxworks -D__alpha_vxworks -Asystem(vxworks) \
--Asystem(embedded) -D_LONGLONG"
+-D__vxworks -D__alpha_vxworks -Asystem=vxworks \
+-Asystem=embedded -D_LONGLONG"
/* VxWorks does all the library stuff itself. */
diff --git a/contrib/gcc/config/alpha/x-vms b/contrib/gcc/config/alpha/x-vms
new file mode 100644
index 0000000..f53f1c7
--- /dev/null
+++ b/contrib/gcc/config/alpha/x-vms
@@ -0,0 +1,22 @@
+# Under VMS, directory names cannot contain dots.
+version:=$(shell echo $(gcc_version) | sed -e 's/\./_/g')
+
+# Rules for linker and compiler wrappers. These are only useful on
+# a VMS host.
+EXTRA_PROGRAMS=ld.exe decc.exe
+vms-ld.o : $(srcdir)/config/alpha/vms-ld.c
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+ld.exe : vms-ld.o
+ $(CC) -o $@ vms-ld.o ../libiberty/libiberty.a
+
+vms-cc.o : $(srcdir)/config/alpha/vms-cc.c
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+decc.exe : vms-cc.o
+ $(CC) -o $@ vms-cc.o ../libiberty/libiberty.a
+
+# These extra parts can only be compiled on a VMS host and are only needed
+# on a VMS target. The rules are in t-vms.
+VMS_EXTRA_PARTS=vcrt0.o pcrt0.o
+
+# Doesn't work on VMS
+USE_COLLECT2=
diff --git a/contrib/gcc/config/alpha/xm-alpha-interix.h b/contrib/gcc/config/alpha/xm-alpha-interix.h
index 02c53b8..dd71a1d 100644
--- a/contrib/gcc/config/alpha/xm-alpha-interix.h
+++ b/contrib/gcc/config/alpha/xm-alpha-interix.h
@@ -1,6 +1,6 @@
/* Configuration for GNU compiler
for an DEC/Compaq Alpha
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001 Free Software Foundation, Inc.
Donn Terry, Softway Systems, Inc.
derived from code by Douglas B. Rupp (drupp@cs.washington.edu)
@@ -21,11 +21,6 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <alpha/xm-alpha.h>
-
-#undef HOST_BITS_PER_LONG
-#define HOST_BITS_PER_LONG 32
-
#define HOST_BITS_PER_WIDE_INT 64
#ifdef __GNUC__
# define HOST_WIDE_INT long long
@@ -33,7 +28,6 @@ Boston, MA 02111-1307, USA. */
# define HOST_WIDE_INT __int64
#endif
-
#define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG
#ifdef __GNUC__
# define HOST_WIDEST_INT long long
diff --git a/contrib/gcc/config/alpha/xm-vms.h b/contrib/gcc/config/alpha/xm-vms.h
index 472a225..d728ec1 100644
--- a/contrib/gcc/config/alpha/xm-vms.h
+++ b/contrib/gcc/config/alpha/xm-vms.h
@@ -1,5 +1,5 @@
/* Configuration for GNU C-compiler for openVMS/Alpha.
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc.
Contributed by Klaus Kaempf (kkaempf@progis.de).
This file is part of GNU CC.
@@ -19,75 +19,27 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* If compiling with DECC, need to fix problem with <stdio.h>
- which defines a macro called FILE_TYPE that breaks "tree.h".
- Fortunately it uses #ifndef to suppress multiple inclusions.
- Three possible cases:
- 1) <stdio.h> has already been included -- ours will be no-op;
- 2) <stdio.h> will be included after us -- "theirs" will be no-op;
- 3) <stdio.h> isn't needed -- including it here shouldn't hurt.
- In all three cases, the problem macro will be removed here. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef __DECC
-#undef FILE_TYPE
-#endif
-
-#undef HOST_BITS_PER_LONG
-#define HOST_BITS_PER_LONG 32
-
#define HOST_WIDE_INT long long
#define HOST_BITS_PER_WIDE_INT 64
-#undef SUCCESS_EXIT_CODE
-#define SUCCESS_EXIT_CODE 1
-#undef FATAL_EXIT_CODE
-#define FATAL_EXIT_CODE (44 | 0x10000000) /* Abort, and no DCL message. */
-
/* A couple of conditionals for execution machine are controlled here. */
#ifndef VMS
#define VMS
#endif
-#define GCC_INCLUDE_DIR ""
-/* Specify the list of include file directories. */
-#define INCLUDE_DEFAULTS \
-{ \
- { "GNU_GXX_INCLUDE:", "G++", 1, 1 }, \
- { "GNU_CC_INCLUDE:", "GCC", 0, 0 }, \
- { ".", 0, 0, 1 }, \
- { 0, 0, 0, 0 } \
-}
-
/* Define a local equivalent (sort of) for unlink */
#define unlink remove
-#define NEED_ATEXIT
-#define HAVE_VPRINTF
-#define HAVE_PUTENV
-#define HAVE_STRERROR
-#define HAVE_ATOLL
+/* Causes exit() to be redefined to __posix_exit() and
+ Posix compatible failure and success codes to be used */
+#define _POSIX_EXIT 1
-#define NO_SYS_PARAMS_H /* Don't have <sys/params.h> */
-#define USE_C_ALLOCA /* Using alloca.c */
+/* Open files in stream mode if not otherwise explicitly specified */
+#define __UNIX_FOPEN 1
-#define HAVE_FCNTL_H 1
-#define HAVE_STDLIB_H 1
-#define HAVE_UNISTD_H 1
-#define HAVE_STRING_H 1
-#define HAVE_LIMITS_H 1
-#define HAVE_STDDEF_H 1
-#define HAVE_TIME_H 1
#define STDC_HEADERS 1
-#define HAVE_CPP_STRINGIFY 1
-#if __STDC__
-extern void *alloca (size_t);
-#else
-extern char *alloca (unsigned int);
-#endif
+#define HOST_EXECUTABLE_SUFFIX ".exe"
+#define HOST_OBJECT_SUFFIX ".obj"
-#define OBJECT_SUFFIX ".obj"
-#define EXECUTABLE_SUFFIX ".exe"
+#define DUMPFILE_FORMAT "_%02d_"
diff --git a/contrib/gcc/config/alpha/xm-vms64.h b/contrib/gcc/config/alpha/xm-vms64.h
new file mode 100644
index 0000000..26fd829
--- /dev/null
+++ b/contrib/gcc/config/alpha/xm-vms64.h
@@ -0,0 +1,29 @@
+/* Configuration for GNU C-compiler for openVMS/Alpha.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Douglas Rupp (rupp@gnat.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef HOST_WIDE_INT
+
+/* Since DEC C long != Gnu C long */
+#define HOST_PTR_PRINTF "%llx"
+#define HOST_WIDE_INT_PRINT_DEC "%lld"
+#define HOST_WIDE_INT_PRINT_UNSIGNED "%llu"
+#define HOST_WIDE_INT_PRINT_HEX "0x%llx"
+#define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%llx%016llx"
OpenPOWER on IntegriCloud