diff options
Diffstat (limited to 'contrib/gcc/config/alpha')
36 files changed, 0 insertions, 16372 deletions
diff --git a/contrib/gcc/config/alpha/alpha-interix.h b/contrib/gcc/config/alpha/alpha-interix.h deleted file mode 100644 index 668fe9397af5..000000000000 --- a/contrib/gcc/config/alpha/alpha-interix.h +++ /dev/null @@ -1,252 +0,0 @@ -/* Definitions of target machine for GNU compiler, for DEC Alpha - running Windows/NT. - Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. - - Donn Terry, Softway Systems, Inc. - From code - 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, -Boston, MA 02111-1307, USA. */ - -/* cpp handles __STDC__ */ -/* The three "Alpha" defines on the first such line are from the CLAXP spec */ -#undef CPP_PREDEFINES -#define CPP_PREDEFINES " \ - -D__INTERIX \ - -D__OPENNT \ - -D__Alpha_AXP -D_M_ALPHA -D_ALPHA_ \ - -D__alpha -D__alpha__\ - -D__stdcall= \ - -D__cdecl= \ - -Asystem(unix) -Asystem(interix) -Asystem(interix) -Acpu(alpha) -Amachine(alpha)" - -#undef CPP_SUBTARGET_SPEC -#define CPP_SUBTARGET_SPEC "\ --remap \ -%{posix:-D_POSIX_SOURCE} \ --idirafter %$INTERIX_ROOT/usr/include" - -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (alpha Interix)"); - -/* alpha.h sets this, but it doesn't apply to us */ -#undef OBJECT_FORMAT_ECOFF -#undef OBJECT_FORMAT_COFF - -/* LINK_SPEC */ - -/* MD_STARTFILE_PREFIX */ - -/* ASM_OUTPUT_LOOP_ALIGN; ASM_OUTPUT_ALIGN_CODE */ - -/* Codegen macro overrides for NT internal conventions */ - -/* the below are ecoff specific... we don't need them, so - undef them (they'll get a default later) */ - -#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++. - Note that there appears to be two different ways to support const - sections at the moment. You can either #define the symbol - READONLY_DATA_SECTION (giving it some code which switches to the - readonly data section) or else you can #define the symbols - EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and - SELECT_RTX_SECTION. We do both here just to be on the safe side. */ - -#define USE_CONST_SECTION 1 - -#define CONST_SECTION_ASM_OP ".rdata" - -/* Define the pseudo-ops used to switch to the .ctors and .dtors sections. - - Note that we want to give these sections the SHF_WRITE attribute - because these sections will actually contain data (i.e. tables of - addresses of functions in the current root executable or shared library - file) and, in the case of a shared library, the relocatable addresses - will have to be properly resolved/relocated (and then written into) by - the dynamic linker when it actually attaches the given shared library - to the executing process. (Note that on SVR4, you may wish to use the - `-z text' option to the ELF linker, when building a shared library, as - an additional check that you are doing everything right. But if you do - use the `-z text' option when building a shared library, you will get - 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" - -/* 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 - should override this definition in the target-specific file which - includes this file. */ - -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_const, in_ctors, in_dtors - -/* A default list of extra section function definitions. For targets - that use additional sections (e.g. .tdesc) you should override this - definition in the target-specific file which includes this file. */ - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ - CONST_SECTION_FUNCTION \ - CTORS_SECTION_FUNCTION \ - DTORS_SECTION_FUNCTION - -#undef READONLY_DATA_SECTION -#define READONLY_DATA_SECTION() const_section () - -extern void text_section (); - -#define CONST_SECTION_FUNCTION \ -void \ -const_section () \ -{ \ - if (!USE_CONST_SECTION) \ - text_section(); \ - else if (in_section != in_const) \ - { \ - fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \ - in_section = in_const; \ - } \ -} - -#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). */ -#define CTOR_LISTS_DEFINED_EXTERNALLY 1 - -#define SET_ASM_OP ".set" -/* Output a definition (implements alias) */ -#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \ -do \ -{ \ - fprintf ((FILE), "\t"); \ - assemble_name (FILE, LABEL1); \ - fprintf (FILE, "="); \ - assemble_name (FILE, LABEL2); \ - fprintf (FILE, "\n"); \ - } \ -while (0) - -/* We use the defaults, so undef the null definitions */ -#undef PUT_SDB_FUNCTION_START -#undef PUT_SDB_FUNCTION_END -#undef PUT_SDB_EPILOGUE_END - -#define HOST_PTR_PRINTF "%p" -#define HOST_PTR_AS_INT unsigned long - -#define PCC_BITFIELD_TYPE_MATTERS 1 -#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. */ -#undef DWARF2_UNWIND_INFO - -/* Don't assume anything about the header files. */ -#define NO_IMPLICIT_EXTERN_C - -/* The definition of this macro implies that there are cases where - a scalar value cannot be returned in registers. - - 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). */ - -#undef RETURN_IN_MEMORY -#define RETURN_IN_MEMORY(TYPE) \ - (TREE_CODE (TYPE) == ARRAY_TYPE || int_size_in_bytes(TYPE) > 8) - -#define ASM_LOAD_ADDR(loc, reg) " lda " #reg "," #loc "\n" - -#undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ -{ \ - alpha_write_verstamp (FILE); \ - fprintf (FILE, "\t.set noreorder\n"); \ - fprintf (FILE, "\t.set volatile\n"); \ - fprintf (FILE, "\t.set noat\n"); \ - fprintf (FILE, "\t.globl\t__fltused\n"); \ - ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \ -} - -/* The current Interix assembler (consistent with the DEC documentation) - 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 { \ - assemble_name (FILE, SY); \ - fputc ('=', FILE); \ - assemble_name (FILE, HI); \ - fputc ('-', FILE); \ - assemble_name (FILE, LO); \ - } while (0) diff --git a/contrib/gcc/config/alpha/alpha.c b/contrib/gcc/config/alpha/alpha.c deleted file mode 100644 index 2d62693d76bd..000000000000 --- a/contrib/gcc/config/alpha/alpha.c +++ /dev/null @@ -1,5280 +0,0 @@ -/* Subroutines used for code generation on the DEC Alpha. - Copyright (C) 1992, 93-98, 1999 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, -Boston, MA 02111-1307, USA. */ - - -#include "config.h" -#include "system.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "real.h" -#include "insn-config.h" -#include "conditions.h" -#include "insn-flags.h" -#include "output.h" -#include "insn-attr.h" -#include "flags.h" -#include "recog.h" -#include "reload.h" -#include "tree.h" -#include "expr.h" -#include "obstack.h" -#include "except.h" -#include "function.h" -#include "toplev.h" - -/* External data. */ -extern char *version_string; -extern int rtx_equal_function_value_matters; - -/* Specify which cpu to schedule for. */ - -enum processor_type alpha_cpu; -static const char * const alpha_cpu_name[] = -{ - "ev4", "ev5", "ev6" -}; - -/* Specify how accurate floating-point traps need to be. */ - -enum alpha_trap_precision alpha_tp; - -/* Specify the floating-point rounding mode. */ - -enum alpha_fp_rounding_mode alpha_fprm; - -/* Specify which things cause traps. */ - -enum alpha_fp_trap_mode alpha_fptm; - -/* Strings decoded into the above options. */ - -const char *alpha_cpu_string; /* -mcpu= */ -const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */ -const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */ -const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */ -const char *alpha_mlat_string; /* -mmemory-latency= */ - -/* Save information from a "cmpxx" operation until the branch or scc is - emitted. */ - -rtx alpha_compare_op0, alpha_compare_op1; -int alpha_compare_fp_p; - -/* Define the information needed to modify the epilogue for EH. */ - -rtx alpha_eh_epilogue_sp_ofs; - -/* Non-zero if inside of a function, because the Alpha asm can't - handle .files inside of functions. */ - -static int inside_function = FALSE; - -/* If non-null, this rtx holds the return address for the function. */ - -static rtx alpha_return_addr_rtx; - -/* The number of cycles of latency we should assume on memory reads. */ - -int alpha_memory_latency = 3; - -/* Whether the function needs the GP. */ - -static int alpha_function_needs_gp; - -/* The alias set for prologue/epilogue register save/restore. */ - -static int alpha_sr_alias_set; - -/* Declarations of static functions. */ -static void alpha_set_memflags_1 - PROTO((rtx, int, int, int)); -static rtx alpha_emit_set_const_1 - PROTO((rtx, enum machine_mode, HOST_WIDE_INT, int)); -static void alpha_expand_unaligned_load_words - PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs)); -static void alpha_expand_unaligned_store_words - PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs)); -static void alpha_sa_mask - PROTO((unsigned long *imaskP, unsigned long *fmaskP)); -static int alpha_does_function_need_gp - PROTO((void)); - - -/* Get the number of args of a function in one of two ways. */ -#ifdef OPEN_VMS -#define NUM_ARGS current_function_args_info.num_args -#else -#define NUM_ARGS current_function_args_info -#endif - -#define REG_PV 27 -#define REG_RA 26 - -/* Parse target option strings. */ - -void -override_options () -{ - alpha_tp = ALPHA_TP_PROG; - alpha_fprm = ALPHA_FPRM_NORM; - alpha_fptm = ALPHA_FPTM_N; - - if (TARGET_IEEE) - { - alpha_tp = ALPHA_TP_INSN; - alpha_fptm = ALPHA_FPTM_SU; - } - - if (TARGET_IEEE_WITH_INEXACT) - { - alpha_tp = ALPHA_TP_INSN; - alpha_fptm = ALPHA_FPTM_SUI; - } - - if (alpha_tp_string) - { - if (! strcmp (alpha_tp_string, "p")) - alpha_tp = ALPHA_TP_PROG; - else if (! strcmp (alpha_tp_string, "f")) - alpha_tp = ALPHA_TP_FUNC; - else if (! strcmp (alpha_tp_string, "i")) - alpha_tp = ALPHA_TP_INSN; - else - error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string); - } - - if (alpha_fprm_string) - { - if (! strcmp (alpha_fprm_string, "n")) - alpha_fprm = ALPHA_FPRM_NORM; - else if (! strcmp (alpha_fprm_string, "m")) - alpha_fprm = ALPHA_FPRM_MINF; - else if (! strcmp (alpha_fprm_string, "c")) - alpha_fprm = ALPHA_FPRM_CHOP; - else if (! strcmp (alpha_fprm_string,"d")) - alpha_fprm = ALPHA_FPRM_DYN; - else - error ("bad value `%s' for -mfp-rounding-mode switch", - alpha_fprm_string); - } - - if (alpha_fptm_string) - { - if (strcmp (alpha_fptm_string, "n") == 0) - alpha_fptm = ALPHA_FPTM_N; - else if (strcmp (alpha_fptm_string, "u") == 0) - alpha_fptm = ALPHA_FPTM_U; - else if (strcmp (alpha_fptm_string, "su") == 0) - alpha_fptm = ALPHA_FPTM_SU; - else if (strcmp (alpha_fptm_string, "sui") == 0) - alpha_fptm = ALPHA_FPTM_SUI; - else - error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string); - } - - alpha_cpu - = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6 - : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4); - - if (alpha_cpu_string) - { - if (! strcmp (alpha_cpu_string, "ev4") - || ! strcmp (alpha_cpu_string, "21064")) - { - alpha_cpu = PROCESSOR_EV4; - target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX); - } - else if (! strcmp (alpha_cpu_string, "ev5") - || ! strcmp (alpha_cpu_string, "21164")) - { - alpha_cpu = PROCESSOR_EV5; - target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX); - } - else if (! strcmp (alpha_cpu_string, "ev56") - || ! strcmp (alpha_cpu_string, "21164a")) - { - alpha_cpu = PROCESSOR_EV5; - target_flags |= MASK_BWX; - target_flags &= ~ (MASK_MAX | MASK_FIX | MASK_CIX); - } - else if (! strcmp (alpha_cpu_string, "pca56") - || ! strcmp (alpha_cpu_string, "21164PC") - || ! strcmp (alpha_cpu_string, "21164pc")) - { - alpha_cpu = PROCESSOR_EV5; - target_flags |= MASK_BWX | MASK_MAX; - target_flags &= ~ (MASK_FIX | MASK_CIX); - } - else if (! strcmp (alpha_cpu_string, "ev6") - || ! strcmp (alpha_cpu_string, "21264")) - { - alpha_cpu = PROCESSOR_EV6; - target_flags |= MASK_BWX | MASK_MAX | MASK_FIX; - target_flags &= ~ (MASK_CIX); - } - else - error ("bad value `%s' for -mcpu switch", alpha_cpu_string); - } - - /* Do some sanity checks on the above options. */ - - if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI) - && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6) - { - warning ("fp software completion requires -mtrap-precision=i"); - alpha_tp = ALPHA_TP_INSN; - } - - if (TARGET_FLOAT_VAX) - { - if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN) - { - warning ("rounding mode not supported for VAX floats"); - alpha_fprm = ALPHA_FPRM_NORM; - } - if (alpha_fptm == ALPHA_FPTM_SUI) - { - warning ("trap mode not supported for VAX floats"); - alpha_fptm = ALPHA_FPTM_SU; - } - } - - { - char *end; - int lat; - - if (!alpha_mlat_string) - alpha_mlat_string = "L1"; - - if (ISDIGIT ((unsigned char)alpha_mlat_string[0]) - && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0')) - ; - else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l') - && ISDIGIT ((unsigned char)alpha_mlat_string[1]) - && alpha_mlat_string[2] == '\0') - { - static int const cache_latency[][4] = - { - { 3, 30, -1 }, /* ev4 -- Bcache is a guess */ - { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */ - { 3, 13, -1 }, /* ev6 -- Ho hum, doesn't exist yet */ - }; - - lat = alpha_mlat_string[1] - '0'; - if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1) - { - warning ("L%d cache latency unknown for %s", - lat, alpha_cpu_name[alpha_cpu]); - lat = 3; - } - else - lat = cache_latency[alpha_cpu][lat-1]; - } - else if (! strcmp (alpha_mlat_string, "main")) - { - /* Most current memories have about 370ns latency. This is - a reasonable guess for a fast cpu. */ - lat = 150; - } - else - { - warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string); - lat = 3; - } - - alpha_memory_latency = lat; - } - - /* Default the definition of "small data" to 8 bytes. */ - if (!g_switch_set) - g_switch_value = 8; - - /* Acquire a unique set number for our register saves and restores. */ - alpha_sr_alias_set = new_alias_set (); -} - -/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */ - -int -zap_mask (value) - HOST_WIDE_INT value; -{ - int i; - - for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; - i++, value >>= 8) - if ((value & 0xff) != 0 && (value & 0xff) != 0xff) - return 0; - - return 1; -} - -/* Returns 1 if OP is either the constant zero or a register. If a - register, it must be in the proper mode unless MODE is VOIDmode. */ - -int -reg_or_0_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return op == const0_rtx || register_operand (op, mode); -} - -/* Return 1 if OP is a constant in the range of 0-63 (for a shift) or - any register. */ - -int -reg_or_6bit_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return ((GET_CODE (op) == CONST_INT - && (unsigned HOST_WIDE_INT) INTVAL (op) < 64) - || register_operand (op, mode)); -} - - -/* Return 1 if OP is an 8-bit constant or any register. */ - -int -reg_or_8bit_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return ((GET_CODE (op) == CONST_INT - && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100) - || register_operand (op, mode)); -} - -/* Return 1 if OP is an 8-bit constant. */ - -int -cint8_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return ((GET_CODE (op) == CONST_INT - && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)); -} - -/* Return 1 if the operand is a valid second operand to an add insn. */ - -int -add_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == CONST_INT) - /* Constraints I, J, O and P are covered by K. */ - return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K') - || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')); - - return register_operand (op, mode); -} - -/* Return 1 if the operand is a valid second operand to a sign-extending - add insn. */ - -int -sext_add_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == CONST_INT) - return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I') - || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O')); - - return register_operand (op, mode); -} - -/* Return 1 if OP is the constant 4 or 8. */ - -int -const48_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (op) == CONST_INT - && (INTVAL (op) == 4 || INTVAL (op) == 8)); -} - -/* Return 1 if OP is a valid first operand to an AND insn. */ - -int -and_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode) - return (zap_mask (CONST_DOUBLE_LOW (op)) - && zap_mask (CONST_DOUBLE_HIGH (op))); - - if (GET_CODE (op) == CONST_INT) - return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100 - || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100 - || zap_mask (INTVAL (op))); - - return register_operand (op, mode); -} - -/* Return 1 if OP is a valid first operand to an IOR or XOR insn. */ - -int -or_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == CONST_INT) - return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100 - || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100); - - return register_operand (op, mode); -} - -/* Return 1 if OP is a constant that is the width, in bits, of an integral - mode smaller than DImode. */ - -int -mode_width_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (op) == CONST_INT - && (INTVAL (op) == 8 || INTVAL (op) == 16 - || INTVAL (op) == 32 || INTVAL (op) == 64)); -} - -/* Return 1 if OP is a constant that is the width of an integral machine mode - smaller than an integer. */ - -int -mode_mask_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ -#if HOST_BITS_PER_WIDE_INT == 32 - if (GET_CODE (op) == CONST_DOUBLE) - return (CONST_DOUBLE_LOW (op) == -1 - && (CONST_DOUBLE_HIGH (op) == -1 - || CONST_DOUBLE_HIGH (op) == 0)); -#else - if (GET_CODE (op) == CONST_DOUBLE) - return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0); -#endif - - return (GET_CODE (op) == CONST_INT - && (INTVAL (op) == 0xff - || INTVAL (op) == 0xffff - || INTVAL (op) == (HOST_WIDE_INT)0xffffffff -#if HOST_BITS_PER_WIDE_INT == 64 - || INTVAL (op) == -1 -#endif - )); -} - -/* Return 1 if OP is a multiple of 8 less than 64. */ - -int -mul8_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (op) == CONST_INT - && (unsigned HOST_WIDE_INT) INTVAL (op) < 64 - && (INTVAL (op) & 7) == 0); -} - -/* Return 1 if OP is the constant zero in floating-point. */ - -int -fp0_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (GET_MODE (op) == mode - && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode)); -} - -/* Return 1 if OP is the floating-point constant zero or a register. */ - -int -reg_or_fp0_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return fp0_operand (op, mode) || register_operand (op, mode); -} - -/* Return 1 if OP is a hard floating-point register. */ - -int -hard_fp_register_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS) - || (GET_CODE (op) == SUBREG - && hard_fp_register_operand (SUBREG_REG (op), mode))); -} - -/* Return 1 if OP is a register or a constant integer. */ - - -int -reg_or_cint_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (GET_CODE (op) == CONST_INT - || register_operand (op, mode)); -} - -/* Return 1 if OP is something that can be reloaded into a register; - if it is a MEM, it need not be valid. */ - -int -some_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op)) - return 0; - - switch (GET_CODE (op)) - { - case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF: - case SYMBOL_REF: case CONST: - return 1; - - case SUBREG: - return some_operand (SUBREG_REG (op), VOIDmode); - - default: - break; - } - - return 0; -} - -/* Return 1 if OP is a valid operand for the source of a move insn. */ - -int -input_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op)) - return 0; - - if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode) - return 0; - - switch (GET_CODE (op)) - { - case LABEL_REF: - case SYMBOL_REF: - case CONST: - /* This handles both the Windows/NT and OSF cases. */ - return mode == ptr_mode || mode == DImode; - - case REG: - return 1; - - case SUBREG: - if (register_operand (op, mode)) - return 1; - /* ... fall through ... */ - case MEM: - return ((TARGET_BWX || (mode != HImode && mode != QImode)) - && general_operand (op, mode)); - - case CONST_DOUBLE: - return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode); - - case CONST_INT: - return mode == QImode || mode == HImode || add_operand (op, mode); - - case CONSTANT_P_RTX: - return 1; - - default: - break; - } - - return 0; -} - -/* Return 1 if OP is a SYMBOL_REF for a function known to be in this - file. */ - -int -current_file_function_operand (op, mode) - rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (op) == SYMBOL_REF - && ! profile_flag && ! profile_block_flag - && (SYMBOL_REF_FLAG (op) - || op == XEXP (DECL_RTL (current_function_decl), 0))); -} - -/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */ - -int -call_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (mode != Pmode) - return 0; - - return (GET_CODE (op) == SYMBOL_REF - || (GET_CODE (op) == REG - && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27))); -} - -/* Return 1 if OP is a valid Alpha comparison operator. Here we know which - comparisons are valid in which insn. */ - -int -alpha_comparison_operator (op, mode) - register rtx op; - enum machine_mode mode; -{ - enum rtx_code code = GET_CODE (op); - - if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<') - return 0; - - return (code == EQ || code == LE || code == LT - || (mode == DImode && (code == LEU || code == LTU))); -} - -/* Return 1 if OP is a valid Alpha swapped comparison operator. */ - -int -alpha_swapped_comparison_operator (op, mode) - register rtx op; - enum machine_mode mode; -{ - enum rtx_code code = GET_CODE (op); - - if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<') - return 0; - - code = swap_condition (code); - return (code == EQ || code == LE || code == LT - || (mode == DImode && (code == LEU || code == LTU))); -} - -/* Return 1 if OP is a signed comparison operation. */ - -int -signed_comparison_operator (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - switch (GET_CODE (op)) - { - case EQ: case NE: case LE: case LT: case GE: case GT: - return 1; - - default: - break; - } - - return 0; -} - -/* Return 1 if this is a divide or modulus operator. */ - -int -divmod_operator (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - switch (GET_CODE (op)) - { - case DIV: case MOD: case UDIV: case UMOD: - return 1; - - default: - break; - } - - return 0; -} - -/* Return 1 if this memory address is a known aligned register plus - a constant. It must be a valid address. This means that we can do - this as an aligned reference plus some offset. - - Take into account what reload will do. */ - -int -aligned_memory_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - rtx base; - - if (reload_in_progress) - { - rtx tmp = op; - if (GET_CODE (tmp) == SUBREG) - tmp = SUBREG_REG (tmp); - if (GET_CODE (tmp) == REG - && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) - { - op = reg_equiv_memory_loc[REGNO (tmp)]; - if (op == 0) - return 0; - } - } - - if (GET_CODE (op) != MEM - || GET_MODE (op) != mode) - return 0; - op = XEXP (op, 0); - - /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo) - sorts of constructs. Dig for the real base register. */ - if (reload_in_progress - && GET_CODE (op) == PLUS - && GET_CODE (XEXP (op, 0)) == PLUS) - base = XEXP (XEXP (op, 0), 0); - else - { - if (! memory_address_p (mode, op)) - return 0; - base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op); - } - - return (GET_CODE (base) == REG - && REGNO_POINTER_ALIGN (REGNO (base)) >= 4); -} - -/* Similar, but return 1 if OP is a MEM which is not alignable. */ - -int -unaligned_memory_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - rtx base; - - if (reload_in_progress) - { - rtx tmp = op; - if (GET_CODE (tmp) == SUBREG) - tmp = SUBREG_REG (tmp); - if (GET_CODE (tmp) == REG - && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) - { - op = reg_equiv_memory_loc[REGNO (tmp)]; - if (op == 0) - return 0; - } - } - - if (GET_CODE (op) != MEM - || GET_MODE (op) != mode) - return 0; - op = XEXP (op, 0); - - /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo) - sorts of constructs. Dig for the real base register. */ - if (reload_in_progress - && GET_CODE (op) == PLUS - && GET_CODE (XEXP (op, 0)) == PLUS) - base = XEXP (XEXP (op, 0), 0); - else - { - if (! memory_address_p (mode, op)) - return 0; - base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op); - } - - return (GET_CODE (base) == REG - && REGNO_POINTER_ALIGN (REGNO (base)) < 4); -} - -/* Return 1 if OP is either a register or an unaligned memory location. */ - -int -reg_or_unaligned_mem_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - return register_operand (op, mode) || unaligned_memory_operand (op, mode); -} - -/* Return 1 if OP is any memory location. During reload a pseudo matches. */ - -int -any_memory_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (op) == MEM - || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG) - || (reload_in_progress && GET_CODE (op) == REG - && REGNO (op) >= FIRST_PSEUDO_REGISTER) - || (reload_in_progress && GET_CODE (op) == SUBREG - && GET_CODE (SUBREG_REG (op)) == REG - && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)); -} - -/* Returns 1 if OP is not an eliminable register. - - This exists to cure a pathological abort in the s8addq (et al) patterns, - - long foo () { long t; bar(); return (long) &t * 26107; } - - which run afoul of a hack in reload to cure a (presumably) similar - problem with lea-type instructions on other targets. But there is - one of us and many of them, so work around the problem by selectively - preventing combine from making the optimization. */ - -int -reg_not_elim_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - rtx inner = op; - if (GET_CODE (op) == SUBREG) - inner = SUBREG_REG (op); - if (inner == frame_pointer_rtx || inner == arg_pointer_rtx) - return 0; - - return register_operand (op, mode); -} - -/* Return 1 is OP is a memory location that is not a reference (using - an AND) to an unaligned location. Take into account what reload - will do. */ - -int -normal_memory_operand (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - if (reload_in_progress) - { - rtx tmp = op; - if (GET_CODE (tmp) == SUBREG) - tmp = SUBREG_REG (tmp); - if (GET_CODE (tmp) == REG - && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) - { - op = reg_equiv_memory_loc[REGNO (tmp)]; - - /* This may not have been assigned an equivalent address if it will - be eliminated. In that case, it doesn't matter what we do. */ - if (op == 0) - return 1; - } - } - - return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND; -} - -/* Accept a register, but not a subreg of any kind. This allows us to - avoid pathological cases in reload wrt data movement common in - int->fp conversion. */ - -int -reg_no_subreg_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == SUBREG) - return 0; - return register_operand (op, mode); -} - -/* Return 1 if this function can directly return via $26. */ - -int -direct_return () -{ - return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0 - && get_frame_size () == 0 - && current_function_outgoing_args_size == 0 - && current_function_pretend_args_size == 0); -} - -/* REF is an alignable memory location. Place an aligned SImode - reference into *PALIGNED_MEM and the number of bits to shift into - *PBITNUM. SCRATCH is a free register for use in reloading out - of range stack slots. */ - -void -get_aligned_mem (ref, paligned_mem, pbitnum) - rtx ref; - rtx *paligned_mem, *pbitnum; -{ - rtx base; - HOST_WIDE_INT offset = 0; - - if (GET_CODE (ref) != MEM) - abort (); - - if (reload_in_progress - && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0))) - { - base = find_replacement (&XEXP (ref, 0)); - - if (! memory_address_p (GET_MODE (ref), base)) - abort (); - } - else - { - base = XEXP (ref, 0); - } - - if (GET_CODE (base) == PLUS) - offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0); - - *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3)); - MEM_COPY_ATTRIBUTES (*paligned_mem, ref); - RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref); - - /* Sadly, we cannot use alias sets here because we may overlap other - data in a different alias set. */ - /* MEM_ALIAS_SET (*paligned_mem) = MEM_ALIAS_SET (ref); */ - - *pbitnum = GEN_INT ((offset & 3) * 8); -} - -/* Similar, but just get the address. Handle the two reload cases. - Add EXTRA_OFFSET to the address we return. */ - -rtx -get_unaligned_address (ref, extra_offset) - rtx ref; - int extra_offset; -{ - rtx base; - HOST_WIDE_INT offset = 0; - - if (GET_CODE (ref) != MEM) - abort (); - - if (reload_in_progress - && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0))) - { - base = find_replacement (&XEXP (ref, 0)); - - if (! memory_address_p (GET_MODE (ref), base)) - abort (); - } - else - { - base = XEXP (ref, 0); - } - - if (GET_CODE (base) == PLUS) - offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0); - - return plus_constant (base, offset + extra_offset); -} - -/* Subfunction of the following function. Update the flags of any MEM - found in part of X. */ - -static void -alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p) - rtx x; - int in_struct_p, volatile_p, unchanging_p; -{ - int i; - - switch (GET_CODE (x)) - { - case SEQUENCE: - case PARALLEL: - for (i = XVECLEN (x, 0) - 1; i >= 0; i--) - alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p, - unchanging_p); - break; - - case INSN: - alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p, - unchanging_p); - break; - - case SET: - alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p, - unchanging_p); - alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p, - unchanging_p); - break; - - case MEM: - MEM_IN_STRUCT_P (x) = in_struct_p; - MEM_VOLATILE_P (x) = volatile_p; - RTX_UNCHANGING_P (x) = unchanging_p; - /* Sadly, we cannot use alias sets because the extra aliasing - produced by the AND interferes. Given that two-byte quantities - are the only thing we would be able to differentiate anyway, - there does not seem to be any point in convoluting the early - out of the alias check. */ - /* MEM_ALIAS_SET (x) = alias_set; */ - break; - - default: - break; - } -} - -/* Given INSN, which is either an INSN or a SEQUENCE generated to - perform a memory operation, look for any MEMs in either a SET_DEST or - a SET_SRC and copy the in-struct, unchanging, and volatile flags from - REF into each of the MEMs found. If REF is not a MEM, don't do - anything. */ - -void -alpha_set_memflags (insn, ref) - rtx insn; - rtx ref; -{ - int in_struct_p, volatile_p, unchanging_p; - - if (GET_CODE (ref) != MEM) - return; - - in_struct_p = MEM_IN_STRUCT_P (ref); - volatile_p = MEM_VOLATILE_P (ref); - unchanging_p = RTX_UNCHANGING_P (ref); - - /* This is only called from alpha.md, after having had something - generated from one of the insn patterns. So if everything is - zero, the pattern is already up-to-date. */ - if (! in_struct_p && ! volatile_p && ! unchanging_p) - return; - - alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p); -} - -/* 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. */ - -rtx -alpha_emit_set_const (target, mode, c, n) - rtx target; - enum machine_mode mode; - HOST_WIDE_INT c; - int n; -{ - rtx pat; - int i; - - /* Try 1 insn, then 2, then up to N. */ - for (i = 1; i <= n; i++) - if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0) - return pat; - - return 0; -} - -/* Internal routine for the above to check for N or below insns. */ - -static rtx -alpha_emit_set_const_1 (target, mode, c, n) - rtx target; - enum machine_mode mode; - HOST_WIDE_INT c; - int n; -{ - HOST_WIDE_INT new = c; - int i, bits; - /* Use a pseudo if highly optimizing and still generating RTL. */ - rtx subtarget - = (flag_expensive_optimizations && rtx_equal_function_value_matters - ? 0 : target); - rtx temp; - -#if HOST_BITS_PER_WIDE_INT == 64 - /* We are only called for SImode and DImode. If this is SImode, ensure that - we are sign extended to a full word. This does not make any sense when - cross-compiling on a narrow machine. */ - - if (mode == SImode) - c = (c & 0xffffffff) - 2 * (c & 0x80000000); -#endif - - /* If this is a sign-extended 32-bit constant, we can do this in at most - three insns, so do it if we have enough insns left. We always have - a sign-extended 32-bit constant when compiling on a narrow machine. */ - - if (HOST_BITS_PER_WIDE_INT != 64 - || c >> 31 == -1 || c >> 31 == 0) - { - HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000); - HOST_WIDE_INT tmp1 = c - low; - HOST_WIDE_INT high - = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000); - HOST_WIDE_INT extra = 0; - - /* If HIGH will be interpreted as negative but the constant is - positive, we must adjust it to do two ldha insns. */ - - if ((high & 0x8000) != 0 && c >= 0) - { - extra = 0x4000; - tmp1 -= 0x40000000; - high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000); - } - - if (c == low || (low == 0 && extra == 0)) - { - /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode) - but that meant that we can't handle INT_MIN on 32-bit machines - (like NT/Alpha), because we recurse indefinitely through - emit_move_insn to gen_movdi. So instead, since we know exactly - what we want, create it explicitly. */ - - if (target == NULL) - target = gen_reg_rtx (mode); - emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c))); - return target; - } - else if (n >= 2 + (extra != 0)) - { - temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode); - - if (extra != 0) - temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16), - subtarget, 0, OPTAB_WIDEN); - - return expand_binop (mode, add_optab, temp, GEN_INT (high << 16), - target, 0, OPTAB_WIDEN); - } - } - - /* If we couldn't do it that way, try some other methods. But if we have - no instructions left, don't bother. Likewise, if this is SImode and - we can't make pseudos, we can't do anything since the expand_binop - and expand_unop calls will widen and try to make pseudos. */ - - if (n == 1 - || (mode == SImode && ! rtx_equal_function_value_matters)) - return 0; - -#if HOST_BITS_PER_WIDE_INT == 64 - /* First, see if can load a value into the target that is the same as the - constant except that all bytes that are 0 are changed to be 0xff. If we - can, then we can do a ZAPNOT to obtain the desired constant. */ - - for (i = 0; i < 64; i += 8) - if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0) - new |= (HOST_WIDE_INT) 0xff << i; - - /* We are only called for SImode and DImode. If this is SImode, ensure that - we are sign extended to a full word. */ - - if (mode == SImode) - new = (new & 0xffffffff) - 2 * (new & 0x80000000); - - if (new != c - && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0) - return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new), - target, 0, OPTAB_WIDEN); -#endif - - /* Next, see if we can load a related constant and then shift and possibly - negate it to get the constant we want. Try this once each increasing - numbers of insns. */ - - for (i = 1; i < n; i++) - { - /* First try complementing. */ - if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0) - return expand_unop (mode, one_cmpl_optab, temp, target, 0); - - /* Next try to form a constant and do a left shift. We can do this - if some low-order bits are zero; the exact_log2 call below tells - us that information. The bits we are shifting out could be any - value, but here we'll just try the 0- and sign-extended forms of - the constant. To try to increase the chance of having the same - constant in more than one insn, start at the highest number of - bits to shift, but try all possibilities in case a ZAPNOT will - be useful. */ - - if ((bits = exact_log2 (c & - c)) > 0) - for (; bits > 0; bits--) - if ((temp = (alpha_emit_set_const - (subtarget, mode, - (unsigned HOST_WIDE_INT) (c >> bits), i))) != 0 - || ((temp = (alpha_emit_set_const - (subtarget, mode, - ((unsigned HOST_WIDE_INT) c) >> bits, i))) - != 0)) - return expand_binop (mode, ashl_optab, temp, GEN_INT (bits), - target, 0, OPTAB_WIDEN); - - /* Now try high-order zero bits. Here we try the shifted-in bits as - all zero and all ones. Be careful to avoid shifting outside the - mode and to avoid shifting outside the host wide int size. */ - /* On narrow hosts, don't shift a 1 into the high bit, since we'll - confuse the recursive call and set all of the high 32 bits. */ - - if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8) - - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0) - for (; bits > 0; bits--) - if ((temp = alpha_emit_set_const (subtarget, mode, - c << bits, i)) != 0 - || ((temp = (alpha_emit_set_const - (subtarget, mode, - ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)), - i))) - != 0)) - return expand_binop (mode, lshr_optab, temp, GEN_INT (bits), - target, 1, OPTAB_WIDEN); - - /* Now try high-order 1 bits. We get that with a sign-extension. - But one bit isn't enough here. Be careful to avoid shifting outside - the mode and to avoid shifting outside the host wide int size. */ - - if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8) - - floor_log2 (~ c) - 2)) > 0) - for (; bits > 0; bits--) - if ((temp = alpha_emit_set_const (subtarget, mode, - c << bits, i)) != 0 - || ((temp = (alpha_emit_set_const - (subtarget, mode, - ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)), - i))) - != 0)) - return expand_binop (mode, ashr_optab, temp, GEN_INT (bits), - target, 0, OPTAB_WIDEN); - } - - return 0; -} - -/* Having failed to find a 3 insn sequence in alpha_emit_set_const, - fall back to a straight forward decomposition. We do this to avoid - exponential run times encountered when looking for longer sequences - with alpha_emit_set_const. */ - -rtx -alpha_emit_set_long_const (target, c1, c2) - rtx target; - HOST_WIDE_INT c1, c2; -{ - HOST_WIDE_INT d1, d2, d3, d4; - - /* Decompose the entire word */ -#if HOST_BITS_PER_WIDE_INT >= 64 - if (c2 != -(c1 < 0)) - abort (); - d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000; - c1 -= d1; - d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000; - c1 = (c1 - d2) >> 32; - d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000; - c1 -= d3; - d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000; - if (c1 != d4) - abort (); -#else - d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000; - c1 -= d1; - d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000; - if (c1 != d2) - abort (); - c2 += (d2 < 0); - d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000; - c2 -= d3; - d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000; - if (c2 != d4) - abort (); -#endif - - /* Construct the high word */ - if (d4) - { - emit_move_insn (target, GEN_INT (d4)); - if (d3) - emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3))); - } - else - emit_move_insn (target, GEN_INT (d3)); - - /* Shift it into place */ - emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32))); - - /* Add in the low bits. */ - if (d2) - emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2))); - if (d1) - emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1))); - - return target; -} - -/* Generate the comparison for a conditional branch. */ - -rtx -alpha_emit_conditional_branch (code) - enum rtx_code code; -{ - enum rtx_code cmp_code, branch_code; - enum machine_mode cmp_mode, branch_mode = VOIDmode; - rtx op0 = alpha_compare_op0, op1 = alpha_compare_op1; - rtx tem; - - /* The general case: fold the comparison code to the types of compares - that we have, choosing the branch as necessary. */ - switch (code) - { - case EQ: case LE: case LT: case LEU: case LTU: - /* We have these compares: */ - cmp_code = code, branch_code = NE; - break; - - case NE: - /* This must be reversed. */ - cmp_code = EQ, branch_code = EQ; - break; - - case GE: case GT: case GEU: case GTU: - /* For FP, we swap them, for INT, we reverse them. */ - if (alpha_compare_fp_p) - { - cmp_code = swap_condition (code); - branch_code = NE; - tem = op0, op0 = op1, op1 = tem; - } - else - { - cmp_code = reverse_condition (code); - branch_code = EQ; - } - break; - - default: - abort (); - } - - if (alpha_compare_fp_p) - { - cmp_mode = DFmode; - if (flag_fast_math) - { - /* When we are not as concerned about non-finite values, and we - are comparing against zero, we can branch directly. */ - if (op1 == CONST0_RTX (DFmode)) - cmp_code = NIL, branch_code = code; - else if (op0 == CONST0_RTX (DFmode)) - { - /* Undo the swap we probably did just above. */ - tem = op0, op0 = op1, op1 = tem; - branch_code = swap_condition (cmp_code); - cmp_code = NIL; - } - } - else - { - /* ??? We mark the the branch mode to be CCmode to prevent the - compare and branch from being combined, since the compare - insn follows IEEE rules that the branch does not. */ - branch_mode = CCmode; - } - } - else - { - cmp_mode = DImode; - - /* The following optimizations are only for signed compares. */ - if (code != LEU && code != LTU && code != GEU && code != GTU) - { - /* Whee. Compare and branch against 0 directly. */ - if (op1 == const0_rtx) - cmp_code = NIL, branch_code = code; - - /* We want to use cmpcc/bcc when we can, since there is a zero delay - bypass between logicals and br/cmov on EV5. But we don't want to - force valid immediate constants into registers needlessly. */ - else if (GET_CODE (op1) == CONST_INT) - { - HOST_WIDE_INT v = INTVAL (op1), n = -v; - - if (! CONST_OK_FOR_LETTER_P (v, 'I') - && (CONST_OK_FOR_LETTER_P (n, 'K') - || CONST_OK_FOR_LETTER_P (n, 'L'))) - { - cmp_code = PLUS, branch_code = code; - op1 = GEN_INT (n); - } - } - } - } - - /* Force op0 into a register. */ - if (GET_CODE (op0) != REG) - op0 = force_reg (cmp_mode, op0); - - /* Emit an initial compare instruction, if necessary. */ - tem = op0; - if (cmp_code != NIL) - { - tem = gen_reg_rtx (cmp_mode); - emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1)); - } - - /* Return the branch comparison. */ - return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode)); -} - - -/* Rewrite a comparison against zero CMP of the form - (CODE (cc0) (const_int 0)) so it can be written validly in - a conditional move (if_then_else CMP ...). - If both of the operands that set cc0 are non-zero we must emit - an insn to perform the compare (it can't be done within - the conditional move). */ -rtx -alpha_emit_conditional_move (cmp, mode) - rtx cmp; - enum machine_mode mode; -{ - enum rtx_code code = GET_CODE (cmp); - enum rtx_code cmov_code = NE; - rtx op0 = alpha_compare_op0; - rtx op1 = alpha_compare_op1; - enum machine_mode cmp_mode - = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0)); - enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode; - enum machine_mode cmov_mode = VOIDmode; - rtx tem; - - if (alpha_compare_fp_p != FLOAT_MODE_P (mode)) - return 0; - - /* We may be able to use a conditional move directly. - This avoids emitting spurious compares. */ - if (signed_comparison_operator (cmp, cmp_op_mode) - && (!alpha_compare_fp_p || flag_fast_math) - && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode))) - return gen_rtx_fmt_ee (code, VOIDmode, op0, op1); - - /* We can't put the comparison insides a conditional move; - emit a compare instruction and put that inside the - conditional move. Make sure we emit only comparisons we have; - swap or reverse as necessary. */ - - switch (code) - { - case EQ: case LE: case LT: case LEU: case LTU: - /* We have these compares: */ - break; - - case NE: - /* This must be reversed. */ - code = reverse_condition (code); - cmov_code = EQ; - break; - - case GE: case GT: case GEU: case GTU: - /* These must be swapped. Make sure the new first operand is in - a register. */ - code = swap_condition (code); - tem = op0, op0 = op1, op1 = tem; - op0 = force_reg (cmp_mode, op0); - break; - - default: - abort (); - } - - /* ??? We mark the branch mode to be CCmode to prevent the compare - and cmov from being combined, since the compare insn follows IEEE - rules that the cmov does not. */ - if (alpha_compare_fp_p && !flag_fast_math) - cmov_mode = CCmode; - - tem = gen_reg_rtx (cmp_op_mode); - emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1)); - return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode)); -} - -/* Use ext[wlq][lh] as the Architecture Handbook describes for extracting - unaligned data: - - unsigned: signed: - word: ldq_u r1,X(r11) ldq_u r1,X(r11) - ldq_u r2,X+1(r11) ldq_u r2,X+1(r11) - lda r3,X(r11) lda r3,X+2(r11) - extwl r1,r3,r1 extql r1,r3,r1 - extwh r2,r3,r2 extqh r2,r3,r2 - or r1.r2.r1 or r1,r2,r1 - sra r1,48,r1 - - long: ldq_u r1,X(r11) ldq_u r1,X(r11) - ldq_u r2,X+3(r11) ldq_u r2,X+3(r11) - lda r3,X(r11) lda r3,X(r11) - extll r1,r3,r1 extll r1,r3,r1 - extlh r2,r3,r2 extlh r2,r3,r2 - or r1.r2.r1 addl r1,r2,r1 - - quad: ldq_u r1,X(r11) - ldq_u r2,X+7(r11) - lda r3,X(r11) - extql r1,r3,r1 - extqh r2,r3,r2 - or r1.r2.r1 -*/ - -void -alpha_expand_unaligned_load (tgt, mem, size, ofs, sign) - rtx tgt, mem; - HOST_WIDE_INT size, ofs; - int sign; -{ - rtx meml, memh, addr, extl, exth; - enum machine_mode mode; - - meml = gen_reg_rtx (DImode); - memh = gen_reg_rtx (DImode); - addr = gen_reg_rtx (DImode); - extl = gen_reg_rtx (DImode); - exth = gen_reg_rtx (DImode); - - emit_move_insn (meml, - change_address (mem, DImode, - gen_rtx_AND (DImode, - plus_constant (XEXP (mem, 0), - ofs), - GEN_INT (-8)))); - - emit_move_insn (memh, - change_address (mem, DImode, - gen_rtx_AND (DImode, - plus_constant (XEXP (mem, 0), - ofs + size - 1), - GEN_INT (-8)))); - - if (sign && size == 2) - { - emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2)); - - emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr)); - emit_insn (gen_extqh (exth, memh, addr)); - - /* We must use tgt here for the target. Alpha-vms port fails if we use - addr for the target, because addr is marked as a pointer and combine - knows that pointers are always sign-extended 32 bit values. */ - addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN); - addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48), - addr, 1, OPTAB_WIDEN); - } - else - { - emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs)); - emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr)); - switch (size) - { - case 2: - emit_insn (gen_extwh (exth, memh, addr)); - mode = HImode; - break; - - case 4: - emit_insn (gen_extlh (exth, memh, addr)); - mode = SImode; - break; - - case 8: - emit_insn (gen_extqh (exth, memh, addr)); - mode = DImode; - break; - default: - abort(); - } - - addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl), - gen_lowpart (mode, exth), gen_lowpart (mode, tgt), - sign, OPTAB_WIDEN); - } - - if (addr != tgt) - emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr)); -} - -/* Similarly, use ins and msk instructions to perform unaligned stores. */ - -void -alpha_expand_unaligned_store (dst, src, size, ofs) - rtx dst, src; - HOST_WIDE_INT size, ofs; -{ - rtx dstl, dsth, addr, insl, insh, meml, memh; - - dstl = gen_reg_rtx (DImode); - dsth = gen_reg_rtx (DImode); - insl = gen_reg_rtx (DImode); - insh = gen_reg_rtx (DImode); - - meml = change_address (dst, DImode, - gen_rtx_AND (DImode, - plus_constant (XEXP (dst, 0), ofs), - GEN_INT (-8))); - memh = change_address (dst, DImode, - gen_rtx_AND (DImode, - plus_constant (XEXP (dst, 0), - ofs+size-1), - GEN_INT (-8))); - - emit_move_insn (dsth, memh); - emit_move_insn (dstl, meml); - addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs)); - - if (src != const0_rtx) - { - emit_insn (gen_insxh (insh, gen_lowpart (DImode, src), - GEN_INT (size*8), addr)); - - switch (size) - { - case 2: - emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr)); - break; - case 4: - emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr)); - break; - case 8: - emit_insn (gen_insql (insl, src, addr)); - break; - } - } - - emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr)); - - switch (size) - { - case 2: - emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr)); - break; - case 4: - emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr)); - break; - case 8: - { -#if HOST_BITS_PER_WIDE_INT == 32 - rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode); -#else - rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode); -#endif - emit_insn (gen_mskxl (dstl, dstl, msk, addr)); - } - break; - } - - if (src != const0_rtx) - { - dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN); - dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN); - } - - /* Must store high before low for degenerate case of aligned. */ - emit_move_insn (memh, dsth); - emit_move_insn (meml, dstl); -} - -/* The block move code tries to maximize speed by separating loads and - stores at the expense of register pressure: we load all of the data - before we store it back out. There are two secondary effects worth - mentioning, that this speeds copying to/from aligned and unaligned - buffers, and that it makes the code significantly easier to write. */ - -#define MAX_MOVE_WORDS 8 - -/* Load an integral number of consecutive unaligned quadwords. */ - -static void -alpha_expand_unaligned_load_words (out_regs, smem, words, ofs) - rtx *out_regs; - rtx smem; - HOST_WIDE_INT words, ofs; -{ - rtx const im8 = GEN_INT (-8); - rtx const i64 = GEN_INT (64); - rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1]; - rtx sreg, areg; - HOST_WIDE_INT i; - - /* Generate all the tmp registers we need. */ - for (i = 0; i < words; ++i) - { - data_regs[i] = out_regs[i]; - ext_tmps[i] = gen_reg_rtx (DImode); - } - data_regs[words] = gen_reg_rtx (DImode); - - if (ofs != 0) - smem = change_address (smem, GET_MODE (smem), - plus_constant (XEXP (smem, 0), ofs)); - - /* Load up all of the source data. */ - for (i = 0; i < words; ++i) - { - emit_move_insn (data_regs[i], - change_address (smem, DImode, - gen_rtx_AND (DImode, - plus_constant (XEXP(smem,0), - 8*i), - im8))); - } - emit_move_insn (data_regs[words], - change_address (smem, DImode, - gen_rtx_AND (DImode, - plus_constant (XEXP(smem,0), - 8*words - 1), - im8))); - - /* Extract the half-word fragments. Unfortunately DEC decided to make - extxh with offset zero a noop instead of zeroing the register, so - we must take care of that edge condition ourselves with cmov. */ - - sreg = copy_addr_to_reg (XEXP (smem, 0)); - areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL, - 1, OPTAB_WIDEN); - for (i = 0; i < words; ++i) - { - emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg)); - - emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg)); - emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i], - gen_rtx_IF_THEN_ELSE (DImode, - gen_rtx_EQ (DImode, areg, - const0_rtx), - const0_rtx, ext_tmps[i]))); - } - - /* Merge the half-words into whole words. */ - for (i = 0; i < words; ++i) - { - out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i], - ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN); - } -} - -/* Store an integral number of consecutive unaligned quadwords. DATA_REGS - may be NULL to store zeros. */ - -static void -alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs) - rtx *data_regs; - rtx dmem; - HOST_WIDE_INT words, ofs; -{ - rtx const im8 = GEN_INT (-8); - rtx const i64 = GEN_INT (64); -#if HOST_BITS_PER_WIDE_INT == 32 - rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode); -#else - rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode); -#endif - rtx ins_tmps[MAX_MOVE_WORDS]; - rtx st_tmp_1, st_tmp_2, dreg; - rtx st_addr_1, st_addr_2; - HOST_WIDE_INT i; - - /* Generate all the tmp registers we need. */ - if (data_regs != NULL) - for (i = 0; i < words; ++i) - ins_tmps[i] = gen_reg_rtx(DImode); - st_tmp_1 = gen_reg_rtx(DImode); - st_tmp_2 = gen_reg_rtx(DImode); - - if (ofs != 0) - dmem = change_address (dmem, GET_MODE (dmem), - plus_constant (XEXP (dmem, 0), ofs)); - - - st_addr_2 = change_address (dmem, DImode, - gen_rtx_AND (DImode, - plus_constant (XEXP(dmem,0), - words*8 - 1), - im8)); - st_addr_1 = change_address (dmem, DImode, - gen_rtx_AND (DImode, - XEXP (dmem, 0), - im8)); - - /* Load up the destination end bits. */ - emit_move_insn (st_tmp_2, st_addr_2); - emit_move_insn (st_tmp_1, st_addr_1); - - /* Shift the input data into place. */ - dreg = copy_addr_to_reg (XEXP (dmem, 0)); - if (data_regs != NULL) - { - for (i = words-1; i >= 0; --i) - { - emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg)); - emit_insn (gen_insql (data_regs[i], data_regs[i], dreg)); - } - for (i = words-1; i > 0; --i) - { - ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i], - ins_tmps[i-1], ins_tmps[i-1], 1, - OPTAB_WIDEN); - } - } - - /* Split and merge the ends with the destination data. */ - emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg)); - emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg)); - - if (data_regs != NULL) - { - st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1], - st_tmp_2, 1, OPTAB_WIDEN); - st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0], - st_tmp_1, 1, OPTAB_WIDEN); - } - - /* Store it all. */ - emit_move_insn (st_addr_2, st_tmp_2); - for (i = words-1; i > 0; --i) - { - emit_move_insn (change_address (dmem, DImode, - gen_rtx_AND (DImode, - plus_constant(XEXP (dmem,0), - i*8), - im8)), - data_regs ? ins_tmps[i-1] : const0_rtx); - } - emit_move_insn (st_addr_1, st_tmp_1); -} - - -/* Expand string/block move operations. - - operands[0] is the pointer to the destination. - operands[1] is the pointer to the source. - operands[2] is the number of bytes to move. - operands[3] is the alignment. */ - -int -alpha_expand_block_move (operands) - rtx operands[]; -{ - rtx bytes_rtx = operands[2]; - rtx align_rtx = operands[3]; - HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx); - HOST_WIDE_INT bytes = orig_bytes; - HOST_WIDE_INT src_align = INTVAL (align_rtx); - HOST_WIDE_INT dst_align = src_align; - rtx orig_src = operands[1]; - rtx orig_dst = operands[0]; - rtx data_regs[2*MAX_MOVE_WORDS+16]; - rtx tmp; - int i, words, ofs, nregs = 0; - - if (bytes <= 0) - return 1; - if (bytes > MAX_MOVE_WORDS*8) - return 0; - - /* Look for additional alignment information from recorded register info. */ - - tmp = XEXP (orig_src, 0); - if (GET_CODE (tmp) == REG) - { - if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align) - src_align = REGNO_POINTER_ALIGN (REGNO (tmp)); - } - else if (GET_CODE (tmp) == PLUS - && GET_CODE (XEXP (tmp, 0)) == REG - && GET_CODE (XEXP (tmp, 1)) == CONST_INT) - { - HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1)); - int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0))); - - if (a > src_align) - { - if (a >= 8 && c % 8 == 0) - src_align = 8; - else if (a >= 4 && c % 4 == 0) - src_align = 4; - else if (a >= 2 && c % 2 == 0) - src_align = 2; - } - } - - tmp = XEXP (orig_dst, 0); - if (GET_CODE (tmp) == REG) - { - if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align) - dst_align = REGNO_POINTER_ALIGN (REGNO (tmp)); - } - else if (GET_CODE (tmp) == PLUS - && GET_CODE (XEXP (tmp, 0)) == REG - && GET_CODE (XEXP (tmp, 1)) == CONST_INT) - { - HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1)); - int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0))); - - if (a > dst_align) - { - if (a >= 8 && c % 8 == 0) - dst_align = 8; - else if (a >= 4 && c % 4 == 0) - dst_align = 4; - else if (a >= 2 && c % 2 == 0) - dst_align = 2; - } - } - - /* - * Load the entire block into registers. - */ - - if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF) - { - enum machine_mode mode; - tmp = XEXP (XEXP (orig_src, 0), 0); - - /* Don't use the existing register if we're reading more than - is held in the register. Nor if there is not a mode that - handles the exact size. */ - mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1); - if (mode != BLKmode - && GET_MODE_SIZE (GET_MODE (tmp)) >= bytes) - { - if (mode == TImode) - { - data_regs[nregs] = gen_lowpart (DImode, tmp); - data_regs[nregs+1] = gen_highpart (DImode, tmp); - nregs += 2; - } - else - data_regs[nregs++] = gen_lowpart (mode, tmp); - goto src_done; - } - - /* No appropriate mode; fall back on memory. */ - orig_src = change_address (orig_src, GET_MODE (orig_src), - copy_addr_to_reg (XEXP (orig_src, 0))); - } - - ofs = 0; - if (src_align >= 8 && bytes >= 8) - { - words = bytes / 8; - - for (i = 0; i < words; ++i) - data_regs[nregs+i] = gen_reg_rtx(DImode); - - for (i = 0; i < words; ++i) - { - emit_move_insn (data_regs[nregs+i], - change_address (orig_src, DImode, - plus_constant (XEXP (orig_src, 0), - ofs + i*8))); - } - - nregs += words; - bytes -= words * 8; - ofs += words * 8; - } - if (src_align >= 4 && bytes >= 4) - { - words = bytes / 4; - - for (i = 0; i < words; ++i) - data_regs[nregs+i] = gen_reg_rtx(SImode); - - for (i = 0; i < words; ++i) - { - emit_move_insn (data_regs[nregs+i], - change_address (orig_src, SImode, - plus_constant (XEXP (orig_src, 0), - ofs + i*4))); - } - - nregs += words; - bytes -= words * 4; - ofs += words * 4; - } - if (bytes >= 16) - { - words = bytes / 8; - - for (i = 0; i < words+1; ++i) - data_regs[nregs+i] = gen_reg_rtx(DImode); - - alpha_expand_unaligned_load_words (data_regs + nregs, orig_src, - words, ofs); - - nregs += words; - bytes -= words * 8; - ofs += words * 8; - } - if (!TARGET_BWX && bytes >= 8) - { - data_regs[nregs++] = tmp = gen_reg_rtx (DImode); - alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0); - bytes -= 8; - ofs += 8; - } - if (!TARGET_BWX && bytes >= 4) - { - data_regs[nregs++] = tmp = gen_reg_rtx (SImode); - alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0); - bytes -= 4; - ofs += 4; - } - if (bytes >= 2) - { - if (src_align >= 2) - { - do { - data_regs[nregs++] = tmp = gen_reg_rtx (HImode); - emit_move_insn (tmp, - change_address (orig_src, HImode, - plus_constant (XEXP (orig_src, 0), - ofs))); - bytes -= 2; - ofs += 2; - } while (bytes >= 2); - } - else if (!TARGET_BWX) - { - data_regs[nregs++] = tmp = gen_reg_rtx (HImode); - alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0); - bytes -= 2; - ofs += 2; - } - } - while (bytes > 0) - { - data_regs[nregs++] = tmp = gen_reg_rtx (QImode); - emit_move_insn (tmp, - change_address (orig_src, QImode, - plus_constant (XEXP (orig_src, 0), - ofs))); - bytes -= 1; - ofs += 1; - } - src_done: - - if (nregs > (int)(sizeof(data_regs)/sizeof(*data_regs))) - abort(); - - /* - * Now save it back out again. - */ - - i = 0, ofs = 0; - - if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF) - { - enum machine_mode mode; - tmp = XEXP (XEXP (orig_dst, 0), 0); - - mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1); - if (GET_MODE (tmp) == mode) - { - if (nregs == 1) - { - emit_move_insn (tmp, data_regs[0]); - i = 1; - goto dst_done; - } - else if (nregs == 2 && mode == TImode) - { - /* Undo the subregging done above when copying between - two TImode registers. */ - if (GET_CODE (data_regs[0]) == SUBREG - && GET_MODE (SUBREG_REG (data_regs[0])) == TImode) - { - emit_move_insn (tmp, SUBREG_REG (data_regs[0])); - } - else - { - rtx seq; - - start_sequence (); - emit_move_insn (gen_lowpart (DImode, tmp), data_regs[0]); - emit_move_insn (gen_highpart (DImode, tmp), data_regs[1]); - seq = get_insns (); - end_sequence (); - - emit_no_conflict_block (seq, tmp, data_regs[0], - data_regs[1], NULL_RTX); - } - - i = 2; - goto dst_done; - } - } - - /* ??? If nregs > 1, consider reconstructing the word in regs. */ - /* ??? Optimize mode < dst_mode with strict_low_part. */ - - /* No appropriate mode; fall back on memory. We can speed things - up by recognizing extra alignment information. */ - orig_dst = change_address (orig_dst, GET_MODE (orig_dst), - copy_addr_to_reg (XEXP (orig_dst, 0))); - dst_align = GET_MODE_SIZE (GET_MODE (tmp)); - } - - /* Write out the data in whatever chunks reading the source allowed. */ - if (dst_align >= 8) - { - while (i < nregs && GET_MODE (data_regs[i]) == DImode) - { - emit_move_insn (change_address (orig_dst, DImode, - plus_constant (XEXP (orig_dst, 0), - ofs)), - data_regs[i]); - ofs += 8; - i++; - } - } - if (dst_align >= 4) - { - /* If the source has remaining DImode regs, write them out in - two pieces. */ - while (i < nregs && GET_MODE (data_regs[i]) == DImode) - { - tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32), - NULL_RTX, 1, OPTAB_WIDEN); - - emit_move_insn (change_address (orig_dst, SImode, - plus_constant (XEXP (orig_dst, 0), - ofs)), - gen_lowpart (SImode, data_regs[i])); - emit_move_insn (change_address (orig_dst, SImode, - plus_constant (XEXP (orig_dst, 0), - ofs+4)), - gen_lowpart (SImode, tmp)); - ofs += 8; - i++; - } - - while (i < nregs && GET_MODE (data_regs[i]) == SImode) - { - emit_move_insn (change_address(orig_dst, SImode, - plus_constant (XEXP (orig_dst, 0), - ofs)), - data_regs[i]); - ofs += 4; - i++; - } - } - if (i < nregs && GET_MODE (data_regs[i]) == DImode) - { - /* Write out a remaining block of words using unaligned methods. */ - - for (words = 1; i+words < nregs ; ++words) - if (GET_MODE (data_regs[i+words]) != DImode) - break; - - if (words == 1) - alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs); - else - alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs); - - i += words; - ofs += words * 8; - } - - /* Due to the above, this won't be aligned. */ - /* ??? If we have more than one of these, consider constructing full - words in registers and using alpha_expand_unaligned_store_words. */ - while (i < nregs && GET_MODE (data_regs[i]) == SImode) - { - alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs); - ofs += 4; - i++; - } - - if (dst_align >= 2) - while (i < nregs && GET_MODE (data_regs[i]) == HImode) - { - emit_move_insn (change_address (orig_dst, HImode, - plus_constant (XEXP (orig_dst, 0), - ofs)), - data_regs[i]); - i++; - ofs += 2; - } - else - while (i < nregs && GET_MODE (data_regs[i]) == HImode) - { - alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs); - i++; - ofs += 2; - } - while (i < nregs && GET_MODE (data_regs[i]) == QImode) - { - emit_move_insn (change_address (orig_dst, QImode, - plus_constant (XEXP (orig_dst, 0), - ofs)), - data_regs[i]); - i++; - ofs += 1; - } - dst_done: - - if (i != nregs) - abort(); - - return 1; -} - -int -alpha_expand_block_clear (operands) - rtx operands[]; -{ - rtx bytes_rtx = operands[1]; - rtx align_rtx = operands[2]; - HOST_WIDE_INT bytes = INTVAL (bytes_rtx); - HOST_WIDE_INT align = INTVAL (align_rtx); - rtx orig_dst = operands[0]; - rtx tmp; - HOST_WIDE_INT i, words, ofs = 0; - - if (bytes <= 0) - return 1; - if (bytes > MAX_MOVE_WORDS*8) - return 0; - - /* Look for stricter alignment. */ - - tmp = XEXP (orig_dst, 0); - if (GET_CODE (tmp) == REG) - { - if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align) - align = REGNO_POINTER_ALIGN (REGNO (tmp)); - } - else if (GET_CODE (tmp) == PLUS - && GET_CODE (XEXP (tmp, 0)) == REG - && GET_CODE (XEXP (tmp, 1)) == CONST_INT) - { - HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1)); - int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0))); - - if (a > align) - { - if (a >= 8 && c % 8 == 0) - align = 8; - else if (a >= 4 && c % 4 == 0) - align = 4; - else if (a >= 2 && c % 2 == 0) - align = 2; - } - } - else if (GET_CODE (tmp) == ADDRESSOF) - { - enum machine_mode mode; - - mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1); - if (GET_MODE (XEXP (tmp, 0)) == mode) - { - emit_move_insn (XEXP (tmp, 0), const0_rtx); - return 1; - } - - /* No appropriate mode; fall back on memory. */ - orig_dst = change_address (orig_dst, GET_MODE (orig_dst), - copy_addr_to_reg (tmp)); - align = GET_MODE_SIZE (GET_MODE (XEXP (tmp, 0))); - } - - /* Handle a block of contiguous words first. */ - - if (align >= 8 && bytes >= 8) - { - words = bytes / 8; - - for (i = 0; i < words; ++i) - { - emit_move_insn (change_address(orig_dst, DImode, - plus_constant (XEXP (orig_dst, 0), - ofs + i*8)), - const0_rtx); - } - - bytes -= words * 8; - ofs += words * 8; - } - if (align >= 4 && bytes >= 4) - { - words = bytes / 4; - - for (i = 0; i < words; ++i) - { - emit_move_insn (change_address (orig_dst, SImode, - plus_constant (XEXP (orig_dst, 0), - ofs + i*4)), - const0_rtx); - } - - bytes -= words * 4; - ofs += words * 4; - } - if (bytes >= 16) - { - words = bytes / 8; - - alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs); - - bytes -= words * 8; - ofs += words * 8; - } - - /* Next clean up any trailing pieces. We know from the contiguous - block move that there are no aligned SImode or DImode hunks left. */ - - if (!TARGET_BWX && bytes >= 8) - { - alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs); - bytes -= 8; - ofs += 8; - } - if (!TARGET_BWX && bytes >= 4) - { - alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs); - bytes -= 4; - ofs += 4; - } - if (bytes >= 2) - { - if (align >= 2) - { - do { - emit_move_insn (change_address (orig_dst, HImode, - plus_constant (XEXP (orig_dst, 0), - ofs)), - const0_rtx); - bytes -= 2; - ofs += 2; - } while (bytes >= 2); - } - else if (!TARGET_BWX) - { - alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs); - bytes -= 2; - ofs += 2; - } - } - while (bytes > 0) - { - emit_move_insn (change_address (orig_dst, QImode, - plus_constant (XEXP (orig_dst, 0), - ofs)), - const0_rtx); - bytes -= 1; - ofs += 1; - } - - return 1; -} - - -/* Adjust the cost of a scheduling dependency. Return the new cost of - a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ - -int -alpha_adjust_cost (insn, link, dep_insn, cost) - rtx insn; - rtx link; - rtx dep_insn; - int cost; -{ - rtx set, set_src; - enum attr_type insn_type, dep_insn_type; - - /* If the dependence is an anti-dependence, there is no cost. For an - output dependence, there is sometimes a cost, but it doesn't seem - worth handling those few cases. */ - - if (REG_NOTE_KIND (link) != 0) - return 0; - - /* If we can't recognize the insns, we can't really do anything. */ - if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0) - return cost; - - insn_type = get_attr_type (insn); - dep_insn_type = get_attr_type (dep_insn); - - /* Bring in the user-defined memory latency. */ - if (dep_insn_type == TYPE_ILD - || dep_insn_type == TYPE_FLD - || dep_insn_type == TYPE_LDSYM) - cost += alpha_memory_latency-1; - - switch (alpha_cpu) - { - case PROCESSOR_EV4: - /* On EV4, if INSN is a store insn and DEP_INSN is setting the data - being stored, we can sometimes lower the cost. */ - - if ((insn_type == TYPE_IST || insn_type == TYPE_FST) - && (set = single_set (dep_insn)) != 0 - && GET_CODE (PATTERN (insn)) == SET - && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn)))) - { - switch (dep_insn_type) - { - case TYPE_ILD: - case TYPE_FLD: - /* No savings here. */ - return cost; - - case TYPE_IMUL: - /* In these cases, we save one cycle. */ - return cost - 1; - - default: - /* In all other cases, we save two cycles. */ - return MAX (0, cost - 2); - } - } - - /* Another case that needs adjustment is an arithmetic or logical - operation. It's cost is usually one cycle, but we default it to - two in the MD file. The only case that it is actually two is - for the address in loads, stores, and jumps. */ - - if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG) - { - switch (insn_type) - { - case TYPE_ILD: - case TYPE_IST: - case TYPE_FLD: - case TYPE_FST: - case TYPE_JSR: - return cost; - default: - return 1; - } - } - - /* The final case is when a compare feeds into an integer branch; - the cost is only one cycle in that case. */ - - if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR) - return 1; - break; - - case PROCESSOR_EV5: - /* And the lord DEC saith: "A special bypass provides an effective - latency of 0 cycles for an ICMP or ILOG insn producing the test - operand of an IBR or ICMOV insn." */ - - if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG) - && (set = single_set (dep_insn)) != 0) - { - /* A branch only has one input. This must be it. */ - if (insn_type == TYPE_IBR) - return 0; - /* A conditional move has three, make sure it is the test. */ - if (insn_type == TYPE_ICMOV - && GET_CODE (set_src = PATTERN (insn)) == SET - && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE - && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0))) - return 0; - } - - /* "The multiplier is unable to receive data from IEU bypass paths. - The instruction issues at the expected time, but its latency is - increased by the time it takes for the input data to become - available to the multiplier" -- which happens in pipeline stage - six, when results are comitted to the register file. */ - - if (insn_type == TYPE_IMUL) - { - switch (dep_insn_type) - { - /* These insns produce their results in pipeline stage five. */ - case TYPE_ILD: - case TYPE_ICMOV: - case TYPE_IMUL: - case TYPE_MVI: - return cost + 1; - - /* Other integer insns produce results in pipeline stage four. */ - default: - return cost + 2; - } - } - break; - - case PROCESSOR_EV6: - /* There is additional latency to move the result of (most) FP - operations anywhere but the FP register file. */ - - if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI) - && (dep_insn_type == TYPE_FADD || - dep_insn_type == TYPE_FMUL || - dep_insn_type == TYPE_FCMOV)) - return cost + 2; - - break; - } - - /* Otherwise, return the default cost. */ - return cost; -} - -/* Functions to save and restore alpha_return_addr_rtx. */ - -struct machine_function -{ - rtx ra_rtx; -}; - -static void -alpha_save_machine_status (p) - struct function *p; -{ - struct machine_function *machine = - (struct machine_function *) xmalloc (sizeof (struct machine_function)); - - p->machine = machine; - machine->ra_rtx = alpha_return_addr_rtx; -} - -static void -alpha_restore_machine_status (p) - struct function *p; -{ - struct machine_function *machine = p->machine; - - alpha_return_addr_rtx = machine->ra_rtx; - - free (machine); - p->machine = (struct machine_function *)0; -} - -/* Do anything needed before RTL is emitted for each function. */ - -void -alpha_init_expanders () -{ - alpha_return_addr_rtx = NULL_RTX; - alpha_eh_epilogue_sp_ofs = NULL_RTX; - - /* Arrange to save and restore machine status around nested functions. */ - save_machine_status = alpha_save_machine_status; - restore_machine_status = alpha_restore_machine_status; -} - -/* Start the ball rolling with RETURN_ADDR_RTX. */ - -rtx -alpha_return_addr (count, frame) - int count; - rtx frame ATTRIBUTE_UNUSED; -{ - rtx init; - - if (count != 0) - return const0_rtx; - - if (alpha_return_addr_rtx) - return alpha_return_addr_rtx; - - /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */ - alpha_return_addr_rtx = gen_reg_rtx (Pmode); - init = gen_rtx_SET (VOIDmode, alpha_return_addr_rtx, - gen_rtx_REG (Pmode, REG_RA)); - - /* Emit the insn to the prologue with the other argument copies. */ - push_topmost_sequence (); - emit_insn_after (init, get_insns ()); - pop_topmost_sequence (); - - return alpha_return_addr_rtx; -} - -static int -alpha_ra_ever_killed () -{ - rtx top; - -#ifdef ASM_OUTPUT_MI_THUNK - if (current_function_is_thunk) - return 0; -#endif - if (!alpha_return_addr_rtx) - return regs_ever_live[REG_RA]; - - push_topmost_sequence (); - top = get_insns (); - pop_topmost_sequence (); - - return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX); -} - - -/* Print an operand. Recognize special options, documented below. */ - -void -print_operand (file, x, code) - FILE *file; - rtx x; - char code; -{ - int i; - - switch (code) - { - case '&': - /* 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. */ - switch (alpha_fprm) - { - case ALPHA_FPRM_NORM: - break; - case ALPHA_FPRM_MINF: - fputc ('m', file); - break; - case ALPHA_FPRM_CHOP: - fputc ('c', file); - break; - case ALPHA_FPRM_DYN: - fputc ('d', file); - break; - } - break; - - case '\'': - /* Generates trap-mode suffix for instructions that accept the su - suffix only (cmpt et al). */ - if (alpha_tp == ALPHA_TP_INSN) - fputs ("su", file); - break; - - case '`': - /* Generates trap-mode suffix for instructions that accept the - v and sv suffix. The only instruction that needs this is cvtql. */ - switch (alpha_fptm) - { - case ALPHA_FPTM_N: - break; - case ALPHA_FPTM_U: - fputs ("v", file); - break; - case ALPHA_FPTM_SU: - case ALPHA_FPTM_SUI: - fputs ("sv", file); - break; - } - break; - - case '(': - /* Generates trap-mode suffix for instructions that accept the - v, sv, and svi suffix. The only instruction that needs this - is cvttq. */ - switch (alpha_fptm) - { - case ALPHA_FPTM_N: - break; - case ALPHA_FPTM_U: - fputs ("v", file); - break; - case ALPHA_FPTM_SU: - fputs ("sv", file); - break; - case ALPHA_FPTM_SUI: - fputs ("svi", file); - break; - } - break; - - case ')': - /* 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). */ - switch (alpha_fptm) - { - case ALPHA_FPTM_N: - break; - case ALPHA_FPTM_U: - fputc ('u', file); - break; - case ALPHA_FPTM_SU: - fputs ("su", file); - break; - case ALPHA_FPTM_SUI: - fputs ("sui", file); - break; - } - break; - - case '+': - /* Generates trap-mode suffix for instructions that accept the sui - suffix (cvtqt and cvtqs). */ - switch (alpha_fptm) - { - case ALPHA_FPTM_N: - case ALPHA_FPTM_U: - case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */ - break; - case ALPHA_FPTM_SUI: - fputs ("sui", file); - break; - } - break; - - case ',': - /* Generates single precision instruction suffix. */ - fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's')); - break; - - case '-': - /* Generates double precision instruction suffix. */ - fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't')); - break; - - case 'r': - /* If this operand is the constant zero, write it as "$31". */ - if (GET_CODE (x) == REG) - fprintf (file, "%s", reg_names[REGNO (x)]); - else if (x == CONST0_RTX (GET_MODE (x))) - fprintf (file, "$31"); - else - output_operand_lossage ("invalid %%r value"); - - break; - - case 'R': - /* Similar, but for floating-point. */ - if (GET_CODE (x) == REG) - fprintf (file, "%s", reg_names[REGNO (x)]); - else if (x == CONST0_RTX (GET_MODE (x))) - fprintf (file, "$f31"); - else - output_operand_lossage ("invalid %%R value"); - - break; - - case 'N': - /* Write the 1's complement of a constant. */ - if (GET_CODE (x) != CONST_INT) - output_operand_lossage ("invalid %%N value"); - - fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x)); - break; - - case 'P': - /* Write 1 << C, for a constant C. */ - if (GET_CODE (x) != CONST_INT) - output_operand_lossage ("invalid %%P value"); - - fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x)); - break; - - case 'h': - /* Write the high-order 16 bits of a constant, sign-extended. */ - if (GET_CODE (x) != CONST_INT) - output_operand_lossage ("invalid %%h value"); - - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16); - break; - - case 'L': - /* Write the low-order 16 bits of a constant, sign-extended. */ - if (GET_CODE (x) != CONST_INT) - output_operand_lossage ("invalid %%L value"); - - fprintf (file, HOST_WIDE_INT_PRINT_DEC, - (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000)); - break; - - case 'm': - /* Write mask for ZAP insn. */ - if (GET_CODE (x) == CONST_DOUBLE) - { - HOST_WIDE_INT mask = 0; - HOST_WIDE_INT value; - - value = CONST_DOUBLE_LOW (x); - for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; - i++, value >>= 8) - if (value & 0xff) - mask |= (1 << i); - - value = CONST_DOUBLE_HIGH (x); - for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; - i++, value >>= 8) - if (value & 0xff) - mask |= (1 << (i + sizeof (int))); - - fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff); - } - - else if (GET_CODE (x) == CONST_INT) - { - HOST_WIDE_INT mask = 0, value = INTVAL (x); - - for (i = 0; i < 8; i++, value >>= 8) - if (value & 0xff) - mask |= (1 << i); - - fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask); - } - else - output_operand_lossage ("invalid %%m value"); - break; - - case 'M': - /* 'b', 'w', 'l', or 'q' as the value of the constant. */ - if (GET_CODE (x) != CONST_INT - || (INTVAL (x) != 8 && INTVAL (x) != 16 - && INTVAL (x) != 32 && INTVAL (x) != 64)) - output_operand_lossage ("invalid %%M value"); - - fprintf (file, "%s", - (INTVAL (x) == 8 ? "b" - : INTVAL (x) == 16 ? "w" - : INTVAL (x) == 32 ? "l" - : "q")); - break; - - case 'U': - /* Similar, except do it from the mask. */ - if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff) - fprintf (file, "b"); - else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff) - fprintf (file, "w"); - else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff) - fprintf (file, "l"); -#if HOST_BITS_PER_WIDE_INT == 32 - else if (GET_CODE (x) == CONST_DOUBLE - && CONST_DOUBLE_HIGH (x) == 0 - && CONST_DOUBLE_LOW (x) == -1) - fprintf (file, "l"); - else if (GET_CODE (x) == CONST_DOUBLE - && CONST_DOUBLE_HIGH (x) == -1 - && CONST_DOUBLE_LOW (x) == -1) - fprintf (file, "q"); -#else - else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1) - fprintf (file, "q"); - else if (GET_CODE (x) == CONST_DOUBLE - && CONST_DOUBLE_HIGH (x) == 0 - && CONST_DOUBLE_LOW (x) == -1) - fprintf (file, "q"); -#endif - else - output_operand_lossage ("invalid %%U value"); - break; - - case 's': - /* Write the constant value divided by 8. */ - if (GET_CODE (x) != CONST_INT - && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64 - && (INTVAL (x) & 7) != 8) - output_operand_lossage ("invalid %%s value"); - - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8); - break; - - case 'S': - /* Same, except compute (64 - c) / 8 */ - - if (GET_CODE (x) != CONST_INT - && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64 - && (INTVAL (x) & 7) != 8) - output_operand_lossage ("invalid %%s value"); - - fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8); - break; - - case 'C': case 'D': case 'c': case 'd': - /* Write out comparison name. */ - { - enum rtx_code c = GET_CODE (x); - - if (GET_RTX_CLASS (c) != '<') - output_operand_lossage ("invalid %%C value"); - - if (code == 'D') - c = reverse_condition (c); - else if (code == 'c') - c = swap_condition (c); - else if (code == 'd') - c = swap_condition (reverse_condition (c)); - - if (c == LEU) - fprintf (file, "ule"); - else if (c == LTU) - fprintf (file, "ult"); - else - fprintf (file, "%s", GET_RTX_NAME (c)); - } - break; - - case 'E': - /* Write the divide or modulus operator. */ - switch (GET_CODE (x)) - { - case DIV: - fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q"); - break; - case UDIV: - fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q"); - break; - case MOD: - fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q"); - break; - case UMOD: - fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q"); - break; - default: - output_operand_lossage ("invalid %%E value"); - break; - } - break; - - case 'A': - /* Write "_u" for unaligned access. */ - if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND) - fprintf (file, "_u"); - break; - - case 0: - if (GET_CODE (x) == REG) - fprintf (file, "%s", reg_names[REGNO (x)]); - else if (GET_CODE (x) == MEM) - output_address (XEXP (x, 0)); - else - output_addr_const (file, x); - break; - - default: - output_operand_lossage ("invalid %%xn code"); - } -} - -void -print_operand_address (file, addr) - FILE *file; - rtx addr; -{ - int basereg = 31; - HOST_WIDE_INT offset = 0; - - if (GET_CODE (addr) == AND) - addr = XEXP (addr, 0); - - if (GET_CODE (addr) == PLUS - && GET_CODE (XEXP (addr, 1)) == CONST_INT) - { - offset = INTVAL (XEXP (addr, 1)); - addr = XEXP (addr, 0); - } - if (GET_CODE (addr) == REG) - basereg = REGNO (addr); - else if (GET_CODE (addr) == SUBREG - && GET_CODE (SUBREG_REG (addr)) == REG) - basereg = REGNO (SUBREG_REG (addr)) + SUBREG_WORD (addr); - else if (GET_CODE (addr) == CONST_INT) - offset = INTVAL (addr); - else - abort (); - - fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset); - fprintf (file, "($%d)", basereg); -} - -/* Emit RTL insns to initialize the variable parts of a trampoline at - TRAMP. 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. - - The three offset parameters are for the individual template's - layout. A JMPOFS < 0 indicates that the trampoline does not - contain instructions at all. - - We assume here that a function will be called many more times than - its address is taken (e.g., it might be passed to qsort), so we - take the trouble to initialize the "hint" field in the JMP insn. - Note that the hint field is PC (new) + 4 * bits 13:0. */ - -void -alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs) - rtx tramp, fnaddr, cxt; - int fnofs, cxtofs, jmpofs; -{ - rtx temp, temp1, addr; - /* VMS really uses DImode pointers in memory at this point. */ - enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode; - -#ifdef POINTERS_EXTEND_UNSIGNED - fnaddr = convert_memory_address (mode, fnaddr); - cxt = convert_memory_address (mode, cxt); -#endif - - /* Store function address and CXT. */ - addr = memory_address (mode, plus_constant (tramp, fnofs)); - emit_move_insn (gen_rtx (MEM, mode, addr), fnaddr); - addr = memory_address (mode, plus_constant (tramp, cxtofs)); - emit_move_insn (gen_rtx (MEM, mode, addr), cxt); - - /* This has been disabled since the hint only has a 32k range, and in - no existing OS is the stack within 32k of the text segment. */ - if (0 && jmpofs >= 0) - { - /* Compute hint value. */ - temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX); - temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1, - OPTAB_WIDEN); - temp = expand_shift (RSHIFT_EXPR, Pmode, temp, - build_int_2 (2, 0), NULL_RTX, 1); - temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0); - - /* Merge in the hint. */ - addr = memory_address (SImode, plus_constant (tramp, jmpofs)); - temp1 = force_reg (SImode, gen_rtx (MEM, SImode, addr)); - temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX); - temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1, - OPTAB_WIDEN); - emit_move_insn (gen_rtx (MEM, SImode, addr), temp1); - } - -#ifdef TRANSFER_FROM_TRAMPOLINE - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"), - 0, VOIDmode, 1, addr, Pmode); -#endif - - if (jmpofs >= 0) - emit_insn (gen_imb ()); -} - -/* Do what is necessary for `va_start'. The argument is ignored; - We look at the current function to determine if stdarg or varargs - is used and fill in an initial va_list. A pointer to this constructor - is returned. */ - -struct rtx_def * -alpha_builtin_saveregs (arglist) - tree arglist ATTRIBUTE_UNUSED; -{ - rtx block, addr, dest, argsize; - tree fntype = TREE_TYPE (current_function_decl); - int stdarg = (TYPE_ARG_TYPES (fntype) != 0 - && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) - != void_type_node)); - - /* Compute the current position into the args, taking into account - both registers and memory. Both of these are already included in - NUM_ARGS. */ - - argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD); - - /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48, - storing fp arg registers in the first 48 bytes, and the integer arg - registers in the next 48 bytes. This is only done, however, if any - integer registers need to be stored. - - If no integer registers need be stored, then we must subtract 48 in - order to account for the integer arg registers which are counted in - argsize above, but which are not actually stored on the stack. */ - - if (TARGET_OPEN_VMS) - addr = plus_constant (virtual_incoming_args_rtx, - NUM_ARGS <= 5 + stdarg - ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD); - else - addr = (NUM_ARGS <= 5 + stdarg - ? plus_constant (virtual_incoming_args_rtx, - 6 * UNITS_PER_WORD) - : plus_constant (virtual_incoming_args_rtx, - - (6 * UNITS_PER_WORD))); - - /* For VMS, we include the argsize, while on Unix, it's handled as - a separate field. */ - if (TARGET_OPEN_VMS) - addr = plus_constant (addr, INTVAL (argsize)); - - addr = force_operand (addr, NULL_RTX); - -#ifdef POINTERS_EXTEND_UNSIGNED - addr = convert_memory_address (ptr_mode, addr); -#endif - - if (TARGET_OPEN_VMS) - return addr; - else - { - /* Allocate the va_list constructor */ - block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD); - RTX_UNCHANGING_P (block) = 1; - RTX_UNCHANGING_P (XEXP (block, 0)) = 1; - - /* Store the address of the first integer register in the __base - member. */ - - dest = change_address (block, ptr_mode, XEXP (block, 0)); - emit_move_insn (dest, addr); - - if (current_function_check_memory_usage) - emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, - dest, ptr_mode, - GEN_INT (GET_MODE_SIZE (ptr_mode)), - TYPE_MODE (sizetype), - GEN_INT (MEMORY_USE_RW), - TYPE_MODE (integer_type_node)); - - /* Store the argsize as the __va_offset member. */ - dest = change_address (block, TYPE_MODE (integer_type_node), - plus_constant (XEXP (block, 0), - POINTER_SIZE/BITS_PER_UNIT)); - emit_move_insn (dest, argsize); - - if (current_function_check_memory_usage) - emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, - dest, ptr_mode, - GEN_INT (GET_MODE_SIZE - (TYPE_MODE (integer_type_node))), - TYPE_MODE (sizetype), - GEN_INT (MEMORY_USE_RW), - TYPE_MODE (integer_type_node)); - - /* Return the address of the va_list constructor, but don't put it in a - register. Doing so would fail when not optimizing and produce worse - code when optimizing. */ - return XEXP (block, 0); - } -} - -/* This page contains routines that are used to determine what the function - prologue and epilogue code will do and write them out. */ - -/* Compute the size of the save area in the stack. */ - -/* These variables are used for communication between the following functions. - They indicate various things about the current function being compiled - that are used to tell what kind of prologue, epilogue and procedure - descriptior to generate. */ - -/* Nonzero if we need a stack procedure. */ -static int vms_is_stack_procedure; - -/* Register number (either FP or SP) that is used to unwind the frame. */ -static int vms_unwind_regno; - -/* Register number used to save FP. We need not have one for RA since - we don't modify it for register procedures. This is only defined - for register frame procedures. */ -static int vms_save_fp_regno; - -/* Register number used to reference objects off our PV. */ -static int vms_base_regno; - -/* Compute register masks for saved registers. */ - -static void -alpha_sa_mask (imaskP, fmaskP) - unsigned long *imaskP; - unsigned long *fmaskP; -{ - unsigned long imask = 0; - unsigned long fmask = 0; - int i; - -#ifdef ASM_OUTPUT_MI_THUNK - if (!current_function_is_thunk) -#endif - { - if (TARGET_OPEN_VMS && vms_is_stack_procedure) - imask |= (1L << HARD_FRAME_POINTER_REGNUM); - - /* One for every register we have to save. */ - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (! fixed_regs[i] && ! call_used_regs[i] - && regs_ever_live[i] && i != REG_RA) - { - if (i < 32) - imask |= (1L << i); - else - fmask |= (1L << (i - 32)); - } - - if (imask || fmask || alpha_ra_ever_killed ()) - imask |= (1L << REG_RA); - } - - *imaskP = imask; - *fmaskP = fmask; -} - -int -alpha_sa_size () -{ - int sa_size = 0; - int i; - -#ifdef ASM_OUTPUT_MI_THUNK - if (current_function_is_thunk) - sa_size = 0; - else -#endif - { - /* One for every register we have to save. */ - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (! fixed_regs[i] && ! call_used_regs[i] - && regs_ever_live[i] && i != REG_RA) - sa_size++; - } - - if (TARGET_OPEN_VMS) - { - /* Start by assuming we can use a register procedure if we don't - make any calls (REG_RA not used) or need to save any - registers and a stack procedure if we do. */ - vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed (); - - /* Decide whether to refer to objects off our PV via FP or PV. - If we need FP for something else or if we receive a nonlocal - goto (which expects PV to contain the value), we must use PV. - Otherwise, start by assuming we can use FP. */ - vms_base_regno = (frame_pointer_needed - || current_function_has_nonlocal_label - || vms_is_stack_procedure - || current_function_outgoing_args_size - ? REG_PV : HARD_FRAME_POINTER_REGNUM); - - /* If we want to copy PV into FP, we need to find some register - in which to save FP. */ - - vms_save_fp_regno = -1; - if (vms_base_regno == HARD_FRAME_POINTER_REGNUM) - for (i = 0; i < 32; i++) - if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i]) - vms_save_fp_regno = i; - - if (vms_save_fp_regno == -1) - vms_base_regno = REG_PV, vms_is_stack_procedure = 1; - - /* Stack unwinding should be done via FP unless we use it for PV. */ - vms_unwind_regno = (vms_base_regno == REG_PV - ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM); - - /* If this is a stack procedure, allow space for saving FP and RA. */ - if (vms_is_stack_procedure) - sa_size += 2; - } - else - { - /* If some registers were saved but not RA, RA must also be saved, - so leave space for it. */ - if (sa_size != 0 || alpha_ra_ever_killed ()) - sa_size++; - - /* Our size must be even (multiple of 16 bytes). */ - if (sa_size & 1) - sa_size++; - } - - return sa_size * 8; -} - -int -alpha_pv_save_size () -{ - alpha_sa_size (); - return vms_is_stack_procedure ? 8 : 0; -} - -int -alpha_using_fp () -{ - alpha_sa_size (); - return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM; -} - -int -vms_valid_decl_attribute_p (decl, attributes, identifier, args) - tree decl ATTRIBUTE_UNUSED; - tree attributes ATTRIBUTE_UNUSED; - tree identifier; - tree args; -{ - if (is_attribute_p ("overlaid", identifier)) - return (args == NULL_TREE); - return 0; -} - -static int -alpha_does_function_need_gp () -{ - rtx insn; - - /* We never need a GP for Windows/NT or VMS. */ - if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS) - return 0; - -#ifdef TARGET_PROFILING_NEEDS_GP - if (profile_flag) - return 1; -#endif - -#ifdef ASM_OUTPUT_MI_THUNK - if (current_function_is_thunk) - return 1; -#endif - - /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first. - Even if we are a static function, we still need to do this in case - our address is taken and passed to something like qsort. */ - - push_topmost_sequence (); - insn = get_insns (); - pop_topmost_sequence (); - - for (; insn; insn = NEXT_INSN (insn)) - if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' - && GET_CODE (PATTERN (insn)) != USE - && GET_CODE (PATTERN (insn)) != CLOBBER) - { - enum attr_type type = get_attr_type (insn); - if (type == TYPE_LDSYM || type == TYPE_JSR) - return 1; - } - - return 0; -} - -/* Write a version stamp. Don't write anything if we are running as a - cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */ - -#ifdef HAVE_STAMP_H -#include <stamp.h> -#endif - -void -alpha_write_verstamp (file) - FILE *file ATTRIBUTE_UNUSED; -{ -#ifdef MS_STAMP - fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP); -#endif -} - -/* Helper function to set RTX_FRAME_RELATED_P on instructions, including - sequences. */ - -static rtx -set_frame_related_p () -{ - rtx seq = gen_sequence (); - end_sequence (); - - if (GET_CODE (seq) == SEQUENCE) - { - int i = XVECLEN (seq, 0); - while (--i >= 0) - RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1; - return emit_insn (seq); - } - else - { - seq = emit_insn (seq); - RTX_FRAME_RELATED_P (seq) = 1; - return seq; - } -} - -#define FRP(exp) (start_sequence (), exp, set_frame_related_p ()) - -/* Write function prologue. */ - -/* On vms we have two kinds of functions: - - - stack frame (PROC_STACK) - these are 'normal' functions with local vars and which are - calling other functions - - register frame (PROC_REGISTER) - keeps all data in registers, needs no stack - - We must pass this to the assembler so it can generate the - proper pdsc (procedure descriptor) - This is done with the '.pdesc' command. - - On not-vms, we don't really differentiate between the two, as we can - simply allocate stack without saving registers. */ - -void -alpha_expand_prologue () -{ - /* Registers to save. */ - unsigned long imask = 0; - unsigned long fmask = 0; - /* Stack space needed for pushing registers clobbered by us. */ - HOST_WIDE_INT sa_size; - /* Complete stack size needed. */ - HOST_WIDE_INT frame_size; - /* Offset from base reg to register save area. */ - HOST_WIDE_INT reg_offset; - rtx sa_reg, mem; - int i; - - sa_size = alpha_sa_size (); - - frame_size = get_frame_size (); - if (TARGET_OPEN_VMS) - frame_size = ALPHA_ROUND (sa_size - + (vms_is_stack_procedure ? 8 : 0) - + frame_size - + current_function_pretend_args_size); - else - frame_size = (ALPHA_ROUND (current_function_outgoing_args_size) - + sa_size - + ALPHA_ROUND (frame_size - + current_function_pretend_args_size)); - - if (TARGET_OPEN_VMS) - reg_offset = 8; - else - reg_offset = ALPHA_ROUND (current_function_outgoing_args_size); - - alpha_sa_mask (&imask, &fmask); - - /* Adjust the stack by the frame size. If the frame size is > 4096 - bytes, we need to be sure we probe somewhere in the first and last - 4096 bytes (we can probably get away without the latter test) and - every 8192 bytes in between. If the frame size is > 32768, we - do this in a loop. Otherwise, we generate the explicit probe - instructions. - - Note that we are only allowed to adjust sp once in the prologue. */ - - if (frame_size <= 32768) - { - if (frame_size > 4096) - { - int probed = 4096; - - do - emit_insn (gen_probe_stack (GEN_INT (-probed))); - while ((probed += 8192) < frame_size); - - /* We only have to do this probe if we aren't saving registers. */ - if (sa_size == 0 && probed + 4096 < frame_size) - emit_insn (gen_probe_stack (GEN_INT (-frame_size))); - } - - if (frame_size != 0) - { - FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (-frame_size)))); - } - } - else - { - /* Here we generate code to set R22 to SP + 4096 and set R23 to the - number of 8192 byte blocks to probe. We then probe each block - in the loop and then set SP to the proper location. If the - amount remaining is > 4096, we have to do one more probe if we - are not saving any registers. */ - - HOST_WIDE_INT blocks = (frame_size + 4096) / 8192; - HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192; - rtx ptr = gen_rtx_REG (DImode, 22); - rtx count = gen_rtx_REG (DImode, 23); - rtx seq; - - emit_move_insn (count, GEN_INT (blocks)); - emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096))); - - /* Because of the difficulty in emitting a new basic block this - late in the compilation, generate the loop as a single insn. */ - emit_insn (gen_prologue_stack_probe_loop (count, ptr)); - - if (leftover > 4096 && sa_size == 0) - { - rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover)); - MEM_VOLATILE_P (last) = 1; - emit_move_insn (last, const0_rtx); - } - - if (TARGET_WINDOWS_NT) - { - /* For NT stack unwind (done by 'reverse execution'), it's - not OK to take the result of a loop, even though the value - is already in ptr, so we reload it via a single operation - and subtract it to sp. - - Yes, that's correct -- we have to reload the whole constant - into a temporary via ldah+lda then subtract from sp. To - ensure we get ldah+lda, we use a special pattern. */ - - HOST_WIDE_INT lo, hi; - lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000; - hi = frame_size - lo; - - emit_move_insn (ptr, GEN_INT (hi)); - emit_insn (gen_nt_lda (ptr, GEN_INT (lo))); - seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, - ptr)); - } - else - { - seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr, - GEN_INT (-leftover))); - } - - /* This alternative is special, because the DWARF code cannot - possibly intuit through the loop above. So we invent this - note it looks at instead. */ - RTX_FRAME_RELATED_P (seq) = 1; - REG_NOTES (seq) - = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, - gen_rtx_SET (VOIDmode, stack_pointer_rtx, - gen_rtx_PLUS (Pmode, stack_pointer_rtx, - GEN_INT (-frame_size))), - REG_NOTES (seq)); - } - - /* Cope with very large offsets to the register save area. */ - sa_reg = stack_pointer_rtx; - if (reg_offset + sa_size > 0x8000) - { - int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000; - HOST_WIDE_INT bias; - - if (low + sa_size <= 0x8000) - bias = reg_offset - low, reg_offset = low; - else - bias = reg_offset, reg_offset = 0; - - sa_reg = gen_rtx_REG (DImode, 24); - FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, GEN_INT (bias)))); - } - - /* Save regs in stack order. Beginning with VMS PV. */ - if (TARGET_OPEN_VMS && vms_is_stack_procedure) - { - mem = gen_rtx_MEM (DImode, stack_pointer_rtx); - MEM_ALIAS_SET (mem) = alpha_sr_alias_set; - FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV))); - } - - /* Save register RA next. */ - if (imask & (1L << REG_RA)) - { - mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset)); - MEM_ALIAS_SET (mem) = alpha_sr_alias_set; - FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA))); - imask &= ~(1L << REG_RA); - reg_offset += 8; - } - - /* Now save any other registers required to be saved. */ - for (i = 0; i < 32; i++) - if (imask & (1L << i)) - { - mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset)); - MEM_ALIAS_SET (mem) = alpha_sr_alias_set; - FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i))); - reg_offset += 8; - } - - for (i = 0; i < 32; i++) - if (fmask & (1L << i)) - { - mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset)); - MEM_ALIAS_SET (mem) = alpha_sr_alias_set; - FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32))); - reg_offset += 8; - } - - if (TARGET_OPEN_VMS) - { - if (!vms_is_stack_procedure) - { - /* Register frame procedures fave the fp. */ - FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno), - hard_frame_pointer_rtx)); - } - - if (vms_base_regno != REG_PV) - FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno), - gen_rtx_REG (DImode, REG_PV))); - - if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM) - { - FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx)); - } - - /* If we have to allocate space for outgoing args, do it now. */ - if (current_function_outgoing_args_size != 0) - { - FRP (emit_move_insn (stack_pointer_rtx, - plus_constant (hard_frame_pointer_rtx, - - ALPHA_ROUND (current_function_outgoing_args_size)))); - } - } - else - { - /* If we need a frame pointer, set it from the stack pointer. */ - if (frame_pointer_needed) - { - if (TARGET_CAN_FAULT_IN_PROLOGUE) - FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx)); - else - { - /* This must always be the last instruction in the - prologue, thus we emit a special move + clobber. */ - FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx, - stack_pointer_rtx, sa_reg))); - } - } - } - - /* The ABIs for VMS and OSF/1 say that while we can schedule insns into - the prologue, for exception handling reasons, we cannot do this for - any insn that might fault. We could prevent this for mems with a - (clobber:BLK (scratch)), but this doesn't work for fp insns. So we - have to prevent all such scheduling with a blockage. - - Linux, on the other hand, never bothered to implement OSF/1's - exception handling, and so doesn't care about such things. Anyone - planning to use dwarf2 frame-unwind info can also omit the blockage. */ - - if (! TARGET_CAN_FAULT_IN_PROLOGUE) - emit_insn (gen_blockage ()); -} - -/* Output the textual info surrounding the prologue. */ - -void -alpha_start_function (file, fnname, decl) - FILE *file; - char *fnname; - tree decl ATTRIBUTE_UNUSED; -{ - unsigned long imask = 0; - unsigned long fmask = 0; - /* Stack space needed for pushing registers clobbered by us. */ - HOST_WIDE_INT sa_size; - /* Complete stack size needed. */ - HOST_WIDE_INT frame_size; - /* Offset from base reg to register save area. */ - HOST_WIDE_INT reg_offset; - char *entry_label = (char *) alloca (strlen (fnname) + 6); - int i; - - sa_size = alpha_sa_size (); - - frame_size = get_frame_size (); - if (TARGET_OPEN_VMS) - frame_size = ALPHA_ROUND (sa_size - + (vms_is_stack_procedure ? 8 : 0) - + frame_size - + current_function_pretend_args_size); - else - frame_size = (ALPHA_ROUND (current_function_outgoing_args_size) - + sa_size - + ALPHA_ROUND (frame_size - + current_function_pretend_args_size)); - - if (TARGET_OPEN_VMS) - reg_offset = 8; - else - reg_offset = ALPHA_ROUND (current_function_outgoing_args_size); - - alpha_sa_mask (&imask, &fmask); - - /* Ecoff can handle multiple .file directives, so put out file and lineno. - We have to do that before the .ent directive as we cannot switch - files within procedures with native ecoff because line numbers are - linked to procedure descriptors. - Outputting the lineno helps debugging of one line functions as they - would otherwise get no line number at all. Please note that we would - like to put out last_linenum from final.c, but it is not accessible. */ - - if (write_symbols == SDB_DEBUG) - { - ASM_OUTPUT_SOURCE_FILENAME (file, - DECL_SOURCE_FILE (current_function_decl)); - if (debug_info_level != DINFO_LEVEL_TERSE) - ASM_OUTPUT_SOURCE_LINE (file, - DECL_SOURCE_LINE (current_function_decl)); - } - - /* Issue function start and label. */ - if (TARGET_OPEN_VMS || !flag_inhibit_size_directive) - { - fputs ("\t.ent ", file); - assemble_name (file, fnname); - putc ('\n', file); - } - - strcpy (entry_label, fnname); - if (TARGET_OPEN_VMS) - strcat (entry_label, "..en"); - ASM_OUTPUT_LABEL (file, entry_label); - inside_function = TRUE; - - if (TARGET_OPEN_VMS) - fprintf (file, "\t.base $%d\n", vms_base_regno); - - if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT - && !flag_inhibit_size_directive) - { - /* Set flags in procedure descriptor to request IEEE-conformant - math-library routines. The value we set it to is PDSC_EXC_IEEE - (/usr/include/pdsc.h). */ - fputs ("\t.eflag 48\n", file); - } - - /* Set up offsets to alpha virtual arg/local debugging pointer. */ - alpha_auto_offset = -frame_size + current_function_pretend_args_size; - alpha_arg_offset = -frame_size + 48; - - /* Describe our frame. If the frame size is larger than an integer, - print it as zero to avoid an assembler error. We won't be - properly describing such a frame, but that's the best we can do. */ - if (TARGET_OPEN_VMS) - { - fprintf (file, "\t.frame $%d,", vms_unwind_regno); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, - frame_size >= (1l << 31) ? 0 : frame_size); - fputs (",$26,", file); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset); - fputs ("\n", file); - } - else if (!flag_inhibit_size_directive) - { - fprintf (file, "\t.frame $%d,", - (frame_pointer_needed - ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM)); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, - frame_size >= (1l << 31) ? 0 : frame_size); - fprintf (file, ",$26,%d\n", current_function_pretend_args_size); - } - - /* Describe which registers were spilled. */ - if (TARGET_OPEN_VMS) - { - if (imask) - /* ??? Does VMS care if mask contains ra? The old code did'nt - set it, so I don't here. */ - fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA)); - if (fmask) - fprintf (file, "\t.fmask 0x%lx,0\n", fmask); - if (!vms_is_stack_procedure) - fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno); - } - else if (!flag_inhibit_size_directive) - { - if (imask) - { - fprintf (file, "\t.mask 0x%lx,", imask); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, - frame_size >= (1l << 31) ? 0 : reg_offset - frame_size); - putc ('\n', file); - - for (i = 0; i < 32; ++i) - if (imask & (1L << i)) - reg_offset += 8; - } - - if (fmask) - { - fprintf (file, "\t.fmask 0x%lx,", fmask); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, - frame_size >= (1l << 31) ? 0 : reg_offset - frame_size); - putc ('\n', file); - } - } - - /* Emit GP related things. It is rather unfortunate about the alignment - issues surrounding a CODE_LABEL that forces us to do the label in - plain text. */ - if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT) - { - alpha_function_needs_gp = alpha_does_function_need_gp (); - if (alpha_function_needs_gp) - fputs ("\tldgp $29,0($27)\n", file); - - putc ('$', file); - assemble_name (file, fnname); - fputs ("..ng:\n", file); - } - -#ifdef OPEN_VMS - /* Ifdef'ed cause readonly_section and link_section are only - available then. */ - readonly_section (); - fprintf (file, "\t.align 3\n"); - assemble_name (file, fnname); fputs ("..na:\n", file); - fputs ("\t.ascii \"", file); - assemble_name (file, fnname); - fputs ("\\0\"\n", file); - - link_section (); - fprintf (file, "\t.align 3\n"); - fputs ("\t.name ", file); - assemble_name (file, fnname); - fputs ("..na\n", file); - ASM_OUTPUT_LABEL (file, fnname); - fprintf (file, "\t.pdesc "); - assemble_name (file, fnname); - fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg"); - alpha_need_linkage (fnname, 1); - text_section (); -#endif -} - -/* Emit the .prologue note at the scheduled end of the prologue. */ - -void -output_end_prologue (file) - FILE *file; -{ - if (TARGET_OPEN_VMS) - fputs ("\t.prologue\n", file); - else if (TARGET_WINDOWS_NT) - fputs ("\t.prologue 0\n", file); - else if (!flag_inhibit_size_directive) - fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp); -} - -/* Write function epilogue. */ - -/* ??? At some point we will want to support full unwind, and so will - need to mark the epilogue as well. At the moment, we just confuse - dwarf2out. */ -#undef FRP -#define FRP(exp) exp - -void -alpha_expand_epilogue () -{ - /* Registers to save. */ - unsigned long imask = 0; - unsigned long fmask = 0; - /* Stack space needed for pushing registers clobbered by us. */ - HOST_WIDE_INT sa_size; - /* Complete stack size needed. */ - HOST_WIDE_INT frame_size; - /* Offset from base reg to register save area. */ - HOST_WIDE_INT reg_offset; - int fp_is_frame_pointer, fp_offset; - rtx sa_reg, sa_reg_exp = NULL; - rtx sp_adj1, sp_adj2, mem; - int i; - - sa_size = alpha_sa_size (); - - frame_size = get_frame_size (); - if (TARGET_OPEN_VMS) - frame_size = ALPHA_ROUND (sa_size - + (vms_is_stack_procedure ? 8 : 0) - + frame_size - + current_function_pretend_args_size); - else - frame_size = (ALPHA_ROUND (current_function_outgoing_args_size) - + sa_size - + ALPHA_ROUND (frame_size - + current_function_pretend_args_size)); - - if (TARGET_OPEN_VMS) - reg_offset = 8; - else - reg_offset = ALPHA_ROUND (current_function_outgoing_args_size); - - alpha_sa_mask (&imask, &fmask); - - fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure) - || (!TARGET_OPEN_VMS && frame_pointer_needed)); - - if (sa_size) - { - /* If we have a frame pointer, restore SP from it. */ - if ((TARGET_OPEN_VMS - && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM) - || (!TARGET_OPEN_VMS && frame_pointer_needed)) - { - FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx)); - } - - /* Cope with very large offsets to the register save area. */ - sa_reg = stack_pointer_rtx; - if (reg_offset + sa_size > 0x8000) - { - int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000; - HOST_WIDE_INT bias; - - if (low + sa_size <= 0x8000) - bias = reg_offset - low, reg_offset = low; - else - bias = reg_offset, reg_offset = 0; - - sa_reg = gen_rtx_REG (DImode, 22); - sa_reg_exp = plus_constant (stack_pointer_rtx, bias); - - FRP (emit_move_insn (sa_reg, sa_reg_exp)); - } - - /* Restore registers in order, excepting a true frame pointer. */ - - if (! alpha_eh_epilogue_sp_ofs) - { - mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset)); - MEM_ALIAS_SET (mem) = alpha_sr_alias_set; - FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem)); - } - reg_offset += 8; - imask &= ~(1L << REG_RA); - - for (i = 0; i < 32; ++i) - if (imask & (1L << i)) - { - if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer) - fp_offset = reg_offset; - else - { - mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset)); - MEM_ALIAS_SET (mem) = alpha_sr_alias_set; - FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem)); - } - reg_offset += 8; - } - - for (i = 0; i < 32; ++i) - if (fmask & (1L << i)) - { - mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset)); - MEM_ALIAS_SET (mem) = alpha_sr_alias_set; - FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem)); - reg_offset += 8; - } - } - - if (frame_size || alpha_eh_epilogue_sp_ofs) - { - sp_adj1 = stack_pointer_rtx; - - if (alpha_eh_epilogue_sp_ofs) - { - sp_adj1 = gen_rtx_REG (DImode, 23); - emit_move_insn (sp_adj1, - gen_rtx_PLUS (Pmode, stack_pointer_rtx, - alpha_eh_epilogue_sp_ofs)); - } - - /* If the stack size is large, begin computation into a temporary - register so as not to interfere with a potential fp restore, - which must be consecutive with an SP restore. */ - if (frame_size < 32768) - sp_adj2 = GEN_INT (frame_size); - else if (frame_size < 0x40007fffL) - { - int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000; - - sp_adj2 = plus_constant (sp_adj1, frame_size - low); - if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2)) - sp_adj1 = sa_reg; - else - { - sp_adj1 = gen_rtx_REG (DImode, 23); - FRP (emit_move_insn (sp_adj1, sp_adj2)); - } - sp_adj2 = GEN_INT (low); - } - else - { - rtx tmp = gen_rtx_REG (DImode, 23); - FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3)); - if (!sp_adj2) - { - /* We can't drop new things to memory this late, afaik, - so build it up by pieces. */ - FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size, - -(frame_size < 0))); - if (!sp_adj2) - abort (); - } - } - - /* From now on, things must be in order. So emit blockages. */ - - /* Restore the frame pointer. */ - if (fp_is_frame_pointer) - { - emit_insn (gen_blockage ()); - mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset)); - MEM_ALIAS_SET (mem) = alpha_sr_alias_set; - FRP (emit_move_insn (hard_frame_pointer_rtx, mem)); - } - else if (TARGET_OPEN_VMS) - { - emit_insn (gen_blockage ()); - FRP (emit_move_insn (hard_frame_pointer_rtx, - gen_rtx_REG (DImode, vms_save_fp_regno))); - } - - /* Restore the stack pointer. */ - emit_insn (gen_blockage ()); - FRP (emit_move_insn (stack_pointer_rtx, - gen_rtx_PLUS (DImode, sp_adj1, sp_adj2))); - } - else - { - if (TARGET_OPEN_VMS && !vms_is_stack_procedure) - { - emit_insn (gen_blockage ()); - FRP (emit_move_insn (hard_frame_pointer_rtx, - gen_rtx_REG (DImode, vms_save_fp_regno))); - } - } - - /* Return. */ - emit_jump_insn (gen_return_internal ()); -} - -/* Output the rest of the textual info surrounding the epilogue. */ - -void -alpha_end_function (file, fnname, decl) - FILE *file; - char *fnname; - tree decl ATTRIBUTE_UNUSED; -{ - /* End the function. */ - if (!flag_inhibit_size_directive) - { - fputs ("\t.end ", file); - assemble_name (file, fnname); - putc ('\n', file); - } - inside_function = FALSE; - - /* Show that we know this function if it is called again. - - Don't do this for global functions in object files destined for a - shared library because the function may be overridden by the application - or other libraries. Similarly, don't do this for weak functions. */ - - if (!DECL_WEAK (current_function_decl) - && (!flag_pic || !TREE_PUBLIC (current_function_decl))) - SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1; -} - -/* Debugging support. */ - -#include "gstab.h" - -/* Count the number of sdb related labels are generated (to find block - start and end boundaries). */ - -int sdb_label_count = 0; - -/* Next label # for each statement. */ - -static int sym_lineno = 0; - -/* Count the number of .file directives, so that .loc is up to date. */ - -static int num_source_filenames = 0; - -/* Name of the file containing the current function. */ - -static const char *current_function_file = ""; - -/* Offsets to alpha virtual arg/local debugging pointers. */ - -long alpha_arg_offset; -long alpha_auto_offset; - -/* Emit a new filename to a stream. */ - -void -alpha_output_filename (stream, name) - FILE *stream; - char *name; -{ - static int first_time = TRUE; - char ltext_label_name[100]; - - if (first_time) - { - first_time = FALSE; - ++num_source_filenames; - current_function_file = name; - fprintf (stream, "\t.file\t%d ", num_source_filenames); - output_quoted_string (stream, name); - fprintf (stream, "\n"); - if (!TARGET_GAS && write_symbols == DBX_DEBUG) - fprintf (stream, "\t#@stabs\n"); - } - - else if (write_symbols == DBX_DEBUG) - { - ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0); - fprintf (stream, "%s ", ASM_STABS_OP); - output_quoted_string (stream, name); - fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]); - } - - else if (name != current_function_file - && strcmp (name, current_function_file) != 0) - { - if (inside_function && ! TARGET_GAS) - fprintf (stream, "\t#.file\t%d ", num_source_filenames); - else - { - ++num_source_filenames; - current_function_file = name; - fprintf (stream, "\t.file\t%d ", num_source_filenames); - } - - output_quoted_string (stream, name); - fprintf (stream, "\n"); - } -} - -/* Emit a linenumber to a stream. */ - -void -alpha_output_lineno (stream, line) - FILE *stream; - int line; -{ - if (write_symbols == DBX_DEBUG) - { - /* mips-tfile doesn't understand .stabd directives. */ - ++sym_lineno; - fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n", - sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno); - } - else - fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line); -} - -/* Structure to show the current status of registers and memory. */ - -struct shadow_summary -{ - struct { - unsigned long i : 31; /* Mask of int regs */ - unsigned long fp : 31; /* Mask of fp regs */ - unsigned long mem : 1; /* mem == imem | fpmem */ - } used, defd; -}; - -static void summarize_insn PROTO((rtx, struct shadow_summary *, int)); -static void alpha_handle_trap_shadows PROTO((rtx)); - -/* Summary the effects of expression X on the machine. Update SUM, a pointer - to the summary structure. SET is nonzero if the insn is setting the - object, otherwise zero. */ - -static void -summarize_insn (x, sum, set) - rtx x; - struct shadow_summary *sum; - int set; -{ - char *format_ptr; - int i, j; - - if (x == 0) - return; - - switch (GET_CODE (x)) - { - /* ??? Note that this case would be incorrect if the Alpha had a - ZERO_EXTRACT in SET_DEST. */ - case SET: - summarize_insn (SET_SRC (x), sum, 0); - summarize_insn (SET_DEST (x), sum, 1); - break; - - case CLOBBER: - summarize_insn (XEXP (x, 0), sum, 1); - break; - - case USE: - summarize_insn (XEXP (x, 0), sum, 0); - break; - - case ASM_OPERANDS: - for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--) - summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0); - break; - - case PARALLEL: - for (i = XVECLEN (x, 0) - 1; i >= 0; i--) - summarize_insn (XVECEXP (x, 0, i), sum, 0); - break; - - case SUBREG: - summarize_insn (SUBREG_REG (x), sum, 0); - break; - - case REG: - { - int regno = REGNO (x); - unsigned long mask = 1UL << (regno % 32); - - if (regno == 31 || regno == 63) - break; - - if (set) - { - if (regno < 32) - sum->defd.i |= mask; - else - sum->defd.fp |= mask; - } - else - { - if (regno < 32) - sum->used.i |= mask; - else - sum->used.fp |= mask; - } - } - break; - - case MEM: - if (set) - sum->defd.mem = 1; - else - sum->used.mem = 1; - - /* Find the regs used in memory address computation: */ - summarize_insn (XEXP (x, 0), sum, 0); - break; - - case CONST_INT: case CONST_DOUBLE: - case SYMBOL_REF: case LABEL_REF: case CONST: - break; - - /* Handle common unary and binary ops for efficiency. */ - case COMPARE: case PLUS: case MINUS: case MULT: case DIV: - case MOD: case UDIV: case UMOD: case AND: case IOR: - case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT: - case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX: - case NE: case EQ: case GE: case GT: case LE: - case LT: case GEU: case GTU: case LEU: case LTU: - summarize_insn (XEXP (x, 0), sum, 0); - summarize_insn (XEXP (x, 1), sum, 0); - break; - - case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND: - case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT: - case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS: - case SQRT: case FFS: - summarize_insn (XEXP (x, 0), sum, 0); - break; - - default: - format_ptr = GET_RTX_FORMAT (GET_CODE (x)); - for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) - switch (format_ptr[i]) - { - case 'e': - summarize_insn (XEXP (x, i), sum, 0); - break; - - case 'E': - for (j = XVECLEN (x, i) - 1; j >= 0; j--) - summarize_insn (XVECEXP (x, i, j), sum, 0); - break; - - case 'i': - break; - - default: - abort (); - } - } -} - -/* Ensure a sufficient number of `trapb' insns are in the code when - the user requests code with a trap precision of functions or - instructions. - - In naive mode, when the user requests a trap-precision of - "instruction", a trapb is needed after every instruction that may - generate a trap. This ensures that the code is resumption safe but - it is also slow. - - When optimizations are turned on, we delay issuing a trapb as long - as possible. In this context, a trap shadow is the sequence of - instructions that starts with a (potentially) trap generating - instruction and extends to the next trapb or call_pal instruction - (but GCC never generates call_pal by itself). We can delay (and - therefore sometimes omit) a trapb subject to the following - conditions: - - (a) On entry to the trap shadow, if any Alpha register or memory - location contains a value that is used as an operand value by some - instruction in the trap shadow (live on entry), then no instruction - in the trap shadow may modify the register or memory location. - - (b) Within the trap shadow, the computation of the base register - for a memory load or store instruction may not involve using the - result of an instruction that might generate an UNPREDICTABLE - result. - - (c) Within the trap shadow, no register may be used more than once - as a destination register. (This is to make life easier for the - trap-handler.) - - (d) The trap shadow may not include any branch instructions. */ - -static void -alpha_handle_trap_shadows (insns) - rtx insns; -{ - struct shadow_summary shadow; - int trap_pending, exception_nesting; - rtx i, n; - - trap_pending = 0; - exception_nesting = 0; - shadow.used.i = 0; - shadow.used.fp = 0; - shadow.used.mem = 0; - shadow.defd = shadow.used; - - for (i = insns; i ; i = NEXT_INSN (i)) - { - if (GET_CODE (i) == NOTE) - { - switch (NOTE_LINE_NUMBER (i)) - { - case NOTE_INSN_EH_REGION_BEG: - exception_nesting++; - if (trap_pending) - goto close_shadow; - break; - - case NOTE_INSN_EH_REGION_END: - exception_nesting--; - if (trap_pending) - goto close_shadow; - break; - - case NOTE_INSN_EPILOGUE_BEG: - if (trap_pending && alpha_tp >= ALPHA_TP_FUNC) - goto close_shadow; - break; - } - } - else if (trap_pending) - { - if (alpha_tp == ALPHA_TP_FUNC) - { - if (GET_CODE (i) == JUMP_INSN - && GET_CODE (PATTERN (i)) == RETURN) - goto close_shadow; - } - else if (alpha_tp == ALPHA_TP_INSN) - { - if (optimize > 0) - { - struct shadow_summary sum; - - sum.used.i = 0; - sum.used.fp = 0; - sum.used.mem = 0; - sum.defd = sum.used; - - switch (GET_CODE (i)) - { - case INSN: - /* Annoyingly, get_attr_trap will abort on these. */ - if (GET_CODE (PATTERN (i)) == USE - || GET_CODE (PATTERN (i)) == CLOBBER) - break; - - summarize_insn (PATTERN (i), &sum, 0); - - if ((sum.defd.i & shadow.defd.i) - || (sum.defd.fp & shadow.defd.fp)) - { - /* (c) would be violated */ - goto close_shadow; - } - - /* Combine shadow with summary of current insn: */ - shadow.used.i |= sum.used.i; - shadow.used.fp |= sum.used.fp; - shadow.used.mem |= sum.used.mem; - shadow.defd.i |= sum.defd.i; - shadow.defd.fp |= sum.defd.fp; - shadow.defd.mem |= sum.defd.mem; - - if ((sum.defd.i & shadow.used.i) - || (sum.defd.fp & shadow.used.fp) - || (sum.defd.mem & shadow.used.mem)) - { - /* (a) would be violated (also takes care of (b)) */ - if (get_attr_trap (i) == TRAP_YES - && ((sum.defd.i & sum.used.i) - || (sum.defd.fp & sum.used.fp))) - abort (); - - goto close_shadow; - } - break; - - case JUMP_INSN: - case CALL_INSN: - case CODE_LABEL: - goto close_shadow; - - default: - abort (); - } - } - else - { - close_shadow: - n = emit_insn_before (gen_trapb (), i); - PUT_MODE (n, TImode); - PUT_MODE (i, TImode); - trap_pending = 0; - shadow.used.i = 0; - shadow.used.fp = 0; - shadow.used.mem = 0; - shadow.defd = shadow.used; - } - } - } - - if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC) - && GET_CODE (i) == INSN - && GET_CODE (PATTERN (i)) != USE - && GET_CODE (PATTERN (i)) != CLOBBER - && get_attr_trap (i) == TRAP_YES) - { - if (optimize && !trap_pending) - summarize_insn (PATTERN (i), &shadow, 0); - trap_pending = 1; - } - } -} - -#ifdef HAIFA -/* Alpha can only issue instruction groups simultaneously if they are - suitibly aligned. This is very processor-specific. */ - -enum alphaev4_pipe { - EV4_STOP = 0, - EV4_IB0 = 1, - EV4_IB1 = 2, - EV4_IBX = 4 -}; - -enum alphaev5_pipe { - EV5_STOP = 0, - EV5_NONE = 1, - EV5_E01 = 2, - EV5_E0 = 4, - EV5_E1 = 8, - EV5_FAM = 16, - EV5_FA = 32, - EV5_FM = 64 -}; - -static enum alphaev4_pipe alphaev4_insn_pipe PROTO((rtx)); -static enum alphaev5_pipe alphaev5_insn_pipe PROTO((rtx)); -static rtx alphaev4_next_group PROTO((rtx, int*, int*)); -static rtx alphaev5_next_group PROTO((rtx, int*, int*)); -static rtx alphaev4_next_nop PROTO((int*)); -static rtx alphaev5_next_nop PROTO((int*)); - -static void alpha_align_insns - PROTO((rtx, int, rtx (*)(rtx, int*, int*), rtx (*)(int*), int)); - -static enum alphaev4_pipe -alphaev4_insn_pipe (insn) - rtx insn; -{ - if (recog_memoized (insn) < 0) - return EV4_STOP; - if (get_attr_length (insn) != 4) - return EV4_STOP; - - switch (get_attr_type (insn)) - { - case TYPE_ILD: - case TYPE_FLD: - return EV4_IBX; - - case TYPE_LDSYM: - case TYPE_IADD: - case TYPE_ILOG: - case TYPE_ICMOV: - case TYPE_ICMP: - case TYPE_IST: - case TYPE_FST: - case TYPE_SHIFT: - case TYPE_IMUL: - case TYPE_FBR: - return EV4_IB0; - - case TYPE_MISC: - case TYPE_IBR: - case TYPE_JSR: - case TYPE_FCPYS: - case TYPE_FCMOV: - case TYPE_FADD: - case TYPE_FDIV: - case TYPE_FMUL: - return EV4_IB1; - - default: - abort(); - } -} - -static enum alphaev5_pipe -alphaev5_insn_pipe (insn) - rtx insn; -{ - if (recog_memoized (insn) < 0) - return EV5_STOP; - if (get_attr_length (insn) != 4) - return EV5_STOP; - - switch (get_attr_type (insn)) - { - case TYPE_ILD: - case TYPE_FLD: - case TYPE_LDSYM: - case TYPE_IADD: - case TYPE_ILOG: - case TYPE_ICMOV: - case TYPE_ICMP: - return EV5_E01; - - case TYPE_IST: - case TYPE_FST: - case TYPE_SHIFT: - case TYPE_IMUL: - case TYPE_MISC: - case TYPE_MVI: - return EV5_E0; - - case TYPE_IBR: - case TYPE_JSR: - return EV5_E1; - - case TYPE_FCPYS: - return EV5_FAM; - - case TYPE_FBR: - case TYPE_FCMOV: - case TYPE_FADD: - case TYPE_FDIV: - return EV5_FA; - - case TYPE_FMUL: - return EV5_FM; - - default: - abort(); - } -} - -/* IN_USE is a mask of the slots currently filled within the insn group. - The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then - the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1. - - LEN is, of course, the length of the group in bytes. */ - -static rtx -alphaev4_next_group (insn, pin_use, plen) - rtx insn; - int *pin_use, *plen; -{ - int len, in_use; - - len = in_use = 0; - - if (GET_RTX_CLASS (GET_CODE (insn)) != 'i' - || GET_CODE (PATTERN (insn)) == CLOBBER - || GET_CODE (PATTERN (insn)) == USE) - goto next_and_done; - - while (1) - { - enum alphaev4_pipe pipe; - - pipe = alphaev4_insn_pipe (insn); - switch (pipe) - { - case EV4_STOP: - /* Force complex instructions to start new groups. */ - if (in_use) - goto done; - - /* If this is a completely unrecognized insn, its an asm. - We don't know how long it is, so record length as -1 to - signal a needed realignment. */ - if (recog_memoized (insn) < 0) - len = -1; - else - len = get_attr_length (insn); - goto next_and_done; - - case EV4_IBX: - if (in_use & EV4_IB0) - { - if (in_use & EV4_IB1) - goto done; - in_use |= EV4_IB1; - } - else - in_use |= EV4_IB0 | EV4_IBX; - break; - - case EV4_IB0: - if (in_use & EV4_IB0) - { - if (!(in_use & EV4_IBX) || (in_use & EV4_IB1)) - goto done; - in_use |= EV4_IB1; - } - in_use |= EV4_IB0; - break; - - case EV4_IB1: - if (in_use & EV4_IB1) - goto done; - in_use |= EV4_IB1; - break; - - default: - abort(); - } - len += 4; - - /* Haifa doesn't do well scheduling branches. */ - if (GET_CODE (insn) == JUMP_INSN) - goto next_and_done; - - next: - insn = next_nonnote_insn (insn); - - if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i') - goto done; - - /* Let Haifa tell us where it thinks insn group boundaries are. */ - if (GET_MODE (insn) == TImode) - goto done; - - if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE) - goto next; - } - - next_and_done: - insn = next_nonnote_insn (insn); - - done: - *plen = len; - *pin_use = in_use; - return insn; -} - -/* IN_USE is a mask of the slots currently filled within the insn group. - The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then - the insn in EV5_E0 can be swapped by the hardware into EV5_E1. - - LEN is, of course, the length of the group in bytes. */ - -static rtx -alphaev5_next_group (insn, pin_use, plen) - rtx insn; - int *pin_use, *plen; -{ - int len, in_use; - - len = in_use = 0; - - if (GET_RTX_CLASS (GET_CODE (insn)) != 'i' - || GET_CODE (PATTERN (insn)) == CLOBBER - || GET_CODE (PATTERN (insn)) == USE) - goto next_and_done; - - while (1) - { - enum alphaev5_pipe pipe; - - pipe = alphaev5_insn_pipe (insn); - switch (pipe) - { - case EV5_STOP: - /* Force complex instructions to start new groups. */ - if (in_use) - goto done; - - /* If this is a completely unrecognized insn, its an asm. - We don't know how long it is, so record length as -1 to - signal a needed realignment. */ - if (recog_memoized (insn) < 0) - len = -1; - else - len = get_attr_length (insn); - goto next_and_done; - - /* ??? Most of the places below, we would like to abort, as - it would indicate an error either in Haifa, or in the - scheduling description. Unfortunately, Haifa never - schedules the last instruction of the BB, so we don't - have an accurate TI bit to go off. */ - case EV5_E01: - if (in_use & EV5_E0) - { - if (in_use & EV5_E1) - goto done; - in_use |= EV5_E1; - } - else - in_use |= EV5_E0 | EV5_E01; - break; - - case EV5_E0: - if (in_use & EV5_E0) - { - if (!(in_use & EV5_E01) || (in_use & EV5_E1)) - goto done; - in_use |= EV5_E1; - } - in_use |= EV5_E0; - break; - - case EV5_E1: - if (in_use & EV5_E1) - goto done; - in_use |= EV5_E1; - break; - - case EV5_FAM: - if (in_use & EV5_FA) - { - if (in_use & EV5_FM) - goto done; - in_use |= EV5_FM; - } - else - in_use |= EV5_FA | EV5_FAM; - break; - - case EV5_FA: - if (in_use & EV5_FA) - goto done; - in_use |= EV5_FA; - break; - - case EV5_FM: - if (in_use & EV5_FM) - goto done; - in_use |= EV5_FM; - break; - - case EV5_NONE: - break; - - default: - abort(); - } - len += 4; - - /* Haifa doesn't do well scheduling branches. */ - /* ??? If this is predicted not-taken, slotting continues, except - that no more IBR, FBR, or JSR insns may be slotted. */ - if (GET_CODE (insn) == JUMP_INSN) - goto next_and_done; - - next: - insn = next_nonnote_insn (insn); - - if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i') - goto done; - - /* Let Haifa tell us where it thinks insn group boundaries are. */ - if (GET_MODE (insn) == TImode) - goto done; - - if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE) - goto next; - } - - next_and_done: - insn = next_nonnote_insn (insn); - - done: - *plen = len; - *pin_use = in_use; - return insn; -} - -static rtx -alphaev4_next_nop (pin_use) - int *pin_use; -{ - int in_use = *pin_use; - rtx nop; - - if (!(in_use & EV4_IB0)) - { - in_use |= EV4_IB0; - nop = gen_nop (); - } - else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX) - { - in_use |= EV4_IB1; - nop = gen_nop (); - } - else if (TARGET_FP && !(in_use & EV4_IB1)) - { - in_use |= EV4_IB1; - nop = gen_fnop (); - } - else - nop = gen_unop (); - - *pin_use = in_use; - return nop; -} - -static rtx -alphaev5_next_nop (pin_use) - int *pin_use; -{ - int in_use = *pin_use; - rtx nop; - - if (!(in_use & EV5_E1)) - { - in_use |= EV5_E1; - nop = gen_nop (); - } - else if (TARGET_FP && !(in_use & EV5_FA)) - { - in_use |= EV5_FA; - nop = gen_fnop (); - } - else if (TARGET_FP && !(in_use & EV5_FM)) - { - in_use |= EV5_FM; - nop = gen_fnop (); - } - else - nop = gen_unop (); - - *pin_use = in_use; - return nop; -} - -/* The instruction group alignment main loop. */ - -static void -alpha_align_insns (insns, max_align, next_group, next_nop, gp_in_use) - rtx insns; - int max_align; - rtx (*next_group) PROTO((rtx, int*, int*)); - rtx (*next_nop) PROTO((int*)); - int gp_in_use; -{ - /* ALIGN is the known alignment for the insn group. */ - int align; - /* OFS is the offset of the current insn in the insn group. */ - int ofs; - int prev_in_use, in_use, len; - rtx i, next; - - /* Let shorten branches care for assigning alignments to code labels. */ - shorten_branches (insns); - - align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < max_align - ? FUNCTION_BOUNDARY/BITS_PER_UNIT : max_align); - - /* Account for the initial GP load, which happens before the scheduled - prologue we emitted as RTL. */ - ofs = prev_in_use = 0; - if (alpha_does_function_need_gp()) - { - ofs = 8 & (align - 1); - prev_in_use = gp_in_use; - } - - i = insns; - if (GET_CODE (i) == NOTE) - i = next_nonnote_insn (i); - - while (i) - { - next = (*next_group)(i, &in_use, &len); - - /* When we see a label, resync alignment etc. */ - if (GET_CODE (i) == CODE_LABEL) - { - int new_align = 1 << label_to_alignment (i); - if (new_align >= align) - { - align = new_align < max_align ? new_align : max_align; - ofs = 0; - } - else if (ofs & (new_align-1)) - ofs = (ofs | (new_align-1)) + 1; - if (len != 0) - abort(); - } - - /* Handle complex instructions special. */ - else if (in_use == 0) - { - /* Asms will have length < 0. This is a signal that we have - lost alignment knowledge. Assume, however, that the asm - will not mis-align instructions. */ - if (len < 0) - { - ofs = 0; - align = 4; - len = 0; - } - } - - /* If the known alignment is smaller than the recognized insn group, - realign the output. */ - else if (align < len) - { - int new_log_align = len > 8 ? 4 : 3; - rtx where; - - where = prev_nonnote_insn (i); - if (!where || GET_CODE (where) != CODE_LABEL) - where = i; - - emit_insn_before (gen_realign (GEN_INT (new_log_align)), where); - align = 1 << new_log_align; - ofs = 0; - } - - /* If the group won't fit in the same INT16 as the previous, - we need to add padding to keep the group together. Rather - than simply leaving the insn filling to the assembler, we - can make use of the knowledge of what sorts of instructions - were issued in the previous group to make sure that all of - the added nops are really free. */ - else if (ofs + len > align) - { - int nop_count = (align - ofs) / 4; - rtx where; - - /* Insert nops before labels and branches to truely merge the - execution of the nops with the previous instruction group. */ - where = prev_nonnote_insn (i); - if (where) - { - if (GET_CODE (where) == CODE_LABEL) - { - rtx where2 = prev_nonnote_insn (where); - if (where2 && GET_CODE (where2) == JUMP_INSN) - where = where2; - } - else if (GET_CODE (where) != JUMP_INSN) - where = i; - } - else - where = i; - - do - emit_insn_before ((*next_nop)(&prev_in_use), where); - while (--nop_count); - ofs = 0; - } - - ofs = (ofs + len) & (align - 1); - prev_in_use = in_use; - i = next; - } -} -#endif /* HAIFA */ - -/* Machine dependant reorg pass. */ - -void -alpha_reorg (insns) - rtx insns; -{ - if (alpha_tp != ALPHA_TP_PROG || flag_exceptions) - alpha_handle_trap_shadows (insns); - -#ifdef HAIFA - /* Due to the number of extra trapb insns, don't bother fixing up - alignment when trap precision is instruction. Moreover, we can - only do our job when sched2 is run and Haifa is our scheduler. */ - if (optimize && !optimize_size - && alpha_tp != ALPHA_TP_INSN - && flag_schedule_insns_after_reload) - { - if (alpha_cpu == PROCESSOR_EV4) - alpha_align_insns (insns, 8, alphaev4_next_group, - alphaev4_next_nop, EV4_IB0); - else if (alpha_cpu == PROCESSOR_EV5) - alpha_align_insns (insns, 16, alphaev5_next_group, - alphaev5_next_nop, EV5_E01 | EV5_E0); - } -#endif -} - - -/* Check a floating-point value for validity for a particular machine mode. */ - -static char * const float_strings[] = -{ - /* These are for FLOAT_VAX. */ - "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */ - "-1.70141173319264430e+38", - "2.93873587705571877e-39", /* 2^-128 */ - "-2.93873587705571877e-39", - /* These are for the default broken IEEE mode, which traps - on infinity or denormal numbers. */ - "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */ - "-3.402823466385288598117e+38", - "1.1754943508222875079687e-38", /* 2^-126 */ - "-1.1754943508222875079687e-38", -}; - -static REAL_VALUE_TYPE float_values[8]; -static int inited_float_values = 0; - -int -check_float_value (mode, d, overflow) - enum machine_mode mode; - REAL_VALUE_TYPE *d; - int overflow ATTRIBUTE_UNUSED; -{ - - if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT) - return 0; - - if (inited_float_values == 0) - { - int i; - for (i = 0; i < 8; i++) - float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode); - - inited_float_values = 1; - } - - if (mode == SFmode) - { - REAL_VALUE_TYPE r; - REAL_VALUE_TYPE *fvptr; - - if (TARGET_FLOAT_VAX) - fvptr = &float_values[0]; - else - fvptr = &float_values[4]; - - bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE)); - if (REAL_VALUES_LESS (fvptr[0], r)) - { - bcopy ((char *) &fvptr[0], (char *) d, - sizeof (REAL_VALUE_TYPE)); - return 1; - } - else if (REAL_VALUES_LESS (r, fvptr[1])) - { - bcopy ((char *) &fvptr[1], (char *) d, - sizeof (REAL_VALUE_TYPE)); - return 1; - } - else if (REAL_VALUES_LESS (dconst0, r) - && REAL_VALUES_LESS (r, fvptr[2])) - { - bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE)); - return 1; - } - else if (REAL_VALUES_LESS (r, dconst0) - && REAL_VALUES_LESS (fvptr[3], r)) - { - bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE)); - return 1; - } - } - - return 0; -} - -#if OPEN_VMS - -/* Return the VMS argument type corresponding to MODE. */ - -enum avms_arg_type -alpha_arg_type (mode) - enum machine_mode mode; -{ - switch (mode) - { - case SFmode: - return TARGET_FLOAT_VAX ? FF : FS; - case DFmode: - return TARGET_FLOAT_VAX ? FD : FT; - default: - return I64; - } -} - -/* Return an rtx for an integer representing the VMS Argument Information - register value. */ - -struct rtx_def * -alpha_arg_info_reg_val (cum) - CUMULATIVE_ARGS cum; -{ - unsigned HOST_WIDE_INT regval = cum.num_args; - int i; - - for (i = 0; i < 6; i++) - regval |= ((int) cum.atypes[i]) << (i * 3 + 8); - - return GEN_INT (regval); -} - -/* Structure to collect function names for final output - in link section. */ - -enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN}; - - -struct alpha_links { - struct alpha_links *next; - char *name; - enum links_kind kind; -}; - -static struct alpha_links *alpha_links_base = 0; - -/* 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. */ - -void -alpha_need_linkage (name, is_local) - char *name; - int is_local; -{ - rtx x; - struct alpha_links *lptr, *nptr; - - if (name[0] == '*') - name++; - - /* Is this name already defined ? */ - - for (lptr = alpha_links_base; lptr; lptr = lptr->next) - if (strcmp (lptr->name, name) == 0) - { - if (is_local) - { - /* Defined here but external assumed. */ - if (lptr->kind == KIND_EXTERN) - lptr->kind = KIND_LOCAL; - } - else - { - /* Used here but unused assumed. */ - if (lptr->kind == KIND_UNUSED) - lptr->kind = KIND_LOCAL; - } - return; - } - - nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links)); - nptr->next = alpha_links_base; - nptr->name = xstrdup (name); - - /* Assume external if no definition. */ - nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN); - - /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */ - get_identifier (name); - - alpha_links_base = nptr; - - return; -} - - -void -alpha_write_linkage (stream) - FILE *stream; -{ - struct alpha_links *lptr, *nptr; - - readonly_section (); - - fprintf (stream, "\t.align 3\n"); - - for (lptr = alpha_links_base; lptr; lptr = nptr) - { - nptr = lptr->next; - - if (lptr->kind == KIND_UNUSED - || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name))) - continue; - - fprintf (stream, "$%s..lk:\n", lptr->name); - if (lptr->kind == KIND_LOCAL) - { - /* Local and used, build linkage pair. */ - fprintf (stream, "\t.quad %s..en\n", lptr->name); - fprintf (stream, "\t.quad %s\n", lptr->name); - } - else - /* External and used, request linkage pair. */ - fprintf (stream, "\t.linkage %s\n", lptr->name); - } -} - -#else - -void -alpha_need_linkage (name, is_local) - char *name ATTRIBUTE_UNUSED; - int is_local ATTRIBUTE_UNUSED; -{ -} - -#endif /* OPEN_VMS */ diff --git a/contrib/gcc/config/alpha/alpha.h b/contrib/gcc/config/alpha/alpha.h deleted file mode 100644 index e9c3f6d2f684..000000000000 --- a/contrib/gcc/config/alpha/alpha.h +++ /dev/null @@ -1,2550 +0,0 @@ -/* Definitions of target machine for GNU compiler, for DEC Alpha. - Copyright (C) 1992, 93-98, 1999 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, -Boston, MA 02111-1307, USA. */ - - -/* 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 }}}}}}\ -%{mieee:-D_IEEE_FP }\ -%{mieee-with-inexact:-D_IEEE_FP -D_IEEE_FP_INEXACT }}\ -%(cpp_cpu) %(cpp_subtarget)" - -#ifndef CPP_SUBTARGET_SPEC -#define CPP_SUBTARGET_SPEC "" -#endif - -/* Set the spec to use for signed char. The default tests the above macro - but DEC's compiler can't handle the conditional in a "constant" - operand. */ - -#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")) - -/* Print subsidiary information on the compiler version in use. */ -#define TARGET_VERSION - -/* Run-time compilation parameters selecting different hardware subsets. */ - -/* Which processor to schedule for. The cpu attribute defines a list that - mirrors this list, so changes to alpha.md must be made at the same time. */ - -enum processor_type - {PROCESSOR_EV4, /* 2106[46]{a,} */ - PROCESSOR_EV5, /* 21164{a,pc,} */ - PROCESSOR_EV6}; /* 21264 */ - -extern enum processor_type alpha_cpu; - -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. */ -}; - -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_DYN /* Dynamic rounding mode. */ -}; - -enum alpha_fp_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 */ -}; - -extern int target_flags; - -extern enum alpha_trap_precision alpha_tp; -extern enum alpha_fp_rounding_mode alpha_fprm; -extern enum alpha_fp_trap_mode alpha_fptm; - -/* This means that floating-point support exists in the target implementation - of the Alpha architecture. This is usually the default. */ -#define MASK_FP (1 << 0) -#define TARGET_FP (target_flags & MASK_FP) - -/* This means that floating-point registers are allowed to be used. Note - that Alpha implementations without FP operations are required to - provide the FP registers. */ - -#define MASK_FPREGS (1 << 1) -#define TARGET_FPREGS (target_flags & MASK_FPREGS) - -/* This means that gas is used to process the assembler file. */ - -#define MASK_GAS (1 << 2) -#define TARGET_GAS (target_flags & MASK_GAS) - -/* This means that we should mark procedures as IEEE conformant. */ - -#define MASK_IEEE_CONFORMANT (1 << 3) -#define TARGET_IEEE_CONFORMANT (target_flags & MASK_IEEE_CONFORMANT) - -/* This means we should be IEEE-compliant except for inexact. */ - -#define MASK_IEEE (1 << 4) -#define TARGET_IEEE (target_flags & MASK_IEEE) - -/* This means we should be fully IEEE-compliant. */ - -#define MASK_IEEE_WITH_INEXACT (1 << 5) -#define TARGET_IEEE_WITH_INEXACT (target_flags & MASK_IEEE_WITH_INEXACT) - -/* This means we must construct all constants rather than emitting - them as literal data. */ - -#define MASK_BUILD_CONSTANTS (1 << 6) -#define TARGET_BUILD_CONSTANTS (target_flags & MASK_BUILD_CONSTANTS) - -/* This means we handle floating points in VAX F- (float) - or G- (double) Format. */ - -#define MASK_FLOAT_VAX (1 << 7) -#define TARGET_FLOAT_VAX (target_flags & MASK_FLOAT_VAX) - -/* This means that the processor has byte and half word loads and stores - (the BWX extension). */ - -#define MASK_BWX (1 << 8) -#define TARGET_BWX (target_flags & MASK_BWX) - -/* This means that the processor has the MAX extension. */ -#define MASK_MAX (1 << 9) -#define TARGET_MAX (target_flags & MASK_MAX) - -/* This means that the processor has the FIX extension. */ -#define MASK_FIX (1 << 10) -#define TARGET_FIX (target_flags & MASK_FIX) - -/* This means that the processor has the CIX extension. */ -#define MASK_CIX (1 << 11) -#define TARGET_CIX (target_flags & MASK_CIX) - -/* This means that the processor is an EV5, EV56, or PCA56. This is defined - only in TARGET_CPU_DEFAULT. */ -#define MASK_CPU_EV5 (1 << 28) - -/* Likewise for EV6. */ -#define MASK_CPU_EV6 (1 << 29) - -/* This means we support the .arch directive in the assembler. Only - defined in TARGET_CPU_DEFAULT. */ -#define MASK_SUPPORT_ARCH (1 << 30) -#define TARGET_SUPPORT_ARCH (target_flags & MASK_SUPPORT_ARCH) - -/* These are for target os support and cannot be changed at runtime. */ -#ifndef TARGET_WINDOWS_NT -#define TARGET_WINDOWS_NT 0 -#endif -#ifndef TARGET_OPEN_VMS -#define TARGET_OPEN_VMS 0 -#endif - -#ifndef TARGET_AS_CAN_SUBTRACT_LABELS -#define TARGET_AS_CAN_SUBTRACT_LABELS TARGET_GAS -#endif -#ifndef TARGET_CAN_FAULT_IN_PROLOGUE -#define TARGET_CAN_FAULT_IN_PROLOGUE 0 -#endif - -/* Macro to define tables used to set the flags. - This is a list in braces of pairs in braces, - each pair being { "NAME", VALUE } - where VALUE is the bits to set or minus the bits to clear. - An empty string NAME is used to identify the default VALUE. */ - -#define TARGET_SWITCHES \ - { {"no-soft-float", MASK_FP, "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"}, \ - {"ieee-conformant", MASK_IEEE_CONFORMANT, \ - "Request IEEE-conformant math library routines (OSF/1)"}, \ - {"ieee", MASK_IEEE|MASK_IEEE_CONFORMANT, \ - "Emit IEEE-conformant code, without inexact exceptions"}, \ - {"ieee-with-inexact", MASK_IEEE_WITH_INEXACT|MASK_IEEE_CONFORMANT, \ - "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"}, \ - {"no-bwx", -MASK_BWX, ""}, \ - {"max", MASK_MAX, "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"}, \ - {"no-fix", -MASK_FIX, ""}, \ - {"cix", MASK_CIX, "Emit code for the counting ISA extension"}, \ - {"no-cix", -MASK_CIX, ""}, \ - {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT, ""} } - -#define TARGET_DEFAULT MASK_FP|MASK_FPREGS - -#ifndef TARGET_CPU_DEFAULT -#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 } } */ - -extern const char *alpha_cpu_string; /* For -mcpu= */ -extern const char *alpha_fprm_string; /* For -mfp-rounding-mode=[n|m|c|d] */ -extern const char *alpha_fptm_string; /* For -mfp-trap-mode=[n|u|su|sui] */ -extern const char *alpha_tp_string; /* For -mtrap-precision=[p|f|i] */ -extern const char *alpha_mlat_string; /* For -mmemory-latency= */ - -#define TARGET_OPTIONS \ -{ \ - {"cpu=", &alpha_cpu_string, \ - "Generate code for a given CPU"}, \ - {"fp-rounding-mode=", &alpha_fprm_string, \ - "Control the generated fp rounding mode"}, \ - {"fp-trap-mode=", &alpha_fptm_string, \ - "Control the IEEE trap mode"}, \ - {"trap-precision=", &alpha_tp_string, \ - "Control the precision given to fp exceptions"}, \ - {"memory-latency=", &alpha_mlat_string, \ - "Tune expected memory latency"}, \ -} - -/* Attempt to describe CPU characteristics to the preprocessor. */ - -/* Corresponding to amask... */ -#define CPP_AM_BWX_SPEC "-D__alpha_bwx__ -Acpu(bwx)" -#define CPP_AM_MAX_SPEC "-D__alpha_max__ -Acpu(max)" -#define CPP_AM_FIX_SPEC "-D__alpha_fix__ -Acpu(fix)" -#define CPP_AM_CIX_SPEC "-D__alpha_cix__ -Acpu(cix)" - -/* Corresponding to implver... */ -#define CPP_IM_EV4_SPEC "-D__alpha_ev4__ -Acpu(ev4)" -#define CPP_IM_EV5_SPEC "-D__alpha_ev5__ -Acpu(ev5)" -#define CPP_IM_EV6_SPEC "-D__alpha_ev6__ -Acpu(ev6)" - -/* Common combinations. */ -#define CPP_CPU_EV4_SPEC "%(cpp_im_ev4)" -#define CPP_CPU_EV5_SPEC "%(cpp_im_ev5)" -#define CPP_CPU_EV56_SPEC "%(cpp_im_ev5) %(cpp_am_bwx)" -#define CPP_CPU_PCA56_SPEC "%(cpp_im_ev5) %(cpp_am_bwx) %(cpp_am_max)" -#define CPP_CPU_EV6_SPEC "%(cpp_im_ev6) %(cpp_am_bwx) %(cpp_am_max) %(cpp_am_fix)" - -#ifndef CPP_CPU_DEFAULT_SPEC -# if TARGET_CPU_DEFAULT & MASK_CPU_EV6 -# define CPP_CPU_DEFAULT_SPEC CPP_CPU_EV6_SPEC -# else -# if TARGET_CPU_DEFAULT & MASK_CPU_EV5 -# if TARGET_CPU_DEFAULT & MASK_MAX -# define CPP_CPU_DEFAULT_SPEC CPP_CPU_PCA56_SPEC -# else -# if TARGET_CPU_DEFAULT & MASK_BWX -# define CPP_CPU_DEFAULT_SPEC CPP_CPU_EV56_SPEC -# else -# define CPP_CPU_DEFAULT_SPEC CPP_CPU_EV5_SPEC -# endif -# endif -# else -# define CPP_CPU_DEFAULT_SPEC CPP_CPU_EV4_SPEC -# endif -# endif -#endif /* CPP_CPU_DEFAULT_SPEC */ - -#ifndef CPP_CPU_SPEC -#define CPP_CPU_SPEC "\ -%{!undef:-Acpu(alpha) -Amachine(alpha) -D__alpha -D__alpha__ \ -%{mcpu=ev4|mcpu=21064:%(cpp_cpu_ev4) }\ -%{mcpu=ev5|mcpu=21164:%(cpp_cpu_ev5) }\ -%{mcpu=ev56|mcpu=21164a:%(cpp_cpu_ev56) }\ -%{mcpu=pca56|mcpu=21164pc|mcpu=21164PC:%(cpp_cpu_pca56) }\ -%{mcpu=ev6|mcpu=21264:%(cpp_cpu_ev6) }\ -%{!mcpu*:%(cpp_cpu_default) }}" -#endif - -/* This macro defines names of additional specifications to put in the - specs that can be used in various specifications like CC1_SPEC. Its - definition is an initializer with a subgrouping for each command option. - - Each subgrouping contains a string constant, that defines the - specification name, and a string constant that used by the GNU CC driver - program. - - Do not define this macro if it does not need to do anything. */ - -#ifndef SUBTARGET_EXTRA_SPECS -#define SUBTARGET_EXTRA_SPECS -#endif - -#define EXTRA_SPECS \ - { "cpp_am_bwx", CPP_AM_BWX_SPEC }, \ - { "cpp_am_max", CPP_AM_MAX_SPEC }, \ - { "cpp_am_fix", CPP_AM_FIX_SPEC }, \ - { "cpp_am_cix", CPP_AM_CIX_SPEC }, \ - { "cpp_im_ev4", CPP_IM_EV4_SPEC }, \ - { "cpp_im_ev5", CPP_IM_EV5_SPEC }, \ - { "cpp_im_ev6", CPP_IM_EV6_SPEC }, \ - { "cpp_cpu_ev4", CPP_CPU_EV4_SPEC }, \ - { "cpp_cpu_ev5", CPP_CPU_EV5_SPEC }, \ - { "cpp_cpu_ev56", CPP_CPU_EV56_SPEC }, \ - { "cpp_cpu_pca56", CPP_CPU_PCA56_SPEC }, \ - { "cpp_cpu_ev6", CPP_CPU_EV6_SPEC }, \ - { "cpp_cpu_default", CPP_CPU_DEFAULT_SPEC }, \ - { "cpp_cpu", CPP_CPU_SPEC }, \ - { "cpp_subtarget", CPP_SUBTARGET_SPEC }, \ - SUBTARGET_EXTRA_SPECS - - -/* Sometimes certain combinations of command options do not make sense - on a particular target machine. You can define a macro - `OVERRIDE_OPTIONS' to take account of this. This macro, if - defined, is executed once just after all the command options have - been parsed. - - On the Alpha, it is used to translate target-option strings into - numeric values. */ - -extern void override_options (); -#define OVERRIDE_OPTIONS override_options () - - -/* Define this macro to change register usage conditional on target flags. - - 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; - -/* 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 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 - -/* Define the size of `long long'. The default is the twice the word size. */ -#define LONG_LONG_TYPE_SIZE 64 - -/* The two floating-point formats we support are S-floating, which is - 4 bytes, and T-floating, which is 8 bytes. `float' is S and `double' - and `long double' are T. */ - -#define FLOAT_TYPE_SIZE 32 -#define DOUBLE_TYPE_SIZE 64 -#define LONG_DOUBLE_TYPE_SIZE 64 - -#define WCHAR_TYPE "unsigned int" -#define WCHAR_TYPE_SIZE 32 - -/* Define this macro if it is advisable to hold scalars in registers - in a wider mode than that declared by the program. In such cases, - the value is constrained to be within the bounds of the declared - type, but kept valid in the wider mode. The signedness of the - extension may differ from that of the type. - - For Alpha, we always store objects in a full register. 32-bit objects - are always sign-extended, but smaller objects retain their signedness. */ - -#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \ - if (GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ - { \ - if ((MODE) == SImode) \ - (UNSIGNEDP) = 0; \ - (MODE) = DImode; \ - } - -/* Define this if function arguments should also be promoted using the above - procedure. */ - -#define PROMOTE_FUNCTION_ARGS - -/* Likewise, if the function return value is promoted. */ - -#define PROMOTE_FUNCTION_RETURN - -/* Define this if most significant bit is lowest numbered - in instructions that operate on numbered bit-fields. - - There are no such instructions on the Alpha, but the documentation - is little endian. */ -#define BITS_BIG_ENDIAN 0 - -/* Define this if most significant byte of a word is the lowest numbered. - This is false on the Alpha. */ -#define BYTES_BIG_ENDIAN 0 - -/* Define this if most significant word of a multiword number is lowest - numbered. - - For Alpha we can decide arbitrarily since there are no machine instructions - for them. Might as well be consistent with bytes. */ -#define WORDS_BIG_ENDIAN 0 - -/* number of bits in an addressable storage unit */ -#define BITS_PER_UNIT 8 - -/* Width in bits of a "word", which is the contents of a machine register. - Note that this is not necessarily the width of data type `int'; - if using 16-bit ints on a 68000, this would still be 32. - But on a machine with 16-bit registers, this would be 16. */ -#define BITS_PER_WORD 64 - -/* Width of a word, in units (bytes). */ -#define UNITS_PER_WORD 8 - -/* Width in bits of a pointer. - See also the macro `Pmode' defined below. */ -#define POINTER_SIZE 64 - -/* Allocation boundary (in *bits*) for storing arguments in argument list. */ -#define PARM_BOUNDARY 64 - -/* Boundary (in *bits*) on which stack pointer should be aligned. */ -#define STACK_BOUNDARY 64 - -/* Allocation boundary (in *bits*) for the code of a function. */ -#define FUNCTION_BOUNDARY 256 - -/* Alignment of field after `int : 0' in a structure. */ -#define EMPTY_FIELD_BOUNDARY 64 - -/* Every structure's size must be a multiple of this. */ -#define STRUCTURE_SIZE_BOUNDARY 8 - -/* 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 - -/* 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) - -/* Align all constants and variables to at least a word boundary so - we can pick up pieces of them faster. */ -/* ??? Only if block-move stuff knows about different source/destination - alignment. */ -#if 0 -#define CONSTANT_ALIGNMENT(EXP, ALIGN) MAX ((ALIGN), BITS_PER_WORD) -#define DATA_ALIGNMENT(EXP, ALIGN) MAX ((ALIGN), BITS_PER_WORD) -#endif - -/* Set this non-zero if move instructions will actually fail to work - when given unaligned data. - - Since we get an error message when we do one, call them invalid. */ - -#define STRICT_ALIGNMENT 1 - -/* Set this non-zero if unaligned move instructions are extremely slow. - - On the Alpha, they trap. */ - -#define SLOW_UNALIGNED_ACCESS 1 - -/* Standard register usage. */ - -/* Number of actual hardware registers. - The hardware registers are assigned numbers for the compiler - from 0 to just below FIRST_PSEUDO_REGISTER. - All registers that the compiler knows about must be given numbers, - even those that are not normally considered general registers. - - We define all 32 integer registers, even though $31 is always zero, - and all 32 floating-point registers, even though $f31 is also - always zero. We do not bother defining the FP status register and - there are no other registers. - - Since $31 is always zero, we will use register number 31 as the - argument pointer. It will never appear in the generated code - because we will always be eliminating it in favor of the stack - pointer or hardware frame pointer. - - Likewise, we use $f31 for the frame pointer, which will always - be eliminated in favor of the hardware frame pointer or the - stack pointer. */ - -#define FIRST_PSEUDO_REGISTER 64 - -/* 1 for registers that have pervasive standard uses - and are not available for the register allocator. */ - -#define FIXED_REGISTERS \ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } - -/* 1 for registers not available across function calls. - These must include the FIXED_REGISTERS and also any - registers that can be used without being saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - Aside from that, you can include as many other registers as you like. */ -#define CALL_USED_REGISTERS \ - {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, \ - 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: - $f10-$f15 (nonsaved floating-point register) - $f22-$f30 (likewise) - $f21-$f16 (likewise, but input args) - $f0 (nonsaved, but return value) - $f1 (nonsaved, but immediate before saved) - $f2-$f9 (saved floating-point registers) - $1-$8 (nonsaved integer registers) - $22-$25 (likewise) - $28 (likewise) - $0 (likewise, but return value) - $21-$16 (likewise, but input args) - $27 (procedure value in OSF, nonsaved in NT) - $9-$14 (saved integer registers) - $26 (return PC) - $15 (frame pointer) - $29 (global pointer) - $30, $31, $f31 (stack pointer and always zero/ap & fp) */ - -#define REG_ALLOC_ORDER \ - {42, 43, 44, 45, 46, 47, \ - 54, 55, 56, 57, 58, 59, 60, 61, 62, \ - 53, 52, 51, 50, 49, 48, \ - 32, 33, \ - 34, 35, 36, 37, 38, 39, 40, 41, \ - 1, 2, 3, 4, 5, 6, 7, 8, \ - 22, 23, 24, 25, \ - 28, \ - 0, \ - 21, 20, 19, 18, 17, 16, \ - 27, \ - 9, 10, 11, 12, 13, 14, \ - 26, \ - 15, \ - 29, \ - 30, 31, 63 } - -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. - This is ordinarily the length in words of a value of mode MODE - but can be less for certain modes in special long registers. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - -/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. - On Alpha, the integer registers can hold any mode. The floating-point - registers can hold 32-bit and 64-bit integers as well, but not 16-bit - or 8-bit values. */ - -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - ((REGNO) >= 32 && (REGNO) <= 62 \ - ? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4 \ - : 1) - -/* A C expression that is nonzero if a value of mode - MODE1 is accessible in mode MODE2 without copying. - - This asymmetric test is true when MODE1 could be put - in an FP register but MODE2 could not. */ - -#define MODES_TIEABLE_P(MODE1, MODE2) \ - (HARD_REGNO_MODE_OK (32, (MODE1)) \ - ? HARD_REGNO_MODE_OK (32, (MODE2)) \ - : 1) - -/* Specify the registers used for certain standard purposes. - The values of these macros are register numbers. */ - -/* Alpha pc isn't overloaded on a register that the compiler knows about. */ -/* #define PC_REGNUM */ - -/* Register to use for pushing function arguments. */ -#define STACK_POINTER_REGNUM 30 - -/* Base register for access to local variables of the function. */ -#define HARD_FRAME_POINTER_REGNUM 15 - -/* Value should be nonzero if functions must have frame pointers. - Zero means the frame pointer need not be set up (and parms - may be accessed via the stack pointer) in functions that seem suitable. - This is computed in `reload', in reload1.c. */ -#define FRAME_POINTER_REQUIRED 0 - -/* Base register for access to arguments of the function. */ -#define ARG_POINTER_REGNUM 31 - -/* Base register for access to local variables of function. */ -#define FRAME_POINTER_REGNUM 63 - -/* Register in which static-chain is passed to a function. - - For the Alpha, this is based on an example; the calling sequence - doesn't seem to specify this. */ -#define STATIC_CHAIN_REGNUM 1 - -/* Register in which address to store a structure value - arrives in the function. On the Alpha, the address is passed - as a hidden argument. */ -#define STRUCT_VALUE 0 - -/* Define the classes of registers for register constraints in the - machine description. Also define ranges of constants. - - One of the classes must always be named ALL_REGS and include all hard regs. - If there is more than one class, another class must be named NO_REGS - and contain no registers. - - The name GENERAL_REGS must be the name of a class (or an alias for - another name such as ALL_REGS). This is the class of registers - that is allowed by "g" or "r" in a register constraint. - Also, registers outside this class are allocated only when - instructions express preferences for them. - - The classes must be numbered in nondecreasing order; that is, - a larger-numbered class must never be contained completely - in a smaller-numbered class. - - 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 }; - -#define N_REG_CLASSES (int) LIM_REG_CLASSES - -/* Give names of register classes as strings for dump file. */ - -#define REG_CLASS_NAMES \ - {"NO_REGS", "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} } - -/* 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) - -/* The class value for index registers, and the one for base regs. */ -#define INDEX_REG_CLASS NO_REGS -#define BASE_REG_CLASS GENERAL_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) - -/* Define this macro to change register usage conditional on target flags. */ -/* #define CONDITIONAL_REGISTER_USAGE */ - -/* The letters I, J, K, L, M, N, O, and P in a register constraint string - can be used to stand for particular ranges of immediate operands. - This macro defines what the ranges are. - C is the letter, and VALUE is a constant value. - Return 1 if VALUE is in the range specified by C. - - For Alpha: - `I' is used for the range of constants most insns can contain. - `J' is the constant zero. - `K' is used for the constant in an LDA insn. - `L' is used for the constant in a LDAH insn. - `M' is used for the constants that can be AND'ed with using a ZAP insn. - `N' is used for complemented 8-bit constants. - `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) - -/* Similar, but for floating or large integer constants, and defining letters - G and H. Here VALUE is the CONST_DOUBLE rtx itself. - - 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) - -/* Optional extra constraints for this machine. - - For the Alpha, `Q' means that this is a memory operand but not a - reference to an unaligned location. - - `R' is a SYMBOL_REF that has SYMBOL_REF_FLAG set or is the current - function. - - 'S' is a 6-bit constant (valid for a shift insn). */ - -#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 (); - -/* 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. */ - -#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)) - -/* 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) - -/* 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)) - -/* Specify the mode to be used for memory when a secondary memory - location is needed. If MODE is floating-point, use it. Otherwise, - widen to a word like the default. This is needed because we always - store integers in FP registers in quadword format. This whole - area is very tricky! */ -#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ - (GET_MODE_CLASS (MODE) == MODE_FLOAT ? (MODE) \ - : GET_MODE_SIZE (MODE) >= 4 ? (MODE) \ - : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0)) - -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ - -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((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. */ - -#define CLASS_CANNOT_CHANGE_SIZE FLOAT_REGS - -/* Define the cost of moving between registers of various classes. Moving - between FLOAT_REGS and anything else except float regs is expensive. - In fact, we make it quite expensive because we really don't want to - do these moves unless it is clearly worth it. Optimizations may - reduce the impact of not being able to allocate a pseudo to a - hard register. */ - -#define REGISTER_MOVE_COST(CLASS1, CLASS2) \ - (((CLASS1) == FLOAT_REGS) == ((CLASS2) == FLOAT_REGS) \ - ? 2 \ - : TARGET_FIX ? 3 : 4+2*alpha_memory_latency) - -/* A C expressions returning the cost of moving data of MODE from a register to - or from memory. - - On the Alpha, bump this up a bit. */ - -extern int alpha_memory_latency; -#define MEMORY_MOVE_COST(MODE,CLASS,IN) (2*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. */ - -/* Define this if pushing a word on the stack - makes the stack pointer a smaller address. */ -#define STACK_GROWS_DOWNWARD - -/* Define this if the nominal address of the stack frame - is at the high-address end of the local variables; - that is, each additional local variable allocated - goes at a more negative offset in the frame. */ -/* #define FRAME_GROWS_DOWNWARD */ - -/* Offset within stack frame to start allocating local variables at. - If FRAME_GROWS_DOWNWARD, this is the offset to the END of the - first local allocated. Otherwise, it is the offset to the BEGINNING - of the first local allocated. */ - -#define STARTING_FRAME_OFFSET 0 - -/* If we generate an insn to push BYTES bytes, - this says how many the stack pointer really advances by. - On Alpha, don't define this because there are no push insns. */ -/* #define PUSH_ROUNDING(BYTES) */ - -/* Define this to be nonzero if stack checking is built into the ABI. */ -#define STACK_CHECK_BUILTIN 1 - -/* 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 - -/* Offset of first parameter from the argument pointer register value. */ - -#define FIRST_PARM_OFFSET(FNDECL) 0 - -/* Definitions for register eliminations. - - 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. */ - -/* This is an array of structures. Each structure initializes one pair - of eliminable registers. The "from" register number is given first, - followed by "to". Eliminations of the same "from" register are listed - in order of preference. */ - -#define ELIMINABLE_REGS \ -{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ - { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} - -/* Given FROM and TO register numbers, say whether this elimination is allowed. - Frame pointer elimination is automatically handled. - - All eliminations are valid since the cases where FP can't be - eliminated are already handled. */ - -#define CAN_ELIMINATE(FROM, TO) 1 - -/* Round up to a multiple of 16 bytes. */ -#define ALPHA_ROUND(X) (((X) + 15) & ~ 15) - -/* Define the offset between two registers, one to be eliminated, and the other - its replacement, at the start of a routine. */ -#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ -{ if ((FROM) == FRAME_POINTER_REGNUM) \ - (OFFSET) = (ALPHA_ROUND (current_function_outgoing_args_size) \ - + alpha_sa_size ()); \ - else if ((FROM) == ARG_POINTER_REGNUM) \ - (OFFSET) = (ALPHA_ROUND (current_function_outgoing_args_size) \ - + alpha_sa_size () \ - + (ALPHA_ROUND (get_frame_size () \ - + current_function_pretend_args_size) \ - - current_function_pretend_args_size)); \ -} - -/* Define this if stack space is still allocated for a parameter passed - in a register. */ -/* #define REG_PARM_STACK_SPACE */ - -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - -/* Define how to find the value returned by a function. - VALTYPE is the data type of the value (as a tree). - If the precise function being called is known, FUNC is its FUNCTION_DECL; - otherwise, FUNC is 0. - - On Alpha the value is found in $0 for integer functions and - $f0 for floating-point functions. */ - -#define FUNCTION_VALUE(VALTYPE, FUNC) \ - gen_rtx_REG (((INTEGRAL_TYPE_P (VALTYPE) \ - && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \ - || POINTER_TYPE_P (VALTYPE)) \ - ? word_mode : TYPE_MODE (VALTYPE), \ - ((TARGET_FPREGS \ - && (TREE_CODE (VALTYPE) == REAL_TYPE \ - || TREE_CODE (VALTYPE) == COMPLEX_TYPE)) \ - ? 32 : 0)) - -/* Define how to find the value returned by a library function - assuming the value has mode MODE. */ - -#define LIBCALL_VALUE(MODE) \ - gen_rtx_REG (MODE, \ - (TARGET_FPREGS \ - && (GET_MODE_CLASS (MODE) == MODE_FLOAT \ - || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \ - ? 32 : 0)) - -/* The definition of this macro implies that there are cases where - a scalar value cannot be returned in registers. - - For the Alpha, any structure or union type is returned in memory, as - are integers whose size is larger than 64 bits. */ - -#define RETURN_IN_MEMORY(TYPE) \ - (TYPE_MODE (TYPE) == BLKmode \ - || (TREE_CODE (TYPE) == INTEGER_TYPE && TYPE_PRECISION (TYPE) > 64)) - -/* 1 if N is a possible register number for a function value - as seen by the caller. */ - -#define FUNCTION_VALUE_REGNO_P(N) \ - ((N) == 0 || (N) == 1 || (N) == 32 || (N) == 33) - -/* 1 if N is a possible register number for function argument passing. - On Alpha, these are $16-$21 and $f16-$f21. */ - -#define FUNCTION_ARG_REGNO_P(N) \ - (((N) >= 16 && (N) <= 21) || ((N) >= 16 + 32 && (N) <= 21 + 32)) - -/* 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 Alpha, this is a single integer, which is a number of words - of arguments scanned so far. - Thus 6 or more means all following args should go on the stack. */ - -#define CUMULATIVE_ARGS int - -/* 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. */ - -#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) (CUM) = 0 - -/* Define intermediate macro to compute the size (in registers) of an argument - 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) - -/* 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.) */ - -#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - if (MUST_PASS_IN_STACK (MODE, TYPE)) \ - (CUM) = 6; \ - else \ - (CUM) += ALPHA_ARG_SIZE (MODE, TYPE, NAMED) - -/* 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. - 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. */ - -#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) - -/* Specify the padding direction of arguments. - - On the Alpha, we must pad upwards in order to be able to pass args in - registers. */ - -#define FUNCTION_ARG_PADDING(MODE, TYPE) upward - -/* For an arg passed partly in registers and partly in memory, - this is the number of registers used. - For args passed entirely in registers or entirely in memory, zero. */ - -#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ -((CUM) < 6 && 6 < (CUM) + ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \ - ? 6 - (CUM) : 0) - -/* Perform any needed actions needed for a function that is receiving a - variable number of arguments. - - CUM is as above. - - MODE and TYPE are the mode and type of the current parameter. - - PRETEND_SIZE is a variable that should be set to the amount of stack - that must be pushed by the prolog to pretend that our caller pushed - it. - - Normally, this macro will push all remaining incoming registers on the - stack and set PRETEND_SIZE to the length of the registers pushed. - - On the Alpha, we allocate space for all 12 arg registers, but only - push those that are remaining. - - However, if NO registers need to be saved, don't allocate any space. - This is not only because we won't need the space, but because AP includes - the current_pretend_args_size and we don't want to mess up any - ap-relative addresses already made. - - If we are not to use the floating-point registers, save the integer - registers where we would put the floating-point registers. This is - not the most efficient way to implement varargs with just one register - class, but it isn't worth doing anything more efficient in this rare - case. */ - - -#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \ -{ if ((CUM) < 6) \ - { \ - if (! (NO_RTL)) \ - { \ - move_block_from_reg \ - (16 + CUM, \ - gen_rtx (MEM, BLKmode, \ - plus_constant (virtual_incoming_args_rtx, \ - ((CUM) + 6)* UNITS_PER_WORD)), \ - 6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD); \ - move_block_from_reg \ - (16 + (TARGET_FPREGS ? 32 : 0) + CUM, \ - gen_rtx (MEM, BLKmode, \ - plus_constant (virtual_incoming_args_rtx, \ - (CUM) * UNITS_PER_WORD)), \ - 6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD); \ - emit_insn (gen_blockage ()); \ - } \ - PRETEND_SIZE = 12 * UNITS_PER_WORD; \ - } \ -} - -/* 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. */ - -extern struct rtx_def *alpha_eh_epilogue_sp_ofs; - -/* Make (or fake) .linkage entry for function call. - IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */ -extern void alpha_need_linkage (); - -/* This macro defines the start of an assembly comment. */ - -#define ASM_COMMENT_START " #" - -/* This macro produces the initial definition of a function. */ - -#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 - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. Under OSF/1, profiling is enabled - by simply passing -pg to the assembler and linker. */ - -#define FUNCTION_PROFILER(FILE, LABELNO) - -/* 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. */ - -#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \ - do { \ - ASM_OUTPUT_REG_PUSH (FILE, 16); \ - fputs ("\tlda $16,$PBX32\n", (FILE)); \ - fputs ("\tldq $26,0($16)\n", (FILE)); \ - fputs ("\tbne $26,1f\n", (FILE)); \ - fputs ("\tlda $27,__bb_init_func\n", (FILE)); \ - fputs ("\tjsr $26,($27),__bb_init_func\n", (FILE)); \ - fputs ("\tldgp $29,0($26)\n", (FILE)); \ - fputs ("1:\n", (FILE)); \ - ASM_OUTPUT_REG_POP (FILE, 16); \ - } while (0); - -/* Output assembler code to FILE to increment the entry-count for - the BLOCKNO'th basic block in this source file. */ - -#define BLOCK_PROFILER(FILE, BLOCKNO) \ - do { \ - int blockn = (BLOCKNO); \ - fputs ("\tsubq $30,16,$30\n", (FILE)); \ - fputs ("\tstq $26,0($30)\n", (FILE)); \ - fputs ("\tstq $27,8($30)\n", (FILE)); \ - fputs ("\tlda $26,$PBX34\n", (FILE)); \ - fprintf ((FILE), "\tldq $27,%d($26)\n", 8*blockn); \ - fputs ("\taddq $27,1,$27\n", (FILE)); \ - fprintf ((FILE), "\tstq $27,%d($26)\n", 8*blockn); \ - fputs ("\tldq $26,0($30)\n", (FILE)); \ - fputs ("\tldq $27,8($30)\n", (FILE)); \ - fputs ("\taddq $30,16,$30\n", (FILE)); \ - } while (0) - - -/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, - the stack pointer does not matter. The value is tested only in - functions that have frame pointers. - No definition is equivalent to always zero. */ - -#define EXIT_IGNORE_STACK 1 - -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. - - 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. */ - -#define TRAMPOLINE_TEMPLATE(FILE) \ -do { \ - fprintf (FILE, "\tldq $1,24($27)\n"); \ - fprintf (FILE, "\tldq $27,16($27)\n"); \ - fprintf (FILE, "\tjmp $31,($27),0\n"); \ - fprintf (FILE, "\tnop\n"); \ - fprintf (FILE, "\t.quad 0,0\n"); \ -} while (0) - -/* Section in which to place the trampoline. On Alpha, instructions - may only be placed in a text segment. */ - -#define TRAMPOLINE_SECTION text_section - -/* Length in units of the trampoline for entering a nested function. */ - -#define TRAMPOLINE_SIZE 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. */ - -#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. - FRAMEADDR is the frame pointer of the COUNT frame, or the frame pointer of - the COUNT-1 frame if RETURN_ADDR_IN_PREVIOUS_FRAME is defined. */ - -#define RETURN_ADDR_RTX alpha_return_addr -extern struct rtx_def *alpha_return_addr (); - -/* 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 (); - -/* Addressing modes, and classification of registers for them. */ - -/* #define HAVE_POST_INCREMENT 0 */ -/* #define HAVE_POST_DECREMENT 0 */ - -/* #define HAVE_PRE_DECREMENT 0 */ -/* #define HAVE_PRE_INCREMENT 0 */ - -/* Macros to check register numbers against specific register classes. */ - -/* These assume that REGNO is a hard or pseudo reg number. - They give nonzero only if REGNO is a hard reg of the suitable class - or a pseudo reg currently allocated to a suitable hard reg. - Since they use reg_renumber, they are safe only once reg_renumber - has been allocated, which happens in local-alloc.c. */ - -#define REGNO_OK_FOR_INDEX_P(REGNO) 0 -#define REGNO_OK_FOR_BASE_P(REGNO) \ -((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32 \ - || (REGNO) == 63 || reg_renumber[REGNO] == 63) - -/* Maximum number of registers that can appear in a valid memory address. */ -#define MAX_REGS_PER_ADDRESS 1 - -/* Recognize any constant value that is a valid address. For the Alpha, - there are only constants none since we want to use LDA to load any - symbolic addresses into registers. */ - -#define CONSTANT_ADDRESS_P(X) \ - (GET_CODE (X) == CONST_INT \ - && (unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000) - -/* Include all constant integers and constant doubles, but not - floating-point, except for floating-point zero. */ - -#define LEGITIMATE_CONSTANT_P(X) \ - (GET_MODE_CLASS (GET_MODE (X)) != MODE_FLOAT \ - || (X) == CONST0_RTX (GET_MODE (X))) - -/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx - and check its validity for a certain class. - We have two alternate definitions for each of them. - The usual definition accepts all pseudo regs; the other rejects - them unless they have been allocated suitable hard regs. - The symbol REG_OK_STRICT causes the latter definition to be used. - - Most source files want to accept pseudo regs in the hope that - they will get allocated to the class that the insn wants them to be in. - Source files for reload pass need to be strict. - 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) \ - (REGNO (X) < 32 || REGNO (X) == 63 || REGNO (X) >= FIRST_PSEUDO_REGISTER) - -/* ??? Nonzero if X is the frame pointer, or some virtual register - that may eliminate to the frame pointer. These will be allowed to - have offsets greater than 32K. This is done because register - elimination offsets will change the hi/lo split, and if we split - before reload, we will require additional instructions. */ -#define REG_OK_FP_BASE_P(X) \ - (REGNO (X) == 31 || REGNO (X) == 63 \ - || (REGNO (X) >= FIRST_PSEUDO_REGISTER \ - && REGNO (X) < LAST_VIRTUAL_REGISTER)) - -#else - -/* Nonzero if X is a hard reg that can be used as an index. */ -#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) - -/* Nonzero if X is a hard reg that can be used as a base reg. */ -#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) - -#define REG_OK_FP_BASE_P(X) 0 - -#endif - -/* 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. */ - -#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); \ -} - -/* 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. */ - -#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) \ - { \ - 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); \ - goto WIN; \ - } \ -} - -/* 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. */ - -#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; \ - } \ -} while (0) - -/* Go to LABEL if ADDR (a legitimate address expression) - has an effect that depends on the machine mode it is used for. - On the Alpha this is true only for the unaligned modes. We can - simplify this test since we know that the address must be valid. */ - -#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \ -{ if (GET_CODE (ADDR) == AND) goto LABEL; } - -/* Compute the cost of an address. For the Alpha, all valid addresses are - the same cost. */ - -#define ADDRESS_COST(X) 0 - -/* Machine-dependent reorg pass. */ -#define MACHINE_DEPENDENT_REORG(X) alpha_reorg(X) - -/* Specify the machine mode that this machine uses - for the index in the tablejump instruction. */ -#define CASE_VECTOR_MODE SImode - -/* Define as C expression which evaluates to nonzero if the tablejump - instruction expects the table to contain offsets from the address of the - table. - - Do not define this if the table should contain absolute addresses. - On the Alpha, the table is really GP-relative, not relative to the PC - of the table, but we pretend that it is PC-relative; this should be OK, - 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 - -/* This flag, if defined, says the same insns that convert to a signed fixnum - also convert validly to an unsigned one. - - We actually lie a bit here as overflow conditions are different. But - they aren't being checked anyway. */ - -#define FIXUNS_TRUNC_LIKE_FIX_TRUNC - -/* Max number of bytes we can move to or from memory - in one reasonably fast instruction. */ - -#define MOVE_MAX 8 - -/* If a memory-to-memory move would take MOVE_RATIO or more simple - move-instruction pairs, we will do a movstr or libcall instead. - - Without byte/word accesses, we want no more than four instructions; - with, several single byte accesses are better. */ - -#define MOVE_RATIO (TARGET_BWX ? 7 : 2) - -/* Largest number of bytes of an object that can be placed in a register. - On the Alpha we have plenty of registers, so use TImode. */ -#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TImode) - -/* Nonzero if access to memory by bytes is no faster than for words. - Also non-zero if doing byte operations (specifically shifts) in registers - is undesirable. - - On the Alpha, we want to not use the byte operation and instead use - masking operations to access fields; these will save instructions. */ - -#define SLOW_BYTE_ACCESS 1 - -/* Define if operations between registers always perform the operation - on the full register even if a narrower mode is specified. */ -#define WORD_REGISTER_OPERATIONS - -/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD - will either zero-extend or sign-extend. The value of this macro should - be the code that says which one of the two operations is implicitly - done, NIL if none. */ -#define LOAD_EXTEND_OP(MODE) ((MODE) == SImode ? SIGN_EXTEND : ZERO_EXTEND) - -/* Define if loading short immediate values into registers sign extends. */ -#define SHORT_IMMEDIATES_SIGN_EXTEND - -/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits - is done just by pretending it is already truncated. */ -#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 - -/* We assume that the store-condition-codes instructions store 0 for false - and some other value for true. This is the value stored for true. */ - -#define STORE_FLAG_VALUE 1 - -/* Define the value returned by a floating-point comparison instruction. */ - -#define FLOAT_STORE_FLAG_VALUE (TARGET_FLOAT_VAX ? 0.5 : 2.0) - -/* Canonicalize a comparison from one we don't have to one we do have. */ - -#define CANONICALIZE_COMPARISON(CODE,OP0,OP1) \ - do { \ - if (((CODE) == GE || (CODE) == GT || (CODE) == GEU || (CODE) == GTU) \ - && (GET_CODE (OP1) == REG || (OP1) == const0_rtx)) \ - { \ - rtx tem = (OP0); \ - (OP0) = (OP1); \ - (OP1) = tem; \ - (CODE) = swap_condition (CODE); \ - } \ - if (((CODE) == LT || (CODE) == LTU) \ - && GET_CODE (OP1) == CONST_INT && INTVAL (OP1) == 256) \ - { \ - (CODE) = (CODE) == LT ? LE : LEU; \ - (OP1) = GEN_INT (255); \ - } \ - } while (0) - -/* Specify the machine mode that pointers have. - After generation of rtl, the compiler makes no further distinction - 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). */ - -#define FUNCTION_MODE Pmode - -/* Define this if addresses of constant functions - shouldn't be put through pseudo regs where they can be cse'd. - Desirable on machines where ordinary constants are expensive - but a CALL with constant address is cheap. - - We define this on the Alpha so that gen_call and gen_call_value - get to see the SYMBOL_REF (for the hint field of the jsr). It will - then copy it into a register, thus actually letting the address be - cse'ed. */ - -#define NO_FUNCTION_CSE - -/* Define this to be nonzero if shift instructions ignore all but the low-order - 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, - return it with a return statement. Otherwise, break from the switch. - - If this is an 8-bit constant, return zero since it can be used - nearly anywhere with no cost. If it is a valid operand for an - ADD or AND, likewise return 0 if we know it will be used in that - context. Otherwise, return 2 since it might be used there later. - All other constants take at least two insns. */ - -#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ - case CONST_INT: \ - if (INTVAL (RTX) >= 0 && INTVAL (RTX) < 256) \ - return 0; \ - case CONST_DOUBLE: \ - if ((RTX) == CONST0_RTX (GET_MODE (RTX))) \ - return 0; \ - else if (((OUTER_CODE) == PLUS && add_operand (RTX, VOIDmode)) \ - || ((OUTER_CODE) == AND && and_operand (RTX, VOIDmode))) \ - return 0; \ - else if (add_operand (RTX, VOIDmode) || and_operand (RTX, VOIDmode)) \ - return 2; \ - else \ - return COSTS_N_INSNS (2); \ - case CONST: \ - case SYMBOL_REF: \ - case LABEL_REF: \ - switch (alpha_cpu) \ - { \ - case PROCESSOR_EV4: \ - return COSTS_N_INSNS (3); \ - case PROCESSOR_EV5: \ - case PROCESSOR_EV6: \ - return COSTS_N_INSNS (2); \ - default: abort(); \ - } - -/* Provide the costs of a rtl expression. This is in the body of a - switch on CODE. */ - -#define RTX_COSTS(X,CODE,OUTER_CODE) \ - case PLUS: case MINUS: \ - if (FLOAT_MODE_P (GET_MODE (X))) \ - switch (alpha_cpu) \ - { \ - case PROCESSOR_EV4: \ - return COSTS_N_INSNS (6); \ - case PROCESSOR_EV5: \ - case PROCESSOR_EV6: \ - return COSTS_N_INSNS (4); \ - default: abort(); \ - } \ - else if (GET_CODE (XEXP (X, 0)) == MULT \ - && const48_operand (XEXP (XEXP (X, 0), 1), VOIDmode)) \ - return (2 + rtx_cost (XEXP (XEXP (X, 0), 0), OUTER_CODE) \ - + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ - break; \ - case MULT: \ - switch (alpha_cpu) \ - { \ - case PROCESSOR_EV4: \ - if (FLOAT_MODE_P (GET_MODE (X))) \ - return COSTS_N_INSNS (6); \ - return COSTS_N_INSNS (23); \ - case PROCESSOR_EV5: \ - if (FLOAT_MODE_P (GET_MODE (X))) \ - return COSTS_N_INSNS (4); \ - else if (GET_MODE (X) == DImode) \ - return COSTS_N_INSNS (12); \ - else \ - return COSTS_N_INSNS (8); \ - case PROCESSOR_EV6: \ - if (FLOAT_MODE_P (GET_MODE (X))) \ - return COSTS_N_INSNS (4); \ - else \ - return COSTS_N_INSNS (7); \ - default: abort(); \ - } \ - case ASHIFT: \ - if (GET_CODE (XEXP (X, 1)) == CONST_INT \ - && INTVAL (XEXP (X, 1)) <= 3) \ - break; \ - /* ... fall through ... */ \ - case ASHIFTRT: case LSHIFTRT: \ - switch (alpha_cpu) \ - { \ - case PROCESSOR_EV4: \ - return COSTS_N_INSNS (2); \ - case PROCESSOR_EV5: \ - case PROCESSOR_EV6: \ - return COSTS_N_INSNS (1); \ - default: abort(); \ - } \ - case IF_THEN_ELSE: \ - switch (alpha_cpu) \ - { \ - case PROCESSOR_EV4: \ - case PROCESSOR_EV6: \ - return COSTS_N_INSNS (2); \ - case PROCESSOR_EV5: \ - return COSTS_N_INSNS (1); \ - default: abort(); \ - } \ - case DIV: case UDIV: case MOD: case UMOD: \ - switch (alpha_cpu) \ - { \ - case PROCESSOR_EV4: \ - if (GET_MODE (X) == SFmode) \ - return COSTS_N_INSNS (34); \ - else if (GET_MODE (X) == DFmode) \ - return COSTS_N_INSNS (63); \ - else \ - return COSTS_N_INSNS (70); \ - case PROCESSOR_EV5: \ - if (GET_MODE (X) == SFmode) \ - return COSTS_N_INSNS (15); \ - else if (GET_MODE (X) == DFmode) \ - return COSTS_N_INSNS (22); \ - else \ - return COSTS_N_INSNS (70); /* ??? */ \ - case PROCESSOR_EV6: \ - if (GET_MODE (X) == SFmode) \ - return COSTS_N_INSNS (12); \ - else if (GET_MODE (X) == DFmode) \ - return COSTS_N_INSNS (15); \ - else \ - return COSTS_N_INSNS (70); /* ??? */ \ - default: abort(); \ - } \ - case MEM: \ - switch (alpha_cpu) \ - { \ - case PROCESSOR_EV4: \ - case PROCESSOR_EV6: \ - return COSTS_N_INSNS (3); \ - case PROCESSOR_EV5: \ - return COSTS_N_INSNS (2); \ - default: abort(); \ - } \ - case NEG: case ABS: \ - if (! FLOAT_MODE_P (GET_MODE (X))) \ - break; \ - /* ... fall through ... */ \ - case FLOAT: case UNSIGNED_FLOAT: case FIX: case UNSIGNED_FIX: \ - case FLOAT_EXTEND: case FLOAT_TRUNCATE: \ - switch (alpha_cpu) \ - { \ - case PROCESSOR_EV4: \ - return COSTS_N_INSNS (6); \ - case PROCESSOR_EV5: \ - case PROCESSOR_EV6: \ - return COSTS_N_INSNS (4); \ - default: abort(); \ - } - -/* 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 "" - -/* Output to assembler file text saying following lines - no longer contain unusual constructs. */ - -#define ASM_APP_OFF "" - -#define TEXT_SECTION_ASM_OP ".text" - -/* Output before read-only data. */ - -#define READONLY_DATA_SECTION_ASM_OP ".rdata" - -/* Output before writable data. */ - -#define DATA_SECTION_ASM_OP ".data" - -/* Define an extra section for read-only data, a routine to enter it, and - indicate that it is for read-only data. - - The first time we enter the readonly data section for a file, we write - eight bytes of zero. This works around a bug in DEC's assembler in - some versions of OSF/1 V3.x. */ - -#define EXTRA_SECTIONS readonly_data - -#define EXTRA_SECTION_FUNCTIONS \ -void \ -literal_section () \ -{ \ - if (in_section != readonly_data) \ - { \ - static int firsttime = 1; \ - \ - fprintf (asm_out_file, "%s\n", READONLY_DATA_SECTION_ASM_OP); \ - if (firsttime) \ - { \ - firsttime = 0; \ - ASM_OUTPUT_DOUBLE_INT (asm_out_file, const0_rtx); \ - } \ - \ - in_section = readonly_data; \ - } \ -} \ - -#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 ENCODE_SECTION_INFO(DECL) \ - if (TREE_CODE (DECL) == FUNCTION_DECL && ! TREE_PUBLIC (DECL)) \ - SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; - -/* How to refer to registers in assembler output. - This sequence is indexed by compiler's hard-register-number (see above). */ - -#define REGISTER_NAMES \ -{"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \ - "$9", "$10", "$11", "$12", "$13", "$14", "$15", \ - "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", \ - "$24", "$25", "$26", "$27", "$28", "$29", "$30", "AP", \ - "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", \ - "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", \ - "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",\ - "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "FP"} - -/* How to renumber registers for dbx and gdb. */ - -#define DBX_REGISTER_NUMBER(REGNO) (REGNO) - -/* 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. */ - -#define ASM_OUTPUT_LABEL(FILE,NAME) \ - do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0) - -/* This is how to output a command to make the user-level label named NAME - defined for reference from other files. */ - -#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. */ - -#define USER_LABEL_PREFIX "" - -/* This is how to output an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, "$%s%d:\n", PREFIX, NUM) - -/* 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. */ - -#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \ -{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); } - -/* This is how to store into the string LABEL - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf ((LABEL), "*$%s%ld", (PREFIX), (long)(NUM)) - -/* Check a floating-point value for validity for a particular machine mode. */ - -#define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \ - ((OVERFLOW) = check_float_value (MODE, &D, OVERFLOW)) - -/* This is how to output an assembler line defining a `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); \ - int _hide_thissize = (MYLENGTH); \ - int _size_so_far = 0; \ - { \ - FILE *asm_out_file = _hide_asm_out_file; \ - unsigned char *p = _hide_p; \ - int thissize = _hide_thissize; \ - int i; \ - fprintf (asm_out_file, "\t.ascii \""); \ - \ - for (i = 0; i < thissize; i++) \ - { \ - register int c = p[i]; \ - \ - if (_size_so_far ++ > 50 && i < thissize - 4) \ - _size_so_far = 0, fprintf (asm_out_file, "\"\n\t.ascii \""); \ - \ - if (c == '\"' || c == '\\') \ - putc ('\\', asm_out_file); \ - if (c >= ' ' && c < 0177) \ - putc (c, asm_out_file); \ - else \ - { \ - 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 \ - 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') \ - _size_so_far = 0, fprintf (asm_out_file, "\"\n\t.ascii \""); \ - } \ - } \ - fprintf (asm_out_file, "\"\n"); \ - } \ - } \ - 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. */ - -#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ - fprintf (FILE, "\tsubq $30,8,$30\n\tst%s $%s%d,0($30)\n", \ - (REGNO) > 32 ? "t" : "q", (REGNO) > 32 ? "f" : "", \ - (REGNO) & 31); - -/* This is how to output an insn to pop a register from the stack. - It need not be very fast code. */ - -#define ASM_OUTPUT_REG_POP(FILE,REGNO) \ - fprintf (FILE, "\tld%s $%s%d,0($30)\n\taddq $30,8,$30\n", \ - (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.) */ - -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) abort () - -/* 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", \ - (VALUE)) - -/* This is how to output an assembler line - that says to advance the location counter - to a multiple of 2**LOG bytes. */ - -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG) != 0) \ - fprintf (FILE, "\t.align %d\n", LOG); - -/* This is how to advance the location counter by SIZE bytes. */ - -#define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf (FILE, "\t.space %d\n", (SIZE)) - -/* This says how to output an assembler line - to define a global common symbol. */ - -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ -( fputs ("\t.comm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%d\n", (SIZE))) - -/* This says how to output an assembler line - to define a local common symbol. */ - -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE,ROUNDED) \ -( fputs ("\t.lcomm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%d\n", (SIZE))) - -/* Store in OUTPUT a string (made with alloca) containing - an assembler-name for a local static variable named NAME. - LABELNO is an integer which is different for each call. */ - -#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. */ - -#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. - - ) 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 trap-mode suffix for instructions that accept the - sui suffix (cvtqt and cvtqs). - - , Generates single precision suffix for floating point - instructions (s for IEEE, f for VAX) - - - Generates double precision suffix for floating point - instructions (t for IEEE, g for VAX) - */ - -#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ - ((CODE) == '&' || (CODE) == '`' || (CODE) == '\'' || (CODE) == '(' \ - || (CODE) == ')' || (CODE) == '+' || (CODE) == ',' || (CODE) == '-') - -/* Print a memory address as an operand to reference that memory location. */ - -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ - print_operand_address((FILE), (ADDR)) - -/* Define the codes that are matched by predicates in alpha.c. */ - -#define PREDICATE_CODES \ - {"reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \ - {"reg_or_6bit_operand", {SUBREG, REG, CONST_INT}}, \ - {"reg_or_8bit_operand", {SUBREG, REG, CONST_INT}}, \ - {"cint8_operand", {CONST_INT}}, \ - {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \ - {"add_operand", {SUBREG, REG, CONST_INT}}, \ - {"sext_add_operand", {SUBREG, REG, CONST_INT}}, \ - {"const48_operand", {CONST_INT}}, \ - {"and_operand", {SUBREG, REG, CONST_INT}}, \ - {"or_operand", {SUBREG, REG, CONST_INT}}, \ - {"mode_mask_operand", {CONST_INT}}, \ - {"mul8_operand", {CONST_INT}}, \ - {"mode_width_operand", {CONST_INT}}, \ - {"reg_or_fp0_operand", {SUBREG, REG, CONST_DOUBLE}}, \ - {"alpha_comparison_operator", {EQ, LE, LT, LEU, LTU}}, \ - {"alpha_swapped_comparison_operator", {EQ, GE, GT, GEU, GTU}}, \ - {"signed_comparison_operator", {EQ, NE, LE, LT, GE, GT}}, \ - {"divmod_operator", {DIV, MOD, UDIV, UMOD}}, \ - {"fp0_operand", {CONST_DOUBLE}}, \ - {"current_file_function_operand", {SYMBOL_REF}}, \ - {"call_operand", {REG, SYMBOL_REF}}, \ - {"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \ - SYMBOL_REF, CONST, LABEL_REF}}, \ - {"some_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \ - SYMBOL_REF, CONST, LABEL_REF}}, \ - {"aligned_memory_operand", {MEM}}, \ - {"unaligned_memory_operand", {MEM}}, \ - {"reg_or_unaligned_mem_operand", {SUBREG, REG, MEM}}, \ - {"any_memory_operand", {MEM}}, \ - {"hard_fp_register_operand", {SUBREG, REG}}, \ - {"reg_not_elim_operand", {SUBREG, REG}}, \ - {"reg_no_subreg_operand", {REG}}, - -/* Tell collect that the object format is ECOFF. */ -#define OBJECT_FORMAT_COFF -#define EXTENDED_COFF - -/* If we use NM, pass -g to it so it only lists globals. */ -#define NM_FLAGS "-pg" - -/* Definitions for debugging. */ - -#define SDB_DEBUGGING_INFO /* generate info for mips-tfile */ -#define DBX_DEBUGGING_INFO /* generate embedded stabs */ -#define MIPS_DEBUGGING_INFO /* MIPS specific debugging info */ - -#ifndef PREFERRED_DEBUGGING_TYPE /* assume SDB_DEBUGGING_INFO */ -#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG -#endif - - -/* Correct the offset of automatic variables and arguments. Note that - the Alpha debug format wants all automatic variables and arguments - to be in terms of two different offsets from the virtual frame pointer, - which is the stack pointer before any adjustment in the function. - The offset for the argument pointer is fixed for the native compiler, - it is either zero (for the no arguments case) or large enough to hold - all argument registers. - The offset for the auto pointer is the fourth argument to the .frame - directive (local_offset). - To stay compatible with the native tools we use the same offsets - from the virtual frame pointer and adjust the debugger arg/auto offsets - accordingly. These debugger offsets are set up in output_prolog. */ - -extern long alpha_arg_offset; -extern long alpha_auto_offset; -#define DEBUGGER_AUTO_OFFSET(X) \ - ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) + alpha_auto_offset) -#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET + alpha_arg_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 - continuation point. This is really a dbxout.c bug. */ -#define DBX_CONTIN_LENGTH 3000 - -/* By default, turn on GDB extensions. */ -#define DEFAULT_GDB_EXTENSIONS 1 - -/* Stabs-in-ECOFF can't handle dbxout_function_end(). */ -#define NO_DBX_FUNCTION_END 1 - -/* If we are smuggling stabs through the ALPHA ECOFF object - format, put a comment in front of the .stab<x> operation so - 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") - -/* Forward references to tags are allowed. */ -#define SDB_ALLOW_FORWARD_REFERENCES - -/* Unknown tags are also allowed. */ -#define SDB_ALLOW_UNKNOWN_REFERENCES - -#define PUT_SDB_DEF(a) \ -do { \ - fprintf (asm_out_file, "\t%s.def\t", \ - (TARGET_GAS) ? "" : "#"); \ - ASM_OUTPUT_LABELREF (asm_out_file, a); \ - fputc (';', asm_out_file); \ -} while (0) - -#define PUT_SDB_PLAIN_DEF(a) \ -do { \ - fprintf (asm_out_file, "\t%s.def\t.%s;", \ - (TARGET_GAS) ? "" : "#", (a)); \ -} while (0) - -#define PUT_SDB_TYPE(a) \ -do { \ - fprintf (asm_out_file, "\t.type\t0x%x;", (a)); \ -} while (0) - -/* For block start and end, we create labels, so that - later we can figure out where the correct offset is. - The normal .ent/.end serve well enough for functions, - so those are just commented out. */ - -extern int sdb_label_count; /* block start/end next label # */ - -#define PUT_SDB_BLOCK_START(LINE) \ -do { \ - fprintf (asm_out_file, \ - "$Lb%d:\n\t%s.begin\t$Lb%d\t%d\n", \ - sdb_label_count, \ - (TARGET_GAS) ? "" : "#", \ - sdb_label_count, \ - (LINE)); \ - sdb_label_count++; \ -} while (0) - -#define PUT_SDB_BLOCK_END(LINE) \ -do { \ - fprintf (asm_out_file, \ - "$Le%d:\n\t%s.bend\t$Le%d\t%d\n", \ - sdb_label_count, \ - (TARGET_GAS) ? "" : "#", \ - sdb_label_count, \ - (LINE)); \ - sdb_label_count++; \ -} while (0) - -#define PUT_SDB_FUNCTION_START(LINE) - -#define PUT_SDB_FUNCTION_END(LINE) - -#define PUT_SDB_EPILOGUE_END(NAME) ((void)(NAME)) - -/* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for - mips-tdump.c to print them out. - - These must match the corresponding definitions in gdb/mipsread.c. - Unfortunately, gcc and gdb do not currently share any directories. */ - -#define CODE_MASK 0x8F300 -#define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK) -#define MIPS_MARK_STAB(code) ((code)+CODE_MASK) -#define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK) - -/* Override some mips-tfile definitions. */ - -#define SHASH_SIZE 511 -#define THASH_SIZE 55 - -/* Align ecoff symbol tables to avoid OSF1/1.3 nm complaints. */ - -#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 (); diff --git a/contrib/gcc/config/alpha/alpha.md b/contrib/gcc/config/alpha/alpha.md deleted file mode 100644 index 6d075e99904a..000000000000 --- a/contrib/gcc/config/alpha/alpha.md +++ /dev/null @@ -1,5415 +0,0 @@ -;; Machine description for DEC Alpha for GNU C compiler -;; Copyright (C) 1992, 93-98, 1999 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, -;; Boston, MA 02111-1307, USA. - -;;- 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 -;; -;; UNSPEC_VOLATILE: -;; -;; 0 imb -;; 1 blockage -;; 2 builtin_setjmp_receiver -;; 3 builtin_longjmp -;; 4 trapb -;; 5 prologue_stack_probe_loop -;; 6 realign -;; 7 exception_receiver - -;; Processor type -- this attribute must exactly match the processor_type -;; enumeration in alpha.h. - -(define_attr "cpu" "ev4,ev5,ev6" - (const (symbol_ref "alpha_cpu"))) - -;; Define an insn type attribute. This is used in function unit delay -;; computations, among other purposes. For the most part, we use the names -;; defined in the EV4 documentation, but add a few that we have to know about -;; 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" - (const_string "iadd")) - -;; Describe a user's asm statement. -(define_asm_attributes - [(set_attr "type" "multi")]) - -;; Define the operand size an insn operates on. Used primarily by mul -;; and div operations that have size dependant timings. - -(define_attr "opsize" "si,di,udi" (const_string "di")) - -;; The TRAP_TYPE 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")) - -;; The length of an instruction sequence in bytes. - -(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 -;; category. ABOX, BBOX, EBOX, FBOX, IMUL & FDIV make up the second. -;; (There are a few other register-like resources, but ...) - -; First, describe all of the issue constraints with single cycle delays. -; All insns need a bus, but all except loads require one or the other. -(define_function_unit "ev4_ibus0" 1 0 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "fst,fbr,iadd,imul,ilog,shift,icmov,icmp")) - 1 1) - -(define_function_unit "ev4_ibus1" 1 0 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "ist,ibr,jsr,fadd,fcmov,fcpys,fmul,fdiv,misc")) - 1 1) - -; Memory delivers its result in three cycles. Actually return one and -; take care of this in adjust_cost, since we want to handle user-defined -; memory latencies. -(define_function_unit "ev4_abox" 1 0 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "ild,fld,ldsym,ist,fst")) - 1 1) - -; Branches have no delay cost, but do tie up the unit for two cycles. -(define_function_unit "ev4_bbox" 1 1 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "ibr,fbr,jsr")) - 2 2) - -; Arithmetic insns are normally have their results available after -; two cycles. There are a number of exceptions. They are encoded in -; ADJUST_COST. Some of the other insns have similar exceptions. -(define_function_unit "ev4_ebox" 1 0 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "iadd,ilog,shift,icmov,icmp,misc")) - 2 1) - -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev4") - (and (eq_attr "type" "imul") - (eq_attr "opsize" "si"))) - 21 19) - -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev4") - (and (eq_attr "type" "imul") - (eq_attr "opsize" "!si"))) - 23 21) - -(define_function_unit "ev4_fbox" 1 0 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "fadd,fmul,fcpys,fcmov")) - 6 1) - -(define_function_unit "fdiv" 1 0 - (and (eq_attr "cpu" "ev4") - (and (eq_attr "type" "fdiv") - (eq_attr "opsize" "si"))) - 34 30) - -(define_function_unit "fdiv" 1 0 - (and (eq_attr "cpu" "ev4") - (and (eq_attr "type" "fdiv") - (eq_attr "opsize" "di"))) - 63 59) - -;; EV5 scheduling. EV5 can issue 4 insns per clock. -;; -;; EV5 has two asymetric integer units. Model this with E0 & E1 along -;; with the combined resource EBOX. - -(define_function_unit "ev5_ebox" 2 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv")) - 1 1) - -; Memory takes at least 2 clocks. Return one from here and fix up with -; user-defined latencies in adjust_cost. -(define_function_unit "ev5_ebox" 2 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "ild,fld,ldsym")) - 1 1) - -; Loads can dual issue with one another, but loads and stores do not mix. -(define_function_unit "ev5_e0" 1 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "ild,fld,ldsym")) - 1 1 - [(eq_attr "type" "ist,fst")]) - -; Stores, shifts, multiplies can only issue to E0 -(define_function_unit "ev5_e0" 1 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "ist,fst,shift,imul")) - 1 1) - -; Motion video insns also issue only to E0, and take two ticks. -(define_function_unit "ev5_e0" 1 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "mvi")) - 2 1) - -; Conditional moves always take 2 ticks. -(define_function_unit "ev5_ebox" 2 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "icmov")) - 2 1) - -; Branches can only issue to E1 -(define_function_unit "ev5_e1" 1 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "ibr,jsr")) - 1 1) - -; Multiplies also use the integer multiplier. -; ??? How to: "No instruction can be issued to pipe E0 exactly two -; cycles before an integer multiplication completes." -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev5") - (and (eq_attr "type" "imul") - (eq_attr "opsize" "si"))) - 8 4) - -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev5") - (and (eq_attr "type" "imul") - (eq_attr "opsize" "di"))) - 12 8) - -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev5") - (and (eq_attr "type" "imul") - (eq_attr "opsize" "udi"))) - 14 8) - -;; Similarly for the FPU we have two asymetric units. But fcpys can issue -;; on either so we have to play the game again. - -(define_function_unit "ev5_fbox" 2 0 - (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, -(define_function_unit "ev5_fa" 1 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "fadd,fcmov,fbr,fdiv")) - 4 1) - -; ??? How to: "No instruction can be issued to pipe FA exactly five -; cycles before a floating point divide completes." -(define_function_unit "fdiv" 1 0 - (and (eq_attr "cpu" "ev5") - (and (eq_attr "type" "fdiv") - (eq_attr "opsize" "si"))) - 15 15) ; 15 to 31 data dependant - -(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 - -;; 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 -;; taking one cycle. Since ev6 is out-of-order, we can't see anything -;; but two cycles. -(define_function_unit "ev6_ebox" 4 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "icmov")) - 2 1) - -(define_function_unit "ev6_ebox" 4 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv,fsqrt")) - 1 1) - -;; Integer loads take at least 3 clocks, and only issue to lower units. -;; Return one from here and fix up with user-defined latencies in adjust_cost. -(define_function_unit "ev6_l" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "ild,ldsym,ist,fst")) - 1 1) - -;; FP loads take at least 4 clocks. Return two from here... -(define_function_unit "ev6_l" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "fld")) - 2 1) - -;; Motion video insns also issue only to U0, and take three ticks. -(define_function_unit "ev6_u0" 1 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "mvi")) - 3 1) - -(define_function_unit "ev6_u" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "mvi")) - 3 1) - -;; Shifts issue to either upper pipe. -(define_function_unit "ev6_u" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "shift")) - 1 1) - -;; Multiplies issue only to U1, and all take 7 ticks. -;; Rather than create a new function unit just for U1, reuse IMUL -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "imul")) - 7 1) - -(define_function_unit "ev6_u" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "imul")) - 7 1) - -;; Branches issue to either upper pipe -(define_function_unit "ev6_u" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "ibr")) - 3 1) - -;; Calls only issue to L0. -(define_function_unit "ev6_l0" 1 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "jsr")) - 1 1) - -(define_function_unit "ev6_l" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "jsr")) - 1 1) - -;; Ftoi/itof only issue to lower pipes -(define_function_unit "ev6_l" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "ftoi")) - 3 1) - -(define_function_unit "ev6_l" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "itof")) - 4 1) - -;; 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")) - 4 1) - -(define_function_unit "ev6_fa" 1 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "fadd,fcpys,fbr,fdiv,fsqrt")) - 4 1) - -(define_function_unit "ev6_fa" 1 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "fcmov")) - 8 1) - -(define_function_unit "fdiv" 1 0 - (and (eq_attr "cpu" "ev6") - (and (eq_attr "type" "fdiv") - (eq_attr "opsize" "si"))) - 12 10) - -(define_function_unit "fdiv" 1 0 - (and (eq_attr "cpu" "ev6") - (and (eq_attr "type" "fdiv") - (eq_attr "opsize" "di"))) - 15 13) - -(define_function_unit "fsqrt" 1 0 - (and (eq_attr "cpu" "ev6") - (and (eq_attr "type" "fsqrt") - (eq_attr "opsize" "si"))) - 16 14) - -(define_function_unit "fsqrt" 1 0 - (and (eq_attr "cpu" "ev6") - (and (eq_attr "type" "fsqrt") - (eq_attr "opsize" "di"))) - 32 30) - -; ??? The FPU communicates with memory and the integer register file -; via two fp store units. We need a slot in the fst immediately, and -; a slot in LOW after the operand data is ready. At which point the -; data may be moved either to the store queue or the integer register -; file and the insn retired. - - -;; First define the arithmetic insns. Note that the 32-bit forms also -;; 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. -;; -;; 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")))] - "" - "@ - addl %1,$31,%0 - ldl %0,%1 - lds %0,%1\;cvtlq %0,%0" - [(set_attr "type" "iadd,ild,fld") - (set_attr "length" "*,*,8")]) - -;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here. -(define_split - [(set (match_operand:DI 0 "hard_fp_register_operand" "") - (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))] - "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")]) - -;; 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 -;; case combine wants to make it. -(define_expand "addsi3" - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "reg_or_0_operand" "") - (match_operand:SI 2 "add_operand" "")))] - "" - " -{ - if (optimize) - { - rtx op1 = gen_lowpart (DImode, operands[1]); - rtx op2 = gen_lowpart (DImode, operands[2]); - - if (! cse_not_expected) - { - rtx tmp = gen_reg_rtx (DImode); - emit_insn (gen_adddi3 (tmp, op1, op2)); - emit_move_insn (gen_lowpart (DImode, operands[0]), tmp); - } - else - emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2)); - DONE; - } -}") - -(define_insn "" - [(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")))] - "" - "@ - addl %r1,%2,%0 - subl %r1,%n2,%0 - lda %0,%2(%r1) - ldah %0,%h2(%r1)") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "const_int_operand" "")))] - "! 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); - HOST_WIDE_INT rest = val - low; - - operands[3] = GEN_INT (rest); - operands[4] = GEN_INT (low); -}") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (sign_extend:DI - (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ") - (match_operand:SI 2 "sext_add_operand" "rI,O"))))] - "" - "@ - addl %r1,%2,%0 - subl %r1,%n2,%0") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (sign_extend:DI - (plus:SI (match_operand:SI 1 "register_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 - && INTVAL (operands[2]) % 4 == 0" - [(set (match_dup 3) (match_dup 4)) - (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; - - if (val % 2 == 0) - val /= 2, mult = 8; - - operands[4] = GEN_INT (val); - operands[5] = GEN_INT (mult); -}") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (sign_extend:DI - (plus:SI (match_operator:SI 1 "comparison_operator" - [(match_operand 2 "" "") - (match_operand 3 "" "")]) - (match_operand:SI 4 "add_operand" "")))) - (clobber (match_operand:DI 5 "register_operand" ""))] - "" - [(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")))] - "" - "* -{ - const char * const pattern[4] = { - \"addq %r1,%2,%0\", - \"subq %r1,%n2,%0\", - \"lda %0,%2(%r1)\", - \"ldah %0,%h2(%r1)\" - }; - - /* 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. */ - - int which = which_alternative; - - if (operands[0] == stack_pointer_rtx - && GET_CODE (operands[2]) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')) - which = 2; - - return pattern[which]; -}") - -;; ??? 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 "" - [(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])" - "#") - -;; Don't do this if we are adjusting SP since we don't want to do it -;; in two steps. Don't split FP sources for the reason listed above. -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "const_int_operand" "")))] - "! add_operand (operands[2], DImode) - && operands[0] != stack_pointer_rtx - && operands[1] != frame_pointer_rtx - && 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); -}") - -(define_insn "" - [(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")) - (match_operand:SI 3 "sext_add_operand" "rI,O")))] - "" - "@ - s%2addl %1,%3,%0 - s%2subl %1,%n3,%0") - -(define_insn "" - [(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") - (match_operand:SI 2 "const48_operand" "I,I")) - (match_operand:SI 3 "sext_add_operand" "rI,O"))))] - "" - "@ - s%2addl %1,%3,%0 - s%2subl %1,%n3,%0") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (sign_extend:DI - (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator" - [(match_operand 2 "" "") - (match_operand 3 "" "")]) - (match_operand:SI 4 "const48_operand" "")) - (match_operand:SI 5 "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 "" - [(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")) - (match_operand:DI 3 "sext_add_operand" "rI,O")))] - "" - "@ - 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 "negsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))] - "" - "subl $31,%1,%0") - -(define_insn "" - [(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 "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_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) - { - rtx op1 = gen_lowpart (DImode, operands[1]); - rtx op2 = gen_lowpart (DImode, operands[2]); - - if (! cse_not_expected) - { - rtx tmp = gen_reg_rtx (DImode); - emit_insn (gen_subdi3 (tmp, op1, op2)); - emit_move_insn (gen_lowpart (DImode, operands[0]), tmp); - } - else - emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2)); - DONE; - } -} ") - -(define_insn "" - [(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 "" - [(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 "subdi3" - [(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")))] - "" - "subq %r1,%2,%0") - -(define_insn "" - [(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")) - (match_operand:SI 3 "reg_or_8bit_operand" "rI")))] - "" - "s%2subl %1,%3,%0") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extend:DI - (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r") - (match_operand:SI 2 "const48_operand" "I")) - (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))] - "" - "s%2subl %1,%3,%0") - -(define_insn "" - [(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")) - (match_operand:DI 3 "reg_or_8bit_operand" "rI")))] - "" - "s%2subq %1,%3,%0") - -(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")))] - "" - "mull %r1,%2,%0" - [(set_attr "type" "imul") - (set_attr "opsize" "si")]) - -(define_insn "" - [(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"))))] - "" - "mull %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") - (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] - "" - "mulq %r1,%2,%0" - [(set_attr "type" "imul")]) - -(define_insn "umuldi3_highpart" - [(set (match_operand:DI 0 "register_operand" "=r") - (truncate:DI - (lshiftrt:TI - (mult:TI (zero_extend:TI - (match_operand:DI 1 "reg_or_0_operand" "%rJ")) - (zero_extend:TI - (match_operand:DI 2 "reg_or_8bit_operand" "rI"))) - (const_int 64))))] - "" - "umulh %r1,%2,%0" - [(set_attr "type" "imul") - (set_attr "opsize" "udi")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (truncate:DI - (lshiftrt:TI - (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r")) - (match_operand:TI 2 "cint8_operand" "I")) - (const_int 64))))] - "" - "umulh %1,%2,%0" - [(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. - -(define_expand "divsi3" - [(set (reg:DI 24) - (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))) - (set (reg:DI 25) - (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)))) - (clobber (reg:DI 23)) - (clobber (reg:DI 28))]) - (set (match_operand:SI 0 "general_operand" "") - (subreg:SI (reg:DI 27) 0))] - "!TARGET_OPEN_VMS" - "") - -(define_expand "udivsi3" - [(set (reg:DI 24) - (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))) - (set (reg:DI 25) - (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)))) - (clobber (reg:DI 23)) - (clobber (reg:DI 28))]) - (set (match_operand:SI 0 "general_operand" "") - (subreg:SI (reg:DI 27) 0))] - "!TARGET_OPEN_VMS" - "") - -(define_expand "modsi3" - [(set (reg:DI 24) - (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))) - (set (reg:DI 25) - (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)))) - (clobber (reg:DI 23)) - (clobber (reg:DI 28))]) - (set (match_operand:SI 0 "general_operand" "") - (subreg:SI (reg:DI 27) 0))] - "!TARGET_OPEN_VMS" - "") - -(define_expand "umodsi3" - [(set (reg:DI 24) - (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))) - (set (reg:DI 25) - (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)))) - (clobber (reg:DI 23)) - (clobber (reg:DI 28))]) - (set (match_operand:SI 0 "general_operand" "") - (subreg:SI (reg:DI 27) 0))] - "!TARGET_OPEN_VMS" - "") - -(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))) - (clobber (reg:DI 23)) - (clobber (reg:DI 28))]) - (set (match_operand:DI 0 "general_operand" "") - (reg:DI 27))] - "!TARGET_OPEN_VMS" - "") - -(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))) - (clobber (reg:DI 23)) - (clobber (reg:DI 28))]) - (set (match_operand:DI 0 "general_operand" "") - (reg:DI 27))] - "!TARGET_OPEN_VMS" - "") - -(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))) - (clobber (reg:DI 23)) - (clobber (reg:DI 28))]) - (set (match_operand:DI 0 "general_operand" "") - (reg:DI 27))] - "!TARGET_OPEN_VMS" - "") - -(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))) - (clobber (reg:DI 23)) - (clobber (reg:DI 28))]) - (set (match_operand:DI 0 "general_operand" "") - (reg:DI 27))] - "!TARGET_OPEN_VMS" - "") - -;; 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)]))) - (clobber (reg:DI 23)) - (clobber (reg:DI 28))] - "!TARGET_OPEN_VMS" - "%E1 $24,$25,$27" - [(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)])) - (clobber (reg:DI 23)) - (clobber (reg:DI 28))] - "!TARGET_OPEN_VMS" - "%E1 $24,$25,$27" - [(set_attr "type" "jsr") - (set_attr "length" "8")]) - -;; Next are the basic logical operations. These only exist in DImode. - -(define_insn "anddi3" - [(set (match_operand:DI 0 "register_operand" "=r,r,r") - (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ") - (match_operand:DI 2 "and_operand" "rI,N,MH")))] - "" - "@ - and %r1,%2,%0 - bic %r1,%N2,%0 - zapnot %r1,%m2,%0" - [(set_attr "type" "ilog,ilog,shift")]) - -;; There are times when we can split an AND into two AND insns. This occurs -;; when we can first clear any bytes and then clear anything else. For -;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07". -;; Only do this when running on 64-bit host since the computations are -;; too messy otherwise. - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (and:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "const_int_operand" "")))] - "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; - int i; - - /* For each byte that isn't all zeros, make it all ones. */ - for (i = 0; i < 64; i += 8) - if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0) - mask1 |= (HOST_WIDE_INT) 0xff << i; - - /* Now turn on any bits we've just turned off. */ - mask2 |= ~ mask1; - - operands[3] = GEN_INT (mask1); - operands[4] = GEN_INT (mask2); -}") - -(define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "register_operand" "=r") - (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))] - "" - "and %1,0xff,%0" - [(set_attr "type" "ilog")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] - "TARGET_BWX" - "@ - and %1,0xff,%0 - ldbu %0,%1" - [(set_attr "type" "ilog,ild")]) - -(define_insn "" - [(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_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] - "TARGET_BWX" - "@ - and %1,0xff,%0 - ldbu %0,%1" - [(set_attr "type" "ilog,ild")]) - -(define_insn "" - [(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_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] - "TARGET_BWX" - "@ - zapnot %1,3,%0 - ldwu %0,%1" - [(set_attr "type" "shift,ild")]) - -(define_insn "" - [(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_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] - "TARGET_BWX" - "@ - zapnot %1,3,%0 - ldwu %0,%1" - [(set_attr "type" "shift,ild")]) - -(define_insn "" - [(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")))] - "" - "zapnot %1,15,%0" - [(set_attr "type" "shift")]) - -(define_insn "" - [(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")))] - "" - "bic %r2,%1,%0" - [(set_attr "type" "ilog")]) - -(define_insn "iordi3" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") - (match_operand:DI 2 "or_operand" "rI,N")))] - "" - "@ - bis %r1,%2,%0 - ornot %r1,%N2,%0" - [(set_attr "type" "ilog")]) - -(define_insn "one_cmpldi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))] - "" - "ornot $31,%1,%0" - [(set_attr "type" "ilog")]) - -(define_insn "" - [(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")))] - "" - "ornot %r2,%1,%0" - [(set_attr "type" "ilog")]) - -(define_insn "xordi3" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") - (match_operand:DI 2 "or_operand" "rI,N")))] - "" - "@ - xor %r1,%2,%0 - eqv %r1,%N2,%0" - [(set_attr "type" "ilog")]) - -(define_insn "" - [(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"))))] - "" - "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. - -(define_expand "ffsdi2" - [(set (match_dup 2) - (unspec [(match_operand:DI 1 "register_operand" "")] 1)) - (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 "" - [(set (match_operand:DI 0 "register_operand" "=r") - (unspec [(match_operand:DI 1 "register_operand" "r")] 1))] - "TARGET_CIX" - "cttz %1,%0" - ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just - ; reuse the existing type name. - [(set_attr "type" "mvi")]) - -;; Next come the shifts and the various extract and insert operations. - -(define_insn "ashldi3" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (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\"; - else - return \"s%P2addq %r1,0,%0\"; - case 1: - return \"sll %r1,%2,%0\"; - default: - abort(); - } -}" - [(set_attr "type" "iadd,shift")]) - -;; ??? The following pattern is made by combine, but earlier phases -;; (specifically flow) can't handle it. This occurs in jump.c. Deal -;; with this in a better way at some point. -;;(define_insn "" -;; [(set (match_operand:DI 0 "register_operand" "=r") -;; (sign_extend:DI -;; (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") -;; (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\"; -;; else -;; 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") - (match_operand:DI 2 "reg_or_6bit_operand" "rS")))] - "" - "srl %r1,%2,%0" - [(set_attr "type" "shift")]) - -(define_insn "ashrdi3" - [(set (match_operand:DI 0 "register_operand" "=r") - (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") - (match_operand:DI 2 "reg_or_6bit_operand" "rS")))] - "" - "sra %r1,%2,%0" - [(set_attr "type" "shift")]) - -(define_expand "extendqihi2" - [(set (match_dup 2) - (ashift:DI (match_operand:QI 1 "some_operand" "") - (const_int 56))) - (set (match_operand:HI 0 "register_operand" "") - (ashiftrt:DI (match_dup 2) - (const_int 56)))] - "" - " -{ - if (TARGET_BWX) - { - emit_insn (gen_extendqihi2x (operands[0], - 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)) - { - rtx temp = gen_reg_rtx (DImode); - - emit_insn (gen_extendqidi2 (temp, operands[1])); - emit_move_insn (operands[0], gen_lowpart (HImode, temp)); - DONE; - } - - 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") - (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))] - "TARGET_BWX" - "sextb %1,%0" - [(set_attr "type" "shift")]) - -(define_insn "extendhidi2x" - [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))] - "TARGET_BWX" - "sextw %1,%0" - [(set_attr "type" "shift")]) - -(define_insn "extendqisi2x" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] - "TARGET_BWX" - "sextb %1,%0" - [(set_attr "type" "shift")]) - -(define_insn "extendhisi2x" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] - "TARGET_BWX" - "sextw %1,%0" - [(set_attr "type" "shift")]) - -(define_insn "extendqihi2x" - [(set (match_operand:HI 0 "register_operand" "=r") - (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))] - "TARGET_BWX" - "sextb %1,%0" - [(set_attr "type" "shift")]) - -(define_expand "extendqisi2" - [(set (match_dup 2) - (ashift:DI (match_operand:QI 1 "some_operand" "") - (const_int 56))) - (set (match_operand:SI 0 "register_operand" "") - (ashiftrt:DI (match_dup 2) - (const_int 56)))] - "" - " -{ - if (TARGET_BWX) - { - emit_insn (gen_extendqisi2x (operands[0], - force_reg (QImode, operands[1]))); - DONE; - } - - /* If we have an unaligned MEM, extend to a DImode form of - the result (which we do specially). */ - if (unaligned_memory_operand (operands[1], QImode)) - { - rtx temp = gen_reg_rtx (DImode); - - emit_insn (gen_extendqidi2 (temp, operands[1])); - emit_move_insn (operands[0], gen_lowpart (SImode, temp)); - DONE; - } - - 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) - (ashift:DI (match_operand:QI 1 "some_operand" "") - (const_int 56))) - (set (match_operand:DI 0 "register_operand" "") - (ashiftrt:DI (match_dup 2) - (const_int 56)))] - "" - " -{ - if (TARGET_BWX) - { - emit_insn (gen_extendqidi2x (operands[0], - force_reg (QImode, operands[1]))); - DONE; - } - - if (unaligned_memory_operand (operands[1], QImode)) - { - rtx seq - = gen_unaligned_extendqidi (operands[0], - get_unaligned_address (operands[1], 1)); - - alpha_set_memflags (seq, operands[1]); - emit_insn (seq); - DONE; - } - - operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1])); - operands[2] = gen_reg_rtx (DImode); -}") - -(define_expand "extendhisi2" - [(set (match_dup 2) - (ashift:DI (match_operand:HI 1 "some_operand" "") - (const_int 48))) - (set (match_operand:SI 0 "register_operand" "") - (ashiftrt:DI (match_dup 2) - (const_int 48)))] - "" - " -{ - if (TARGET_BWX) - { - emit_insn (gen_extendhisi2x (operands[0], - force_reg (HImode, operands[1]))); - DONE; - } - - /* If we have an unaligned MEM, extend to a DImode form of - the result (which we do specially). */ - if (unaligned_memory_operand (operands[1], HImode)) - { - rtx temp = gen_reg_rtx (DImode); - - emit_insn (gen_extendhidi2 (temp, operands[1])); - emit_move_insn (operands[0], gen_lowpart (SImode, temp)); - DONE; - } - - 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) - (ashift:DI (match_operand:HI 1 "some_operand" "") - (const_int 48))) - (set (match_operand:DI 0 "register_operand" "") - (ashiftrt:DI (match_dup 2) - (const_int 48)))] - "" - " -{ - if (TARGET_BWX) - { - emit_insn (gen_extendhidi2x (operands[0], - force_reg (HImode, operands[1]))); - DONE; - } - - if (unaligned_memory_operand (operands[1], HImode)) - { - rtx seq - = gen_unaligned_extendhidi (operands[0], - get_unaligned_address (operands[1], 2)); - - alpha_set_memflags (seq, operands[1]); - emit_insn (seq); - DONE; - } - - 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 -;; the unaligned loads (see below). -;; -;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result. -(define_expand "unaligned_extendqidi" - [(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) - (ashift:DI - (and:DI (plus:DI (match_dup 2) (const_int -1)) - (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); - operands[3] = gen_reg_rtx (DImode); - operands[4] = gen_reg_rtx (DImode); -}") - -(define_expand "unaligned_extendhidi" - [(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) - (ashift:DI - (and:DI (plus:DI (match_dup 2) (const_int -1)) - (const_int 7)) - (const_int 3))))) - (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0) - (ashiftrt:DI (match_dup 4) (const_int 48)))] - "" - " -{ operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_reg_rtx (DImode); - operands[4] = gen_reg_rtx (DImode); -}") - -(define_insn "" - [(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") - (match_operand:DI 3 "mul8_operand" "I")))] - "" - "ext%M2l %r1,%s3,%0" - [(set_attr "type" "shift")]) - -(define_insn "extxl" - [(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))))] - "" - "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 -;; should have turned into zero_extracts. - -(define_insn "" - [(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))) - (match_operand:DI 3 "mode_mask_operand" "n")))] - "" - "ext%U3l %1,%2,%0" - [(set_attr "type" "shift")]) - -(define_insn "" - [(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))))] - "" - "extql %1,%2,%0" - [(set_attr "type" "shift")]) - -(define_insn "extqh" - [(set (match_operand:DI 0 "register_operand" "=r") - (ashift:DI - (match_operand:DI 1 "reg_or_0_operand" "rJ") - (minus:DI (const_int 56) - (ashift:DI - (and:DI - (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") - (const_int -1)) - (const_int 7)) - (const_int 3)))))] - "" - "extqh %r1,%2,%0" - [(set_attr "type" "shift")]) - -(define_insn "extlh" - [(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) - (ashift:DI - (and:DI - (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") - (const_int -1)) - (const_int 7)) - (const_int 3)))))] - "" - "extlh %r1,%2,%0" - [(set_attr "type" "shift")]) - -(define_insn "extwh" - [(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) - (ashift:DI - (and:DI - (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") - (const_int -1)) - (const_int 7)) - (const_int 3)))))] - "" - "extwh %r1,%2,%0" - [(set_attr "type" "shift")]) - -;; This converts an extXl into an extXh with an appropriate adjustment -;; to the address calculation. - -;;(define_split -;; [(set (match_operand:DI 0 "register_operand" "") -;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "") -;; (match_operand:DI 2 "mode_width_operand" "") -;; (ashift:DI (match_operand:DI 3 "" "") -;; (const_int 3))) -;; (match_operand:DI 4 "const_int_operand" ""))) -;; (clobber (match_operand:DI 5 "register_operand" ""))] -;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])" -;; [(set (match_dup 5) (match_dup 6)) -;; (set (match_dup 0) -;; (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2) -;; (ashift:DI (plus:DI (match_dup 5) -;; (match_dup 7)) -;; (const_int 3))) -;; (match_dup 4)))] -;; " -;;{ -;; operands[6] = plus_constant (operands[3], -;; INTVAL (operands[2]) / BITS_PER_UNIT); -;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT); -;;}") - -(define_insn "" - [(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")))] - "" - "insbl %1,%s2,%0" - [(set_attr "type" "shift")]) - -(define_insn "" - [(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")))] - "" - "inswl %1,%s2,%0" - [(set_attr "type" "shift")]) - -(define_insn "" - [(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")))] - "" - "insll %1,%s2,%0" - [(set_attr "type" "shift")]) - -(define_insn "insbl" - [(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))))] - "" - "insbl %1,%2,%0" - [(set_attr "type" "shift")]) - -(define_insn "inswl" - [(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))))] - "" - "inswl %1,%2,%0" - [(set_attr "type" "shift")]) - -(define_insn "insll" - [(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))))] - "" - "insll %1,%2,%0" - [(set_attr "type" "shift")]) - -(define_insn "insql" - [(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))))] - "" - "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 "" - [(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")) - (match_operand:DI 3 "immediate_operand" "i")))] - "HOST_BITS_PER_WIDE_INT == 64 - && GET_CODE (operands[3]) == CONST_INT - && (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2]) - == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) - || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2]) - == (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\"; - if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2]) - == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) - 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\"; -#endif - abort(); -}" - [(set_attr "type" "shift")]) - -;; We do not include the insXh insns because they are complex to express -;; and it does not appear that we would ever want to generate them. -;; -;; Since we need them for block moves, though, cop out and use unspec. - -(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))] - "" - "ins%M2h %1,%3,%0" - [(set_attr "type" "shift")]) - -(define_insn "mskxl" - [(set (match_operand:DI 0 "register_operand" "=r") - (and:DI (not:DI (ashift:DI - (match_operand:DI 2 "mode_mask_operand" "n") - (ashift:DI - (match_operand:DI 3 "reg_or_8bit_operand" "rI") - (const_int 3)))) - (match_operand:DI 1 "reg_or_0_operand" "rJ")))] - "" - "msk%U2l %r1,%3,%0" - [(set_attr "type" "shift")]) - -;; We do not include the mskXh insns because it does not appear we would -;; ever generate one. -;; -;; Again, we do for block moves and we use unspec again. - -(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))] - "" - "msk%M2h %1,%3,%0" - [(set_attr "type" "shift")]) - -;; Floating-point operations. All the double-precision insns can extend -;; from single, so indicate that. The exception are the ones that simply -;; play with the sign bits; it's not clear what to do there. - -(define_insn "abssf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] - "TARGET_FP" - "cpys $f31,%R1,%0" - [(set_attr "type" "fcpys")]) - -(define_insn "absdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] - "TARGET_FP" - "cpys $f31,%R1,%0" - [(set_attr "type" "fcpys")]) - -(define_insn "negsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] - "TARGET_FP" - "cpysn %R1,%R1,%0" - [(set_attr "type" "fadd")]) - -(define_insn "negdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] - "TARGET_FP" - "cpysn %R1,%R1,%0" - [(set_attr "type" "fadd")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -;; Define conversion operators between DFmode and SImode, using the cvtql -;; instruction. To allow combine et al to do useful things, we keep the -;; operation as a unit until after reload, at which point we split the -;; instructions. -;; -;; Note that we (attempt to) only consider this optimization when the -;; ultimate destination is memory. If we will be doing further integer -;; processing, it is cheaper to do the truncation in the int regs. - -(define_insn "*cvtql" - [(set (match_operand:SI 0 "register_operand" "=f") - (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")] 5))] - "TARGET_FP" - "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))] - "") - -(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 "" - [(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" - "#" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - "#" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -;; 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 "" - [(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" - "#" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - "#" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_expand "extendsfdf2" - [(use (match_operand:DF 0 "register_operand" "")) - (use (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])); - - DONE; -}") -;; FIXME -(define_insn "extendsfdf2_tp" - [(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" - "cvtsts %1,%0" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "extendsfdf2_no_tp" - [(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" - "@ - fmov %1,%0 - ld%, %0,%1 - st%- %1,%0" - [(set_attr "type" "fcpys,fld,fst") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fdiv") - (set_attr "opsize" "si") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fdiv") - (set_attr "opsize" "si") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fdiv") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fdiv") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fdiv") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fdiv") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fdiv") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fmul") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fmul") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fmul") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fmul") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fmul") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fmul") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fsqrt") - (set_attr "opsize" "si") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fsqrt") - (set_attr "opsize" "si") - (set_attr "trap" "yes")]) - -(define_insn "" - [(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" - [(set_attr "type" "fsqrt") - (set_attr "trap" "yes")]) - -(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" - [(set_attr "type" "fsqrt") - (set_attr "trap" "yes")]) - -;; 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") - (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))] - "" - "cmp%C1 %r2,%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") - (match_operand:DI 3 "reg_or_0_operand" "rJ")]))] - "" - "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. - -(define_insn "" - [(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" - "@ - 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 "" - [(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" - "@ - 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 "" - [(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") - (const_int 1) - (const_int 0)) - (const_int 0)) - (match_operand:DI 1 "reg_or_8bit_operand" "rI,0") - (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))] - "" - "@ - cmovlbc %r2,%1,%0 - cmovlbs %r2,%3,%0" - [(set_attr "type" "icmov")]) - -(define_insn "" - [(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") - (const_int 1) - (const_int 0)) - (const_int 0)) - (match_operand:DI 1 "reg_or_8bit_operand" "rI,0") - (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))] - "" - "@ - cmovlbs %r2,%1,%0 - cmovlbc %r2,%3,%0" - [(set_attr "type" "icmov")]) - -;; For ABS, we have two choices, depending on whether the input and output -;; registers are the same or not. -(define_expand "absdi2" - [(set (match_operand:DI 0 "register_operand" "") - (abs:DI (match_operand:DI 1 "register_operand" "")))] - "" - " -{ 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" "") - (neg:DI (match_operand:DI 0 "register_operand" ""))) - (set (match_dup 0) - (if_then_else:DI (ge (match_dup 0) (const_int 0)) - (match_dup 0) - (match_dup 1)))] - "" - "") - -(define_expand "absdi2_diff" - [(set (match_operand:DI 0 "register_operand" "") - (neg:DI (match_operand:DI 1 "register_operand" ""))) - (set (match_dup 0) - (if_then_else:DI (lt (match_dup 1) (const_int 0)) - (match_dup 0) - (match_dup 1)))] - "" - "") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (abs:DI (match_dup 0))) - (clobber (match_operand:DI 2 "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)) - (match_dup 0) (match_dup 1)))] - "") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (abs:DI (match_operand:DI 1 "register_operand" "")))] - "! rtx_equal_p (operands[0], operands[1])" - [(set (match_dup 0) (neg:DI (match_dup 1))) - (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0)) - (match_dup 0) (match_dup 1)))] - "") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (neg:DI (abs:DI (match_dup 0)))) - (clobber (match_operand:DI 2 "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)) - (match_dup 0) (match_dup 1)))] - "") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))] - "! rtx_equal_p (operands[0], operands[1])" - [(set (match_dup 0) (neg:DI (match_dup 1))) - (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0)) - (match_dup 0) (match_dup 1)))] - "") - -(define_insn "sminqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") - (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] - "TARGET_MAX" - "minsb8 %r1,%2,%0" - [(set_attr "type" "mvi")]) - -(define_insn "uminqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") - (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] - "TARGET_MAX" - "minub8 %r1,%2,%0" - [(set_attr "type" "mvi")]) - -(define_insn "smaxqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") - (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] - "TARGET_MAX" - "maxsb8 %r1,%2,%0" - [(set_attr "type" "mvi")]) - -(define_insn "umaxqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") - (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] - "TARGET_MAX" - "maxub8 %r1,%2,%0" - [(set_attr "type" "mvi")]) - -(define_insn "sminhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") - (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] - "TARGET_MAX" - "minsw4 %r1,%2,%0" - [(set_attr "type" "mvi")]) - -(define_insn "uminhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") - (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] - "TARGET_MAX" - "minuw4 %r1,%2,%0" - [(set_attr "type" "mvi")]) - -(define_insn "smaxhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") - (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] - "TARGET_MAX" - "maxsw4 %r1,%2,%0" - [(set_attr "type" "mvi")]) - -(define_insn "umaxhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") - (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] - "TARGET_MAX" - "maxuw4 %r1,%2,%0" - [(set_attr "type" "shift")]) - -(define_expand "smaxdi3" - [(set (match_dup 3) - (le: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); -}") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (smax:DI (match_operand:DI 1 "reg_or_0_operand" "") - (match_operand:DI 2 "reg_or_8bit_operand" ""))) - (clobber (match_operand:DI 3 "register_operand" ""))] - "operands[2] != const0_rtx" - [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0)) - (match_dup 1) (match_dup 2)))] - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (smax:DI (match_operand:DI 1 "register_operand" "0") - (const_int 0)))] - "" - "cmovlt %0,0,%0" - [(set_attr "type" "icmov")]) - -(define_expand "smindi3" - [(set (match_dup 3) - (lt: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 (ne (match_dup 3) (const_int 0)) - (match_dup 1) (match_dup 2)))] - "" - " -{ operands[3] = gen_reg_rtx (DImode); -}") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (smin:DI (match_operand:DI 1 "reg_or_0_operand" "") - (match_operand:DI 2 "reg_or_8bit_operand" ""))) - (clobber (match_operand:DI 3 "register_operand" ""))] - "operands[2] != const0_rtx" - [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0)) - (match_dup 1) (match_dup 2)))] - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (smin:DI (match_operand:DI 1 "register_operand" "0") - (const_int 0)))] - "" - "cmovgt %0,0,%0" - [(set_attr "type" "icmov")]) - -(define_expand "umaxdi3" - [(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); -}") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (umax:DI (match_operand:DI 1 "reg_or_0_operand" "") - (match_operand:DI 2 "reg_or_8bit_operand" ""))) - (clobber (match_operand:DI 3 "register_operand" ""))] - "operands[2] != const0_rtx" - [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0)) - (match_dup 1) (match_dup 2)))] - "") - -(define_expand "umindi3" - [(set (match_dup 3) - (ltu: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 (ne (match_dup 3) (const_int 0)) - (match_dup 1) (match_dup 2)))] - "" - " -{ operands[3] = gen_reg_rtx (DImode); -}") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (umin:DI (match_operand:DI 1 "reg_or_0_operand" "") - (match_operand:DI 2 "reg_or_8bit_operand" ""))) - (clobber (match_operand:DI 3 "register_operand" ""))] - "operands[2] != const0_rtx" - [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0)) - (match_dup 1) (match_dup 2)))] - "") - -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 1 "signed_comparison_operator" - [(match_operand:DI 2 "reg_or_0_operand" "rJ") - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "b%C1 %r2,%0" - [(set_attr "type" "ibr")]) - -(define_insn "" - [(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)))] - "" - "b%c1 %2,%0" - [(set_attr "type" "ibr")]) - -(define_insn "" - [(set (pc) - (if_then_else - (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") - (const_int 1) - (const_int 0)) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "blbs %r1,%0" - [(set_attr "type" "ibr")]) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") - (const_int 1) - (const_int 0)) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "blbc %r1,%0" - [(set_attr "type" "ibr")]) - -(define_split - [(parallel - [(set (pc) - (if_then_else - (match_operator 1 "comparison_operator" - [(zero_extract:DI (match_operand:DI 2 "register_operand" "") - (const_int 1) - (match_operand:DI 3 "const_int_operand" "")) - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc))) - (clobber (match_operand:DI 4 "register_operand" ""))])] - "INTVAL (operands[3]) != 0" - [(set (match_dup 4) - (lshiftrt:DI (match_dup 2) (match_dup 3))) - (set (pc) - (if_then_else (match_op_dup 1 - [(zero_extract:DI (match_dup 4) - (const_int 1) - (const_int 0)) - (const_int 0)]) - (label_ref (match_dup 0)) - (pc)))] - "") - -;; The following are the corresponding floating-point insns. Recall -;; we need to have variants that expand the arguments from SF mode -;; to DFmode. - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=&f") - (match_operator:DF 1 "alpha_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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 1 "alpha_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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=&f") - (match_operator:DF 1 "alpha_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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 1 "alpha_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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=&f") - (match_operator:DF 1 "alpha_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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 1 "alpha_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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=&f") - (match_operator:DF 1 "alpha_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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 1 "alpha_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" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (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")]) - (match_operand:DF 1 "reg_or_fp0_operand" "fG,0") - (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] - "TARGET_FP" - "@ - fcmov%C3 %R4,%R1,%0 - fcmov%D3 %R4,%R5,%0" - [(set_attr "type" "fcmov")]) - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (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")]) - (match_operand:SF 1 "reg_or_fp0_operand" "fG,0") - (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))] - "TARGET_FP" - "@ - fcmov%C3 %R4,%R1,%0 - fcmov%D3 %R4,%R5,%0" - [(set_attr "type" "fcmov")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (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")]) - (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")) - (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] - "TARGET_FP" - "@ - fcmov%C3 %R4,%R1,%0 - fcmov%D3 %R4,%R5,%0" - [(set_attr "type" "fcmov")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (if_then_else:DF - (match_operator 3 "signed_comparison_operator" - [(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") - (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] - "TARGET_FP" - "@ - fcmov%C3 %R4,%R1,%0 - fcmov%D3 %R4,%R5,%0" - [(set_attr "type" "fcmov")]) - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (if_then_else:SF - (match_operator 3 "signed_comparison_operator" - [(float_extend:DF - (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG")) - (match_operand:DF 2 "fp0_operand" "G,G")]) - (match_operand:SF 1 "reg_or_fp0_operand" "fG,0") - (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))] - "TARGET_FP" - "@ - fcmov%C3 %R4,%R1,%0 - fcmov%D3 %R4,%R5,%0" - [(set_attr "type" "fcmov")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (if_then_else:DF - (match_operator 3 "signed_comparison_operator" - [(float_extend:DF - (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG")) - (match_operand:DF 2 "fp0_operand" "G,G")]) - (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")) - (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] - "TARGET_FP" - "@ - fcmov%C3 %R4,%R1,%0 - fcmov%D3 %R4,%R5,%0" - [(set_attr "type" "fcmov")]) - -(define_expand "maxdf3" - [(set (match_dup 3) - (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "") - (match_operand:DF 2 "reg_or_fp0_operand" ""))) - (set (match_operand:DF 0 "register_operand" "") - (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[4] = CONST0_RTX (DFmode); -}") - -(define_expand "mindf3" - [(set (match_dup 3) - (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "") - (match_operand:DF 2 "reg_or_fp0_operand" ""))) - (set (match_operand:DF 0 "register_operand" "") - (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[4] = CONST0_RTX (DFmode); -}") - -(define_expand "maxsf3" - [(set (match_dup 3) - (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "")) - (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "")))) - (set (match_operand:SF 0 "register_operand" "") - (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[4] = CONST0_RTX (DFmode); -}") - -(define_expand "minsf3" - [(set (match_dup 3) - (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "")) - (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "")))) - (set (match_operand:SF 0 "register_operand" "") - (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[4] = CONST0_RTX (DFmode); -}") - -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 1 "signed_comparison_operator" - [(match_operand:DF 2 "reg_or_fp0_operand" "fG") - (match_operand:DF 3 "fp0_operand" "G")]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_FP" - "fb%C1 %R2,%0" - [(set_attr "type" "fbr")]) - -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 1 "signed_comparison_operator" - [(float_extend:DF - (match_operand:SF 2 "reg_or_fp0_operand" "fG")) - (match_operand:DF 3 "fp0_operand" "G")]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_FP" - "fb%C1 %R2,%0" - [(set_attr "type" "fbr")]) - -;; These are the main define_expand's used to make conditional branches -;; and compares. - -(define_expand "cmpdf" - [(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; - DONE; -}") - -(define_expand "cmpdi" - [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "") - (match_operand:DI 1 "reg_or_8bit_operand" "")))] - "" - " -{ - alpha_compare_op0 = operands[0]; - alpha_compare_op1 = operands[1]; - alpha_compare_fp_p = 0; - DONE; -}") - -(define_expand "beq" - [(set (pc) - (if_then_else (match_dup 1) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "{ operands[1] = alpha_emit_conditional_branch (EQ); }") - -(define_expand "bne" - [(set (pc) - (if_then_else (match_dup 1) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "{ operands[1] = alpha_emit_conditional_branch (NE); }") - -(define_expand "blt" - [(set (pc) - (if_then_else (match_dup 1) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "{ operands[1] = alpha_emit_conditional_branch (LT); }") - -(define_expand "ble" - [(set (pc) - (if_then_else (match_dup 1) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "{ operands[1] = alpha_emit_conditional_branch (LE); }") - -(define_expand "bgt" - [(set (pc) - (if_then_else (match_dup 1) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "{ operands[1] = alpha_emit_conditional_branch (GT); }") - -(define_expand "bge" - [(set (pc) - (if_then_else (match_dup 1) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "{ operands[1] = alpha_emit_conditional_branch (GE); }") - -(define_expand "bltu" - [(set (pc) - (if_then_else (match_dup 1) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "{ operands[1] = alpha_emit_conditional_branch (LTU); }") - -(define_expand "bleu" - [(set (pc) - (if_then_else (match_dup 1) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "{ operands[1] = alpha_emit_conditional_branch (LEU); }") - -(define_expand "bgtu" - [(set (pc) - (if_then_else (match_dup 1) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "{ operands[1] = alpha_emit_conditional_branch (GTU); }") - -(define_expand "bgeu" - [(set (pc) - (if_then_else (match_dup 1) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "{ operands[1] = alpha_emit_conditional_branch (GEU); }") - -(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); -}") - -(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)))] - "" - " -{ - if (alpha_compare_fp_p) - FAIL; - - operands[1] = gen_rtx_EQ (DImode, alpha_compare_op0, alpha_compare_op1); -}") - -(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); -}") - -(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); -}") - -(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); -}") - -(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); -}") - -(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); -}") - -(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); -}") - -(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); -}") - -(define_expand "sgeu" - [(set (match_operand:DI 0 "register_operand" "") - (match_dup 1))] - "" - " -{ - if (alpha_compare_fp_p) - FAIL; - - operands[1] = gen_rtx_LEU (DImode, force_reg (DImode, alpha_compare_op1), - alpha_compare_op0); -}") - -;; These are the main define_expand's used to make conditional moves. - -(define_expand "movsicc" - [(set (match_operand:SI 0 "register_operand" "") - (if_then_else:SI (match_operand 1 "comparison_operator" "") - (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" "") - (if_then_else:DI (match_operand 1 "comparison_operator" "") - (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" "") - (if_then_else:SF (match_operand 1 "comparison_operator" "") - (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" "") - (if_then_else:DF (match_operand 1 "comparison_operator" "") - (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 -;; comparison. For example, x >= 7 has to be done as x < 6 with the -;; comparison that tests the result being reversed. We have one define_split -;; for each use of a comparison. They do not match valid insns and need -;; not generate valid insns. -;; -;; We can also handle equality comparisons (and inequality comparisons in -;; cases where the resulting add cannot overflow) by doing an add followed by -;; a comparison with zero. This is faster since the addition takes one -;; less cycle than a compare when feeding into a conditional move. -;; For this case, we also have an SImode pattern since we can merge the add -;; and sign extend and the order doesn't matter. -;; -;; We do not do this for floating-point, since it isn't clear how the "wrong" -;; operation could have been generated. - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (if_then_else:DI - (match_operator 1 "comparison_operator" - [(match_operand:DI 2 "reg_or_0_operand" "") - (match_operand:DI 3 "reg_or_cint_operand" "")]) - (match_operand:DI 4 "reg_or_cint_operand" "") - (match_operand:DI 5 "reg_or_cint_operand" ""))) - (clobber (match_operand:DI 6 "register_operand" ""))] - "operands[3] != const0_rtx" - [(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]); - int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU); - - /* If we are comparing for equality with a constant and that constant - appears in the arm when the register equals the constant, use the - register since that is more likely to match (and to produce better code - if both would). */ - - if (code == EQ && GET_CODE (operands[3]) == CONST_INT - && rtx_equal_p (operands[4], operands[3])) - operands[4] = operands[2]; - - else if (code == NE && GET_CODE (operands[3]) == CONST_INT - && rtx_equal_p (operands[5], operands[3])) - operands[5] = operands[2]; - - if (code == NE || code == EQ - || (extended_count (operands[2], DImode, unsignedp) >= 1 - && extended_count (operands[3], DImode, unsignedp) >= 1)) - { - if (GET_CODE (operands[3]) == CONST_INT) - operands[7] = gen_rtx_PLUS (DImode, operands[2], - GEN_INT (- INTVAL (operands[3]))); - else - operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]); - - operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx); - } - - else if (code == EQ || code == LE || code == LT - || code == LEU || code == LTU) - { - operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]); - operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx); - } - else - { - operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode, - operands[2], operands[3]); - operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx); - } -}") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (if_then_else:DI - (match_operator 1 "comparison_operator" - [(match_operand:SI 2 "reg_or_0_operand" "") - (match_operand:SI 3 "reg_or_cint_operand" "")]) - (match_operand:DI 4 "reg_or_8bit_operand" "") - (match_operand:DI 5 "reg_or_8bit_operand" ""))) - (clobber (match_operand:DI 6 "register_operand" ""))] - "operands[3] != const0_rtx - && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)" - [(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]); - int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU); - rtx tem; - - if ((code != NE && code != EQ - && ! (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]))); - else - tem = gen_rtx_MINUS (SImode, operands[2], operands[3]); - - 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) - (if_then_else - (match_operator 1 "comparison_operator" - [(match_operand:DI 2 "reg_or_0_operand" "") - (match_operand:DI 3 "reg_or_cint_operand" "")]) - (label_ref (match_operand 0 "" "")) - (pc))) - (clobber (match_operand:DI 4 "register_operand" ""))] - "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]); - int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU); - - if (code == NE || code == EQ - || (extended_count (operands[2], DImode, unsignedp) >= 1 - && extended_count (operands[3], DImode, unsignedp) >= 1)) - { - if (GET_CODE (operands[3]) == CONST_INT) - operands[5] = gen_rtx_PLUS (DImode, operands[2], - GEN_INT (- INTVAL (operands[3]))); - else - operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]); - - operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx); - } - - else if (code == EQ || code == LE || code == LT - || code == LEU || code == LTU) - { - operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]); - operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx); - } - else - { - operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode, - operands[2], operands[3]); - operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx); - } -}") - -(define_split - [(set (pc) - (if_then_else - (match_operator 1 "comparison_operator" - [(match_operand:SI 2 "reg_or_0_operand" "") - (match_operand:SI 3 "const_int_operand" "")]) - (label_ref (match_operand 0 "" "")) - (pc))) - (clobber (match_operand:DI 4 "register_operand" ""))] - "operands[3] != const0_rtx - && (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; - - 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_operand:DI 2 "register_operand" "") - (match_operand:DI 3 "const_int_operand" "")])) - (clobber (match_operand:DI 4 "register_operand" ""))] - "exact_log2 (INTVAL (operands[3]) + 1) >= 0 - && (GET_CODE (operands[1]) == GTU - || GET_CODE (operands[1]) == LEU - || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE) - && 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); -}") - -;; Here are the CALL and unconditional branch insns. Calls on NT and OSF -;; work differently, so we have different patterns for each. - -(define_expand "call" - [(use (match_operand:DI 0 "" "")) - (use (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" ""))] - "" - " -{ if (TARGET_WINDOWS_NT) - emit_call_insn (gen_call_nt (operands[0], operands[1])); - else if (TARGET_OPEN_VMS) - emit_call_insn (gen_call_vms (operands[0], operands[2])); - else - emit_call_insn (gen_call_osf (operands[0], operands[1])); - - DONE; -}") - -(define_expand "call_osf" - [(parallel [(call (mem:DI (match_operand 0 "" "")) - (match_operand 1 "" "")) - (clobber (reg:DI 27)) - (clobber (reg:DI 26))])] - "" - " -{ 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; - } -}") - -(define_expand "call_nt" - [(parallel [(call (mem:DI (match_operand 0 "" "")) - (match_operand 1 "" "")) - (clobber (reg:DI 26))])] - "" - " -{ 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]); -}") - -;; -;; call openvms/alpha -;; op 0: symbol ref for called function -;; op 1: next_arg_reg (argument information value for R25) -;; -(define_expand "call_vms" - [(parallel [(call (mem:DI (match_operand 0 "" "")) - (match_operand 1 "" "")) - (use (match_dup 2)) - (use (reg:DI 25)) - (use (reg:DI 26)) - (clobber (reg:DI 27))])] - "" - " -{ if (GET_CODE (operands[0]) != MEM) - abort (); - - operands[0] = XEXP (operands[0], 0); - - /* Always load AI with argument information, then handle symbolic and - indirect call differently. Load RA and set operands[2] to PV in - both cases. */ - - 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); - - 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))); - } - else - { - 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 "" "")) - (use (match_operand:DI 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" "")) - (use (match_operand 4 "" ""))] - "" - " -{ if (TARGET_WINDOWS_NT) - emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2])); - else if (TARGET_OPEN_VMS) - emit_call_insn (gen_call_value_vms (operands[0], operands[1], - operands[3])); - else - emit_call_insn (gen_call_value_osf (operands[0], operands[1], - operands[2])); - DONE; -}") - -(define_expand "call_value_osf" - [(parallel [(set (match_operand 0 "" "") - (call (mem:DI (match_operand 1 "" "")) - (match_operand 2 "" ""))) - (clobber (reg:DI 27)) - (clobber (reg:DI 26))])] - "" - " -{ 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; - } -}") - -(define_expand "call_value_nt" - [(parallel [(set (match_operand 0 "" "") - (call (mem:DI (match_operand 1 "" "")) - (match_operand 2 "" ""))) - (clobber (reg:DI 26))])] - "" - " -{ 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 "" "") - (call (mem:DI (match_operand:DI 1 "" "")) - (match_operand 2 "" ""))) - (use (match_dup 3)) - (use (reg:DI 25)) - (use (reg:DI 26)) - (clobber (reg:DI 27))])] - "" - " -{ if (GET_CODE (operands[1]) != MEM) - abort (); - - operands[1] = XEXP (operands[1], 0); - - /* Always load AI with argument information, then handle symbolic and - indirect call differently. Load RA and set operands[3] to PV in - both cases. */ - - 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); - - 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))); - } - else - { - emit_move_insn (gen_rtx_REG (Pmode, 26), - gen_rtx_MEM (Pmode, plus_constant (operands[1], 8))); - - operands[3] = operands[1]; - } -}") - -(define_insn "" - [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i")) - (match_operand 1 "" "")) - (clobber (reg:DI 27)) - (clobber (reg:DI 26))] - "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS" - "@ - jsr $26,($27),0\;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 "" - [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i")) - (match_operand 1 "" "")) - (clobber (reg:DI 26))] - "TARGET_WINDOWS_NT" - "@ - jsr $26,(%0) - bsr $26,%0 - 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")]) - -(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)) - (clobber (reg:DI 26))] - "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS" - "@ - 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 "" - [(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 26))] - "TARGET_WINDOWS_NT" - "@ - jsr $26,(%1) - bsr $26,%1 - jsr $26,%1" - [(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")) - (use (reg:DI 25)) - (use (reg:DI 26)) - (clobber (reg:DI 27))] - "TARGET_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")]) - -;; Call subroutine returning any type. - -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" - " -{ - int i; - - emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - 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)] - "" - "" - [(set_attr "length" "0")]) - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "br $31,%l0" - [(set_attr "type" "ibr")]) - -(define_insn "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)] - "" - "ret $31,($26),1" - [(set_attr "type" "ibr")]) - -(define_insn "indirect_jump" - [(set (pc) (match_operand:DI 0 "register_operand" "r"))] - "" - "jmp $31,(%0),0" - [(set_attr "type" "ibr")]) - -(define_expand "tablejump" - [(use (match_operand:SI 0 "register_operand" "")) - (use (match_operand:SI 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) - { - 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[3] = best_label; - return \"addq %0,$29,%2\;jmp $31,(%2),%3\"; - } - else - return \"addq %0,$29,%2\;jmp $31,(%2),0\"; -}" - [(set_attr "type" "ibr") - (set_attr "length" "8")]) - -(define_insn "" - [(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\"; -}" - [(set_attr "type" "ibr")]) - -;; -;; op 0 is table offset -;; op 1 is table label -;; - -(define_insn "" - [(set (pc) - (plus:DI (match_operand 0 "register_operand" "r") - (label_ref (match_operand 1 "" ""))))] - "TARGET_OPEN_VMS" - "jmp $31,(%0),0" - [(set_attr "type" "ibr")]) - -;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't -;; want to have to include pal.h in our .s file. -;; -;; Technically the type for call_pal is jsr, but we use that for determining -;; 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)] - "" - "call_pal 0x86" - [(set_attr "type" "ibr")]) - -;; Finally, we have the basic data motion insns. The byte and word insns -;; 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 - && (register_operand (operands[0], SFmode) - || reg_or_fp0_operand (operands[1], SFmode))" - "@ - fmov %R1,%0 - ld%, %0,%1 - mov %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 - && (register_operand (operands[0], SFmode) - || reg_or_fp0_operand (operands[1], SFmode))" - "@ - fmov %R1,%0 - ld%, %0,%1 - mov %r1,%0 - ldl %0,%1 - st%, %R1,%0 - stl %r1,%0 - itofs %1,%0 - 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 - && (register_operand (operands[0], DFmode) - || reg_or_fp0_operand (operands[1], DFmode))" - "@ - fmov %R1,%0 - ld%- %0,%1 - mov %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 - && (register_operand (operands[0], DFmode) - || reg_or_fp0_operand (operands[1], DFmode))" - "@ - fmov %R1,%0 - ld%- %0,%1 - mov %r1,%0 - ldq %0,%1 - st%- %R1,%0 - stq %r1,%0 - itoft %1,%0 - ftoit %1,%0" - [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")]) - -(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 - && (register_operand (operands[0], SImode) - || reg_or_0_operand (operands[1], SImode))" - "@ - mov %r1,%0 - lda %0,%1 - ldah %0,%h1 - ldl %0,%1 - stl %r1,%0 - fmov %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 - && (register_operand (operands[0], SImode) - || reg_or_0_operand (operands[1], SImode))" - "@ - mov %r1,%0 - lda %0,%1 - ldah %0,%h1 - ldl %0,%1 - stl %r1,%0 - fmov %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) - && (register_operand (operands[0], SImode) - || reg_or_0_operand (operands[1], SImode))" - "@ - mov %1,%0 - lda %0,%1 - ldah %0,%h1 - lda %0,%1 - ldl %0,%1 - stl %r1,%0 - fmov %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"))] - "! 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")]) - -(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"))] - "TARGET_BWX - && (register_operand (operands[0], HImode) - || reg_or_0_operand (operands[1], HImode))" - "@ - mov %r1,%0 - lda %0,%L1 - ldwu %0,%1 - stw %r1,%0 - fmov %R1,%0" - [(set_attr "type" "ilog,iadd,ild,ist,fcpys")]) - -(define_insn "" - [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,f") - (match_operand:QI 1 "input_operand" "rJ,n,fJ"))] - "! 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")]) - -(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"))] - "TARGET_BWX - && (register_operand (operands[0], QImode) - || reg_or_0_operand (operands[1], QImode))" - "@ - mov %r1,%0 - lda %0,%L1 - ldbu %0,%1 - stb %r1,%0 - fmov %R1,%0" - [(set_attr "type" "ilog,iadd,ild,ist,fcpys")]) - -;; We do two major things here: handle mem->mem and construct long -;; constants. - -(define_expand "movsi" - [(set (match_operand:SI 0 "general_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; - } -}") - -;; Split a load of a large constant into the appropriate two-insn -;; sequence. - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "const_int_operand" ""))] - "! 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 - = 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 - && (register_operand (operands[0], DImode) - || reg_or_0_operand (operands[1], DImode))" - "@ - mov %r1,%0 - lda %0,%1 - ldah %0,%h1 - lda %0,%1 - 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")]) - -(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 - && (register_operand (operands[0], DImode) - || reg_or_0_operand (operands[1], DImode))" - "@ - mov %r1,%0 - lda %0,%1 - ldah %0,%h1 - lda %0,%1 - 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,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")]) - -;; 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" "") - (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 (); -}") - -;; Split a load of a large constant into the appropriate two-insn -;; sequence. - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (match_operand:DI 1 "const_int_operand" ""))] - "! 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 - = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2); - - if (tem == operands[0]) - DONE; - else - FAIL; -}") - -;; These are the partial-word cases. -;; -;; First we have the code to load an aligned word. Operand 0 is the register -;; in which to place the result. It's mode is QImode or HImode. Operand 1 -;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the -;; number of bits within the word that the value is. Operand 3 is an SImode -;; scratch register. If operand 0 is a hard register, operand 3 may be the -;; same register. It is allowed to conflict with operand 1 as well. - -(define_expand "aligned_loadqi" - [(set (match_operand:SI 3 "register_operand" "") - (match_operand:SI 1 "memory_operand" "")) - (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0) - (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" "")) - (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0) - (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. -;; -;; 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" - [(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) - (ashift:DI (match_dup 3) (const_int 3))))] - "" - "") - -(define_expand "unaligned_loadhi" - [(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 16) - (ashift:DI (match_dup 3) (const_int 3))))] - "" - "") - -;; Storing an aligned byte or word requires two temporaries. Operand 0 is 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. - -(define_expand "aligned_store" - [(set (match_operand:SI 3 "register_operand" "") - (match_operand:SI 0 "memory_operand" "")) - (set (subreg:DI (match_dup 3) 0) - (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5))) - (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0) - (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" "")) - (match_operand:DI 2 "const_int_operand" ""))) - (set (subreg:DI (match_dup 4) 0) - (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])) - << 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 -;; required. Operand 0 is the address. Operand 1 is the data to store. -;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may -;; be the same temporary, if desired. If the address is in a register, -;; operand 2 can be that register. - -(define_expand "unaligned_storeqi" - [(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) - (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" "")) - (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))] - "" - "") - -(define_expand "unaligned_storehi" - [(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 65535) - (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" "")) - (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))] - "" - "") - -;; Here are the define_expand's for QI and HI moves that use the above -;; patterns. We have the normal sets, plus the ones that need scratch -;; registers for reload. - -(define_expand "movqi" - [(set (match_operand:QI 0 "general_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:; -}") - -(define_expand "movhi" - [(set (match_operand:HI 0 "general_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:; -}") - -;; 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 -;; slots are always aligned references. - -(define_expand "reload_inqi" - [(parallel [(match_operand:QI 0 "register_operand" "=r") - (match_operand:QI 1 "any_memory_operand" "m") - (match_operand:TI 2 "register_operand" "=&r")])] - "! TARGET_BWX" - " -{ - rtx scratch, seq; - - if (GET_CODE (operands[1]) != MEM) - abort (); - - if (aligned_memory_operand (operands[1], QImode)) - { - seq = gen_reload_inqi_help (operands[0], operands[1], - gen_rtx_REG (SImode, REGNO (operands[2]))); - } - else - { - rtx addr; - - /* It is possible that one of the registers we got for operands[2] - might coincide with that of operands[0] (which is why we made - it TImode). Pick the other one to use as our scratch. */ - if (REGNO (operands[0]) == REGNO (operands[2])) - scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); - else - scratch = gen_rtx_REG (DImode, REGNO (operands[2])); - - addr = get_unaligned_address (operands[1], 0); - seq = gen_unaligned_loadqi (operands[0], addr, scratch, - gen_rtx_REG (DImode, REGNO (operands[0]))); - alpha_set_memflags (seq, operands[1]); - } - 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; - - if (GET_CODE (operands[1]) != MEM) - abort (); - - if (aligned_memory_operand (operands[1], HImode)) - { - seq = gen_reload_inhi_help (operands[0], operands[1], - gen_rtx_REG (SImode, REGNO (operands[2]))); - } - else - { - rtx addr; - - /* It is possible that one of the registers we got for operands[2] - might coincide with that of operands[0] (which is why we made - it TImode). Pick the other one to use as our scratch. */ - if (REGNO (operands[0]) == REGNO (operands[2])) - scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); - else - scratch = gen_rtx_REG (DImode, REGNO (operands[2])); - - addr = get_unaligned_address (operands[1], 0); - seq = gen_unaligned_loadhi (operands[0], addr, scratch, - gen_rtx_REG (DImode, REGNO (operands[0]))); - alpha_set_memflags (seq, operands[1]); - } - 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 (); - - if (aligned_memory_operand (operands[0], QImode)) - { - emit_insn (gen_reload_outqi_help - (operands[0], operands[1], - gen_rtx_REG (SImode, REGNO (operands[2])), - gen_rtx_REG (SImode, REGNO (operands[2]) + 1))); - } - else - { - rtx addr = get_unaligned_address (operands[0], 0); - rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2])); - rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); - rtx scratch3 = scratch1; - rtx seq; - - if (GET_CODE (addr) == REG) - scratch1 = addr; - - seq = gen_unaligned_storeqi (addr, operands[1], scratch1, - scratch2, scratch3); - alpha_set_memflags (seq, operands[0]); - 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 (); - - if (aligned_memory_operand (operands[0], HImode)) - { - emit_insn (gen_reload_outhi_help - (operands[0], operands[1], - gen_rtx_REG (SImode, REGNO (operands[2])), - gen_rtx_REG (SImode, REGNO (operands[2]) + 1))); - } - else - { - rtx addr = get_unaligned_address (operands[0], 0); - rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2])); - rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); - rtx scratch3 = scratch1; - rtx seq; - - if (GET_CODE (addr) == REG) - scratch1 = addr; - - seq = gen_unaligned_storehi (addr, operands[1], scratch1, - scratch2, scratch3); - alpha_set_memflags (seq, operands[0]); - 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") - (match_operand:QI 1 "memory_operand" "m")) - (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") - (match_operand:HI 1 "memory_operand" "m")) - (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") - (match_operand:QI 1 "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") - (match_operand:HI 1 "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"))] - "! 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"))] - "! 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"))] - "! 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"))] - "! 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] - -(define_expand "extv" - [(set (match_operand:DI 0 "register_operand" "") - (sign_extract:DI (match_operand:QI 1 "memory_operand" "") - (match_operand:DI 2 "immediate_operand" "") - (match_operand:DI 3 "immediate_operand" "")))] - "" - " -{ - /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */ - if (INTVAL (operands[3]) % 8 != 0 - || (INTVAL (operands[2]) != 16 - && INTVAL (operands[2]) != 32 - && INTVAL (operands[2]) != 64)) - FAIL; - - /* From mips.md: extract_bit_field doesn't verify that our source - matches the predicate, so we force it to be a MEM here. */ - if (GET_CODE (operands[1]) != MEM) - FAIL; - - alpha_expand_unaligned_load (operands[0], operands[1], - INTVAL (operands[2]) / 8, - INTVAL (operands[3]) / 8, 1); - DONE; -}") - -(define_expand "extzv" - [(set (match_operand:DI 0 "register_operand" "") - (zero_extract:DI (match_operand:DI 1 "general_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 - || (INTVAL (operands[2]) != 8 - && INTVAL (operands[2]) != 16 - && INTVAL (operands[2]) != 32 - && INTVAL (operands[2]) != 64)) - FAIL; - - if (GET_CODE (operands[1]) == MEM) - { - /* Fail 8 bit fields, falling back on a simple byte load. */ - if (INTVAL (operands[2]) == 8) - FAIL; - - alpha_expand_unaligned_load (operands[0], operands[1], - INTVAL (operands[2]) / 8, - INTVAL (operands[3]) / 8, 0); - DONE; - } -}") - -(define_expand "insv" - [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "") - (match_operand:DI 1 "immediate_operand" "") - (match_operand:DI 2 "immediate_operand" "")) - (match_operand:DI 3 "register_operand" ""))] - "" - " -{ - /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */ - if (INTVAL (operands[2]) % 8 != 0 - || (INTVAL (operands[1]) != 16 - && INTVAL (operands[1]) != 32 - && INTVAL (operands[1]) != 64)) - FAIL; - - /* From mips.md: store_bit_field doesn't verify that our source - matches the predicate, so we force it to be a MEM here. */ - if (GET_CODE (operands[0]) != MEM) - FAIL; - - alpha_expand_unaligned_store (operands[0], operands[3], - INTVAL (operands[1]) / 8, - INTVAL (operands[2]) / 8); - DONE; -}") - - - -;; Block move/clear, see alpha.c for more details. -;; Argument 0 is the destination -;; Argument 1 is the source -;; Argument 2 is the length -;; Argument 3 is the alignment - -(define_expand "movstrqi" - [(parallel [(set (match_operand:BLK 0 "general_operand" "") - (match_operand:BLK 1 "general_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" "") - (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. -(define_expand "allocate_stack" - [(set (reg:DI 30) - (plus:DI (reg:DI 30) - (match_operand:DI 1 "reg_or_cint_operand" ""))) - (set (match_operand:DI 0 "register_operand" "=r") - (match_dup 2))] - "" - " -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) < 32768) - { - if (INTVAL (operands[1]) >= 4096) - { - /* We do this the same way as in the prologue and generate explicit - probes. Then we update the stack by the constant. */ - - int probed = 4096; - - emit_insn (gen_probe_stack (GEN_INT (- probed))); - while (probed + 8192 < INTVAL (operands[1])) - emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192)))); - - if (probed + 4096 < INTVAL (operands[1])) - emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1])))); - } - - operands[1] = GEN_INT (- INTVAL (operands[1])); - operands[2] = virtual_stack_dynamic_rtx; - } - else - { - rtx out_label = 0; - rtx loop_label = gen_label_rtx (); - rtx want = gen_reg_rtx (Pmode); - rtx tmp = gen_reg_rtx (Pmode); - rtx memref; - - emit_insn (gen_subdi3 (want, stack_pointer_rtx, - force_reg (Pmode, operands[1]))); - emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096))); - - if (GET_CODE (operands[1]) != CONST_INT) - { - out_label = gen_label_rtx (); - emit_insn (gen_cmpdi (want, tmp)); - emit_jump_insn (gen_bgeu (out_label)); - } - - emit_label (loop_label); - memref = gen_rtx_MEM (DImode, tmp); - MEM_VOLATILE_P (memref) = 1; - emit_move_insn (memref, const0_rtx); - 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; - emit_move_insn (memref, const0_rtx); - - if (out_label) - emit_label (out_label); - - emit_move_insn (stack_pointer_rtx, want); - 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)] - "" - "* -{ - operands[2] = gen_label_rtx (); - 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\"; -}" - [(set_attr "length" "16") - (set_attr "type" "multi")]) - -(define_expand "prologue" - [(clobber (const_int 0))] - "" - "alpha_expand_prologue (); DONE;") - -(define_insn "init_fp" - [(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")))] - "" - "mov %1,%0") - -(define_expand "epilogue" - [(clobber (const_int 0))] - "" - "alpha_expand_epilogue (); DONE;") - -(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" - " -{ - 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; - } -}") - -;; 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") - (unspec:DI [(match_dup 0) - (match_operand:DI 1 "const_int_operand" "n")] 6))] - "" - "lda %0,%1(%0)") - -(define_expand "builtin_longjmp" - [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)] - "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT" - " -{ - /* The elements of the buffer are, in order: */ - rtx fp = gen_rtx_MEM (Pmode, operands[0]); - rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)); - rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16)); - rtx pv = gen_rtx_REG (Pmode, 27); - - /* This bit is the same as expand_builtin_longjmp. */ - emit_move_insn (hard_frame_pointer_rtx, fp); - emit_move_insn (pv, lab); - emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX); - emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); - emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); - - /* 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); - 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")]) - -(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)" - [(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") - (set_attr "type" "multi")]) - -(define_expand "nonlocal_goto_receiver" - [(unspec_volatile [(const_int 0)] 1) - (set (reg:DI 27) (mem:DI (reg:DI 29))) - (unspec_volatile [(const_int 0)] 1) - (use (reg:DI 27))] - "TARGET_OPEN_VMS" - "") - -(define_insn "arg_home" - [(unspec [(const_int 0)] 0) - (use (reg:DI 1)) - (use (reg:DI 25)) - (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))) - (clobber (reg:DI 24)) - (clobber (reg:DI 25)) - (clobber (reg:DI 0))] - "TARGET_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 -;; by alpha_reorg. - -(define_insn "trapb" - [(unspec_volatile [(const_int 0)] 4)] - "" - "trapb" - [(set_attr "type" "misc")]) - -;; No-op instructions used by machine-dependant reorg to preserve -;; alignment for instruction issue. - -(define_insn "nop" - [(const_int 0)] - "" - "nop" - [(set_attr "type" "ilog")]) - -(define_insn "fnop" - [(const_int 1)] - "TARGET_FP" - "fnop" - [(set_attr "type" "fcpys")]) - -(define_insn "unop" - [(const_int 2)] - "" - "unop") - -(define_insn "realign" - [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)] - "" - ".align %0 #realign") - -;; Peepholes go at the end. - -;; 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 deleted file mode 100644 index 3cbcfe1f4997..000000000000 --- a/contrib/gcc/config/alpha/alpha32.h +++ /dev/null @@ -1,104 +0,0 @@ -/* Definitions of target machine for GNU compiler, for DEC Alpha - running Windows/NT. - Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc. - - Derived from code - Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - - Donn Terry, Softway Systems, Inc. - - This file contains the code-generation stuff common to the 32-bit - versions of the DEC/Compaq Alpha architecture. It is shared by - Interix and NT/Win32 ports. It should not contain compile-time - or run-time dependent environment values (such as compiler options - or anything containing a file or pathname.) - -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_WINDOWS_NT -#define TARGET_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. */ -#undef POINTER_SIZE -#define POINTER_SIZE 32 -#define POINTERS_EXTEND_UNSIGNED 0 - -/* We don't change Pmode to the "obvious" SI mode... the above appears - to affect the in-memory size; we want the registers to stay DImode - to match the md file */ - -/* "long" is 32 bits. */ -#undef LONG_TYPE_SIZE -#define LONG_TYPE_SIZE 32 - - -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. - - The trampoline should set the static chain pointer to value placed - into the trampoline and should branch to the specified routine. */ - -#undef TRAMPOLINE_TEMPLATE -#define TRAMPOLINE_TEMPLATE(FILE) \ -{ \ - fprintf (FILE, "\tbr $27,$LTRAMPP\n"); \ - fprintf (FILE, "$LTRAMPP:\n\tldl $1,12($27)\n"); \ - fprintf (FILE, "\tldl $27,16($27)\n"); \ - fprintf (FILE, "\tjmp $31,($27),0\n"); \ - fprintf (FILE, "\t.long 0,0\n"); \ -} - -/* Length in units of the trampoline for entering a nested function. */ - -#undef TRAMPOLINE_SIZE -#define TRAMPOLINE_SIZE 24 - -/* 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. */ - -#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/crtbegin.asm b/contrib/gcc/config/alpha/crtbegin.asm deleted file mode 100644 index f954f1ab0d3e..000000000000 --- a/contrib/gcc/config/alpha/crtbegin.asm +++ /dev/null @@ -1,192 +0,0 @@ - # Copyright (C) 1996, 1998 Free Software Foundation, Inc. - # Contributed by Richard Henderson (rth@tamu.edu) - # - # 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. - - # - # Heads of the constructor/destructor lists. - # - - # The __*TOR_LIST__ symbols are not global because when this file is used - # in a shared library, we do not want the symbol to fall over to the - # application's lists. - -.section .ctors,"aw" - - .align 3 -__CTOR_LIST__: - .quad -1 - -.section .dtors,"aw" - - .align 3 -__DTOR_LIST__: - .quad -1 - -.section .eh_frame,"aw" -__EH_FRAME_BEGIN__: - - # - # Fragment of the ELF _fini routine that invokes our dtor cleanup. - # - -.section .fini,"ax" - - # Since the bits of the _fini function are spread across many - # object files, each potentially with its own GP, we must - # assume we need to load ours. Further, our .fini section - # can easily be more than 4MB away from our .text bits so we - # can't use bsr. - - br $29,1f -1: ldgp $29,0($29) - jsr $26,__do_global_dtors_aux - - # Ideally this call would go in crtend.o, except that we can't - # get hold of __EH_FRAME_BEGIN__ there. - - jsr $26,__do_frame_takedown - - # Must match the alignment we got from crti.o else we get - # zero-filled holes in our _fini function and then SIGILL. - .align 3 - - # - # Fragment of the ELF _init routine that sets up the frame info. - # - -.section .init,"ax" - br $29,1f -1: ldgp $29,0($29) - jsr $26,__do_frame_setup - .align 3 - - # - # Invoke our destructors in order. - # - -.data - - # Support recursive calls to exit. -$ptr: .quad __DTOR_LIST__ - -.text - - .align 3 - .ent __do_global_dtors_aux - -__do_global_dtors_aux: - lda $30,-16($30) - .frame $30,16,$26,0 - stq $9,8($30) - stq $26,0($30) - .mask 0x4000200,-16 - .prologue 0 - - lda $9,$ptr - br 1f -0: stq $1,0($9) - jsr $26,($27) -1: ldq $1,0($9) - ldq $27,8($1) - addq $1,8,$1 - bne $27,0b - - ldq $26,0($30) - ldq $9,8($30) - lda $30,16($30) - ret - - .end __do_global_dtors_aux - - # - # Install our frame info. - # - - # ??? How can we rationally keep this size correct? - -.section .bss - .type $object,@object - .align 3 -$object: - .zero 48 - .size $object, 48 - -.text - - .align 3 - .ent __do_frame_setup - -__do_frame_setup: - ldgp $29,0($27) - lda $30,-16($30) - .frame $30,16,$26,0 - stq $26,0($30) - .mask 0x4000000,-16 - .prologue 1 - - lda $1,__register_frame_info - beq $1,0f - lda $16,__EH_FRAME_BEGIN__ - lda $17,$object - jsr $26,__register_frame_info - ldq $26,0($30) -0: lda $30,16($30) - ret - - .end __do_frame_setup - - # - # Remove our frame info. - # - - .align 3 - .ent __do_frame_takedown - -__do_frame_takedown: - ldgp $29,0($27) - lda $30,-16($30) - .frame $30,16,$26,0 - stq $26,0($30) - .mask 0x4000000,-16 - .prologue 1 - - lda $1,__deregister_frame_info - beq $1,0f - lda $16,__EH_FRAME_BEGIN__ - jsr $26,__deregister_frame_info - ldq $26,0($30) -0: lda $30,16($30) - ret - - .end __do_frame_takedown - -.weak __register_frame_info -.weak __deregister_frame_info diff --git a/contrib/gcc/config/alpha/crtend.asm b/contrib/gcc/config/alpha/crtend.asm deleted file mode 100644 index 4a0cc5e9f612..000000000000 --- a/contrib/gcc/config/alpha/crtend.asm +++ /dev/null @@ -1,108 +0,0 @@ - # Copyright (C) 1996 Free Software Foundation, Inc. - # Contributed by Richard Henderson (rth@tamu.edu) - # - # 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. - - # - # Tails of the constructor/destructor lists. - # - - # The __*TOR_END__ symbols are not global because when this file is used - # in a shared library, we do not want the symbol to fall over to the - # application's lists. - -.section .ctors,"aw" - - .align 3 -__CTOR_END__: - .quad 0 - -.section .dtors,"aw" - - .align 3 -__DTOR_END__: - .quad 0 - -.section .eh_frame,"aw" -__FRAME_END__: - .quad 0 - - # - # Fragment of the ELF _init routine that invokes our ctor startup - # - -.section .init,"ax" - - # Since the bits of the _init function are spread across many - # object files, each potentially with its own GP, we must - # assume we need to load ours. Further, our .init section - # can easily be more than 4MB away from our .text bits so we - # can't use bsr. - - br $29,1f -1: ldgp $29,0($29) - jsr $26,__do_global_ctors_aux - - # Must match the alignment we got from crti.o else we get - # zero-filled holes in our _init function and thense SIGILL. - .align 3 - - # - # Invoke our destructors in order. - # - -.text - - .align 3 - .ent __do_global_ctors_aux - -__do_global_ctors_aux: - ldgp $29,0($27) - lda $30,-16($30) - .frame $30,16,$26,0 - stq $9,8($30) - stq $26,0($30) - .mask 0x4000200,-16 - .prologue 1 - - lda $9,__CTOR_END__ - br 1f -0: jsr $26,($27) -1: ldq $27,-8($9) - subq $9,8,$9 - not $27,$0 - bne $0,0b - - ldq $26,0($30) - ldq $9,8($30) - lda $30,16($30) - ret - - .end __do_global_ctors_aux diff --git a/contrib/gcc/config/alpha/elf.h b/contrib/gcc/config/alpha/elf.h deleted file mode 100644 index 6cea3da5d5b4..000000000000 --- a/contrib/gcc/config/alpha/elf.h +++ /dev/null @@ -1,534 +0,0 @@ -/* Definitions of target machine for GNU compiler, for DEC Alpha w/ELF. - Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. - Contributed by Richard Henderson (rth@tamu.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, -Boston, MA 02111-1307, USA. */ - -#undef OBJECT_FORMAT_COFF -#undef EXTENDED_COFF -#define OBJECT_FORMAT_ELF - -#define DBX_DEBUGGING_INFO -#define DWARF2_DEBUGGING_INFO - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG - -#undef ASM_FINAL_SPEC - -#undef CC1_SPEC -#define CC1_SPEC "%{G*}" - -#undef ASM_SPEC -#define ASM_SPEC "%{G*} %{relax:-relax} %{gdwarf*:-no-mdebug}" - -#undef LINK_SPEC -#define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \ - %{O*:-O3} %{!O*:-O1} \ - %{shared:-shared} \ - %{!shared: \ - %{!static: \ - %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker %(elf_dynamic_linker)}} \ - %{static:-static}}" - -/* Output at beginning of assembler file. */ -#undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ -do { \ - if (write_symbols != DWARF2_DEBUG) \ - { \ - alpha_write_verstamp (FILE); \ - output_file_directive (FILE, main_input_filename); \ - } \ - fprintf (FILE, "\t.set noat\n"); \ - fprintf (FILE, "\t.set noreorder\n"); \ - if (TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) \ - { \ - fprintf (FILE, "\t.arch %s\n", \ - (alpha_cpu == PROCESSOR_EV6 ? "ev6" \ - : TARGET_MAX ? "pca56" : "ev56")); \ - } \ -} while (0) - -extern void output_file_directive (); - -/* Attach a special .ident directive to the end of the file to identify - the version of GCC which compiled this code. The format of the - .ident string is patterned after the ones produced by native svr4 - C compilers. */ - -#define IDENT_ASM_OP ".ident" - -#ifdef IDENTIFY_WITH_IDENT -#define ASM_IDENTIFY_GCC(FILE) /* nothing */ -#define ASM_IDENTIFY_LANGUAGE(FILE) \ - fprintf(FILE, "\t%s \"GCC (%s) %s\"\n", IDENT_ASM_OP, \ - lang_identify(), version_string) -#else -#define ASM_FILE_END(FILE) \ -do { \ - if (!flag_no_ident) \ - fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \ - IDENT_ASM_OP, version_string); \ - } while (0) -#endif - -/* Allow #sccs in preprocessor. */ -#define SCCS_DIRECTIVE - -/* Output #ident as a .ident. */ -#define ASM_OUTPUT_IDENT(FILE, NAME) \ - fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME); - -/* This is how to allocate empty space in some section. The .zero - pseudo-op is used for this on most svr4 assemblers. */ - -#define SKIP_ASM_OP ".zero" - -#undef ASM_OUTPUT_SKIP -#define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf (FILE, "\t%s\t%u\n", SKIP_ASM_OP, (SIZE)) - -/* Output the label which precedes a jumptable. Note that for all svr4 - systems where we actually generate jumptables (which is to say every - svr4 target except i386, where we use casesi instead) we put the jump- - tables into the .rodata section and since other stuff could have been - put into the .rodata section prior to any given jumptable, we have to - make sure that the location counter for the .rodata section gets pro- - perly re-aligned prior to the actual beginning of the jump table. */ - -#define ALIGN_ASM_OP ".align" - -#ifndef ASM_OUTPUT_BEFORE_CASE_LABEL -#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \ - ASM_OUTPUT_ALIGN ((FILE), 2); -#endif - -#undef ASM_OUTPUT_CASE_LABEL -#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,JUMPTABLE) \ - do { \ - ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \ - ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \ - } while (0) - -/* The standard SVR4 assembler seems to require that certain builtin - library routines (e.g. .udiv) be explicitly declared as .globl - in each assembly file where they are referenced. */ - -#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \ - ASM_GLOBALIZE_LABEL (FILE, XSTR (FUN, 0)) - -/* This says how to output assembler code to declare an - uninitialized external linkage data object. Under SVR4, - the linker seems to want the alignment of data objects - to depend on their types. We do exactly that here. */ - -#define COMMON_ASM_OP ".comm" - -#undef ASM_OUTPUT_ALIGNED_COMMON -#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \ -do { \ - fprintf ((FILE), "\t%s\t", COMMON_ASM_OP); \ - assemble_name ((FILE), (NAME)); \ - fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \ -} while (0) - -/* This says how to output assembler code to declare an - uninitialized internal linkage data object. Under SVR4, - the linker seems to want the alignment of data objects - to depend on their types. We do exactly that here. */ - -#undef ASM_OUTPUT_ALIGNED_LOCAL -#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ -do { \ - if ((SIZE) <= g_switch_value) \ - sbss_section(); \ - else \ - bss_section(); \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ - putc ('\n', FILE); \ - if (!flag_inhibit_size_directive) \ - { \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ",%d\n", (SIZE)); \ - } \ - ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - ASM_OUTPUT_SKIP((FILE), (SIZE)); \ -} while (0) - -/* This is the pseudo-op used to generate a 64-bit word of data with a - specific value in some section. */ - -#define INT_ASM_OP ".quad" - -/* Biggest alignment supported by the object file format of this - machine. Use this macro to limit the alignment which can be - specified using the `__attribute__ ((aligned (N)))' construct. If - not defined, the default value is `BIGGEST_ALIGNMENT'. - - This value is really 2^63. Since gcc figures the alignment in bits, - we could only potentially get to 2^60 on suitible hosts. Due to other - considerations in varasm, we must restrict this to what fits in an int. */ - -#define MAX_OFILE_ALIGNMENT \ - (1 << (HOST_BITS_PER_INT < 64 ? HOST_BITS_PER_INT - 2 : 62)) - -/* This is the pseudo-op used to generate a contiguous sequence of byte - values from a double-quoted string WITHOUT HAVING A TERMINATING NUL - AUTOMATICALLY APPENDED. This is the same for most svr4 assemblers. */ - -#undef ASCII_DATA_ASM_OP -#define ASCII_DATA_ASM_OP ".ascii" - -/* Support const sections and the ctors and dtors sections for g++. - Note that there appears to be two different ways to support const - sections at the moment. You can either #define the symbol - READONLY_DATA_SECTION (giving it some code which switches to the - readonly data section) or else you can #define the symbols - EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and - SELECT_RTX_SECTION. We do both here just to be on the safe side. */ - -#define USE_CONST_SECTION 1 - -#define CONST_SECTION_ASM_OP ".section\t.rodata" - -/* Define the pseudo-ops used to switch to the .ctors and .dtors sections. - - Note that we want to give these sections the SHF_WRITE attribute - because these sections will actually contain data (i.e. tables of - addresses of functions in the current root executable or shared library - file) and, in the case of a shared library, the relocatable addresses - will have to be properly resolved/relocated (and then written into) by - the dynamic linker when it actually attaches the given shared library - to the executing process. (Note that on SVR4, you may wish to use the - `-z text' option to the ELF linker, when building a shared library, as - an additional check that you are doing everything right. But if you do - use the `-z text' option when building a shared library, you will get - errors unless the .ctors and .dtors sections are marked as writable - via the SHF_WRITE attribute.) */ - -#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\"" -#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\"" - -/* Handle the small data sections. */ -#define BSS_SECTION_ASM_OP ".section\t.bss" -#define SBSS_SECTION_ASM_OP ".section\t.sbss,\"aw\"" -#define SDATA_SECTION_ASM_OP ".section\t.sdata,\"aw\"" - -/* On svr4, we *do* have support for the .init and .fini sections, and we - can put stuff in there to be executed before and after `main'. We let - crtstuff.c and other files know this by defining the following symbols. - The definitions say how to change sections to the .init and .fini - sections. This is the same for all known svr4 assemblers. */ - -#define INIT_SECTION_ASM_OP ".section\t.init" -#define FINI_SECTION_ASM_OP ".section\t.fini" - -/* 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 - should override this definition in the target-specific file which - includes this file. */ - -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_const, in_ctors, in_dtors, in_sbss, in_sdata - -/* A default list of extra section function definitions. For targets - that use additional sections (e.g. .tdesc) you should override this - definition in the target-specific file which includes this file. */ - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ - CONST_SECTION_FUNCTION \ - SECTION_FUNCTION_TEMPLATE(ctors_section, in_ctors, CTORS_SECTION_ASM_OP) \ - SECTION_FUNCTION_TEMPLATE(dtors_section, in_dtors, DTORS_SECTION_ASM_OP) \ - SECTION_FUNCTION_TEMPLATE(sbss_section, in_sbss, SBSS_SECTION_ASM_OP) \ - SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP) - -#undef READONLY_DATA_SECTION -#define READONLY_DATA_SECTION() const_section () - -extern void text_section (); - -#define CONST_SECTION_FUNCTION \ -void \ -const_section () \ -{ \ - if (!USE_CONST_SECTION) \ - text_section(); \ - else if (in_section != in_const) \ - { \ - fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \ - in_section = in_const; \ - } \ -} - -#define SECTION_FUNCTION_TEMPLATE(FN, ENUM, OP) \ -void FN () \ -{ \ - if (in_section != ENUM) \ - { \ - fprintf (asm_out_file, "%s\n", OP); \ - in_section = ENUM; \ - } \ -} - - -/* Switch into a generic section. - This is currently only used to support section attributes. - - We make the section read-only and executable for a function decl, - read-only for a const data decl, and writable for a non-const data decl. */ -#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \ - fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, \ - (DECL) && TREE_CODE (DECL) == FUNCTION_DECL ? "ax" : \ - (DECL) && DECL_READONLY_SECTION (DECL, RELOC) ? "a" : "aw") - - -/* 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) - -/* A C statement or statements to switch to the appropriate - section for output of DECL. DECL is either a `VAR_DECL' node - or a constant of some sort. RELOC indicates whether forming - the initial value of DECL requires link-time relocations. */ - -#define SELECT_SECTION(DECL,RELOC) \ -{ \ - if (TREE_CODE (DECL) == STRING_CST) \ - { \ - if (! flag_writable_strings) \ - const_section (); \ - else \ - data_section (); \ - } \ - else if (TREE_CODE (DECL) == VAR_DECL) \ - { \ - if ((flag_pic && RELOC) \ - || !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \ - || !DECL_INITIAL (DECL) \ - || (DECL_INITIAL (DECL) != error_mark_node \ - && !TREE_CONSTANT (DECL_INITIAL (DECL)))) \ - { \ - int size = int_size_in_bytes (TREE_TYPE (DECL)); \ - if (size >= 0 && size <= g_switch_value) \ - sdata_section (); \ - else \ - data_section (); \ - } \ - else \ - const_section (); \ - } \ - else \ - const_section (); \ -} - -/* A C statement or statements to switch to the appropriate - section for output of RTX in mode MODE. RTX is some kind - of constant in RTL. The argument MODE is redundant except - in the case of a `const_int' rtx. Currently, these always - go into the const section. */ - -#undef SELECT_RTX_SECTION -#define SELECT_RTX_SECTION(MODE,RTX) const_section() - -/* Define the strings used for the special svr4 .type and .size directives. - These strings generally do not vary from one system running svr4 to - another, but if a given system (e.g. m88k running svr) needs to use - different pseudo-op names for these, they may be overridden in the - file which includes this one. */ - -#define TYPE_ASM_OP ".type" -#define SIZE_ASM_OP ".size" - -/* This is how we tell the assembler that a symbol is weak. */ - -#define ASM_WEAKEN_LABEL(FILE,NAME) \ - do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \ - fputc ('\n', FILE); } while (0) - -/* This is how we tell the assembler that two symbols have the same value. */ - -#define ASM_OUTPUT_DEF(FILE,NAME1,NAME2) \ - do { assemble_name(FILE, NAME1); \ - fputs(" = ", FILE); \ - assemble_name(FILE, NAME2); \ - fputc('\n', FILE); } while (0) - -/* The following macro defines the format used to output the second - operand of the .type assembler directive. Different svr4 assemblers - expect various different forms for this operand. The one given here - is just a default. You may need to override it in your machine- - specific tm.h file (depending upon the particulars of your assembler). */ - -#define TYPE_OPERAND_FMT "@%s" - -/* Write the extra assembler code needed to declare a function's result. - Most svr4 assemblers don't require any special declaration of the - result value, but there are exceptions. */ - -#ifndef ASM_DECLARE_RESULT -#define ASM_DECLARE_RESULT(FILE, RESULT) -#endif - -/* These macros generate the special .type and .size directives which - are used to set the corresponding fields of the linker symbol table - entries in an ELF object file under SVR4. These macros also output - the starting labels for the relevant functions/objects. */ - -/* Write the extra assembler code needed to declare an object properly. */ - -#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ - putc ('\n', FILE); \ - size_directive_output = 0; \ - if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \ - { \ - size_directive_output = 1; \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ - } \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - } while (0) - -/* Output the size directive for a decl in rest_of_decl_compilation - in the case where we did not do so before the initializer. - Once we find the error_mark_node, we know that the value of - size_directive_output was set - by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ - -#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ -do { \ - char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ - if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \ - && ! AT_END && TOP_LEVEL \ - && DECL_INITIAL (DECL) == error_mark_node \ - && !size_directive_output) \ - { \ - size_directive_output = 1; \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, name); \ - putc (',', FILE); \ - fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, \ - int_size_in_bytes (TREE_TYPE (DECL))); \ - putc ('\n', FILE); \ - } \ -} while (0) - -/* A table of bytes codes used by the ASM_OUTPUT_ASCII and - ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table - corresponds to a particular byte value [0..255]. For any - given byte value, if the value in the corresponding table - position is zero, the given character can be output directly. - If the table value is 1, the byte must be output as a \ooo - octal escape. If the tables value is anything else, then the - byte value should be output as a \ followed by the value - in the table. Note that we can use standard UN*X escape - sequences for many control characters, but we don't use - \a to represent BEL because some svr4 assemblers (e.g. on - the i386) don't know about that. Also, we don't use \v - since some versions of gas, such as 2.2 did not accept it. */ - -#define ESCAPES \ -"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ -\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\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\1\1\1\1\1\1\1\1\1\1\1\ -\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ -\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ -\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1" - -/* Some svr4 assemblers have a limit on the number of characters which - can appear in the operand of a .string directive. If your assembler - has such a limitation, you should define STRING_LIMIT to reflect that - limit. Note that at least some svr4 assemblers have a limit on the - actual number of bytes in the double-quoted string, and that they - count each character in an escape sequence as one byte. Thus, an - escape sequence like \377 would count as four bytes. - - If your target assembler doesn't support the .string directive, you - should define this to zero. */ - -#define STRING_LIMIT ((unsigned) 256) -#define STRING_ASM_OP ".string" - -/* GAS is the only Alpha/ELF assembler. */ -#undef TARGET_GAS -#define TARGET_GAS (1) - -/* Provide a STARTFILE_SPEC appropriate for ELF. Here we add the - (even more) magical crtbegin.o file which provides part of the - support for getting C++ file-scope static object constructed before - entering `main'. - - Don't bother seeing crtstuff.c -- there is absolutely no hope of - getting that file to understand multiple GPs. GNU Libc provides a - hand-coded version that is used on Linux; it could be copied here - if there is ever a need. */ - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC \ - "%{!shared: \ - %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\ - crti.o%s crtbegin.o%s" - -/* Provide a ENDFILE_SPEC appropriate for ELF. Here we tack on the - magical crtend.o file which provides part of the support for - getting C++ file-scope static object constructed before entering - `main', followed by a normal ELF "finalizer" file, `crtn.o'. */ - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC \ - "crtend.o%s crtn.o%s" - -/* We support #pragma. */ -#define HANDLE_SYSV_PRAGMA - -/* Undo the auto-alignment stuff from alpha.h. ELF has unaligned data - pseudos natively. */ -#undef UNALIGNED_SHORT_ASM_OP -#undef UNALIGNED_INT_ASM_OP -#undef UNALIGNED_DOUBLE_INT_ASM_OP diff --git a/contrib/gcc/config/alpha/freebsd.h b/contrib/gcc/config/alpha/freebsd.h deleted file mode 100644 index 24567a6d065c..000000000000 --- a/contrib/gcc/config/alpha/freebsd.h +++ /dev/null @@ -1,103 +0,0 @@ -/* XXX */ -/* - * This file was derived from source obtained from NetBSD/Alpha which - * is publicly available for ftp. The patch was developed by cgd@netbsd.org - * during the time he worked at CMU. He claims that CMU own this patch - * to gcc and that they have not (and will not) release the patch for - * incorporation in FSF sources. We are supposedly able to use the patch, - * but we are not allowed to forward it back to FSF for inclusion in - * their source releases. - * - * This all has me (jb@freebsd.org) confused because (a) I see no copyright - * messages that tell me that use is restricted; and (b) I expected that - * the patch was originally developed from other files which are subject - * to GPL. - * - * Use of this file is restricted until its CMU ownership is tested. - */ - -#include "alpha/alpha.h" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "int" - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 32 - -/* FreeBSD-specific things: */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-D__FreeBSD__ -D__alpha__ -D__alpha" - -/* Look for the include files in the system-defined places. */ - -#undef GPLUSPLUS_INCLUDE_DIR -#define GPLUSPLUS_INCLUDE_DIR "/usr/include/g++" - -#undef GCC_INCLUDE_DIR -#define GCC_INCLUDE_DIR "/usr/include" - -#undef INCLUDE_DEFAULTS -#define INCLUDE_DEFAULTS \ - { \ - { GPLUSPLUS_INCLUDE_DIR, 1, 1 }, \ - { GCC_INCLUDE_DIR, 0, 0 }, \ - { 0, 0, 0 } \ - } - - -/* Under FreeBSD, the normal location of the `ld' and `as' programs is the - /usr/bin directory. */ - -#undef MD_EXEC_PREFIX -#define MD_EXEC_PREFIX "/usr/bin/" - -/* Under FreeBSD, the normal location of the various *crt*.o files is the - /usr/lib directory. */ - -#undef MD_STARTFILE_PREFIX -#define MD_STARTFILE_PREFIX "/usr/lib/" - - -/* Provide a CPP_SPEC appropriate for FreeBSD. Current we just deal with - the GCC option `-posix'. */ - -#undef CPP_SPEC -#define CPP_SPEC "%{posix:-D_POSIX_SOURCE}" - -/* Provide an ASM_SPEC appropriate for FreeBSD. */ - -#undef ASM_SPEC -#define ASM_SPEC " %|" - -#undef ASM_FINAL_SPEC - -/* Provide a LIB_SPEC appropriate for FreeBSD. Just select the appropriate - libc, depending on whether we're doing profiling. */ - -#undef LIB_SPEC -#define LIB_SPEC "%{!shared:%{!pg:%{!pthread:-lc}%{pthread:-lpthread -lc}}%{pg:%{!pthread:-lc_p}%{pthread:-lpthread_p -lc_p}}}" - -/* Provide a LINK_SPEC appropriate for FreeBSD. Here we provide support - for the special GCC options -static, -assert, and -nostdlib. */ - -#undef LINK_SPEC -#define LINK_SPEC \ - "%{!nostdlib:%{!r*:%{!e*:-e __start}}} -dc -dp %{static:-Bstatic} %{assert*}" - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. Under FreeBSD/Alpha, the assembler does - nothing special with -pg. */ - -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ - fputs ("\tjsr $28,_mcount\n", (FILE)); /* at */ - -/* Show that we need a GP when profiling. */ -#define TARGET_PROFILING_NEEDS_GP - -#define bsd4_4 -#undef HAS_INIT_SECTION - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG diff --git a/contrib/gcc/config/alpha/gdb-osf12.h b/contrib/gcc/config/alpha/gdb-osf12.h deleted file mode 100644 index 98c289714017..000000000000 --- a/contrib/gcc/config/alpha/gdb-osf12.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Definitions of target machine for GNU compiler, for DEC Alpha, using - encapsulated stabs and OSF V1.2. - Copyright (C) 1994 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, -Boston, MA 02111-1307, USA. */ - -#include "alpha/osf12.h" - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG diff --git a/contrib/gcc/config/alpha/gdb-osf2.h b/contrib/gcc/config/alpha/gdb-osf2.h deleted file mode 100644 index 5ddb7981b34d..000000000000 --- a/contrib/gcc/config/alpha/gdb-osf2.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Definitions of target machine for GNU compiler, for DEC Alpha, using - encapsulated stabs. - Copyright (C) 1992, 1993 Free Software Foundation, Inc. - Contributed by Peter Schauer (pes@regent.e-technik.tu-muenchen.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. */ - -#include "alpha/osf2.h" - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG diff --git a/contrib/gcc/config/alpha/gdb.h b/contrib/gcc/config/alpha/gdb.h deleted file mode 100644 index ecdbe40a9a45..000000000000 --- a/contrib/gcc/config/alpha/gdb.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Definitions of target machine for GNU compiler, for DEC Alpha, using - encapsulated stabs. - Copyright (C) 1992, 1993 Free Software Foundation, Inc. - Contributed by Peter Schauer (pes@regent.e-technik.tu-muenchen.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. */ - -#include "alpha/alpha.h" - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG diff --git a/contrib/gcc/config/alpha/lib1funcs.asm b/contrib/gcc/config/alpha/lib1funcs.asm deleted file mode 100644 index e63180ade916..000000000000 --- a/contrib/gcc/config/alpha/lib1funcs.asm +++ /dev/null @@ -1,325 +0,0 @@ -/* DEC Alpha division and remainder support. - Copyright (C) 1994, 1999 Free Software Foundation, Inc. - -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, 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. */ - -/* This had to be written in assembler because the division functions - use a non-standard calling convention. - - This file provides an implementation of __divqu, __divq, __divlu, - __divl, __remqu, __remq, __remlu and __reml. CPP macros control - the exact operation. - - Operation performed: $27 := $24 o $25, clobber $28, return address to - caller in $23, where o one of the operations. - - The following macros need to be defined: - - SIZE, the number of bits, 32 or 64. - - TYPE, either UNSIGNED or SIGNED - - OPERATION, either DIVISION or REMAINDER - - SPECIAL_CALLING_CONVENTION, 0 or 1. It is useful for debugging to - define this to 0. That removes the `__' prefix to make the function - name not collide with the existing libc.a names, and uses the - standard Alpha procedure calling convention. -*/ - -#ifndef SPECIAL_CALLING_CONVENTION -#define SPECIAL_CALLING_CONVENTION 1 -#endif - -#ifdef L_divl -#if SPECIAL_CALLING_CONVENTION -#define FUNCTION_NAME __divl -#else -#define FUNCTION_NAME divl -#endif -#define SIZE 32 -#define TYPE SIGNED -#define OPERATION DIVISION -#endif - -#ifdef L_divlu -#if SPECIAL_CALLING_CONVENTION -#define FUNCTION_NAME __divlu -#else -#define FUNCTION_NAME divlu -#endif -#define SIZE 32 -#define TYPE UNSIGNED -#define OPERATION DIVISION -#endif - -#ifdef L_divq -#if SPECIAL_CALLING_CONVENTION -#define FUNCTION_NAME __divq -#else -#define FUNCTION_NAME divq -#endif -#define SIZE 64 -#define TYPE SIGNED -#define OPERATION DIVISION -#endif - -#ifdef L_divqu -#if SPECIAL_CALLING_CONVENTION -#define FUNCTION_NAME __divqu -#else -#define FUNCTION_NAME divqu -#endif -#define SIZE 64 -#define TYPE UNSIGNED -#define OPERATION DIVISION -#endif - -#ifdef L_reml -#if SPECIAL_CALLING_CONVENTION -#define FUNCTION_NAME __reml -#else -#define FUNCTION_NAME reml -#endif -#define SIZE 32 -#define TYPE SIGNED -#define OPERATION REMAINDER -#endif - -#ifdef L_remlu -#if SPECIAL_CALLING_CONVENTION -#define FUNCTION_NAME __remlu -#else -#define FUNCTION_NAME remlu -#endif -#define SIZE 32 -#define TYPE UNSIGNED -#define OPERATION REMAINDER -#endif - -#ifdef L_remq -#if SPECIAL_CALLING_CONVENTION -#define FUNCTION_NAME __remq -#else -#define FUNCTION_NAME remq -#endif -#define SIZE 64 -#define TYPE SIGNED -#define OPERATION REMAINDER -#endif - -#ifdef L_remqu -#if SPECIAL_CALLING_CONVENTION -#define FUNCTION_NAME __remqu -#else -#define FUNCTION_NAME remqu -#endif -#define SIZE 64 -#define TYPE UNSIGNED -#define OPERATION REMAINDER -#endif - -#define tmp0 $3 -#define tmp1 $28 -#define cnt $1 -#define result_sign $2 - -#if SPECIAL_CALLING_CONVENTION -#define N $24 -#define D $25 -#define Q RETREG -#define RETREG $27 -#else -#define N $16 -#define D $17 -#define Q RETREG -#define RETREG $0 -#endif - -/* Misc symbols to make alpha assembler easier to read. */ -#define zero $31 -#define sp $30 - -/* Symbols to make interface nicer. */ -#define UNSIGNED 0 -#define SIGNED 1 -#define DIVISION 0 -#define REMAINDER 1 - - .set noreorder - .set noat -.text - .align 3 - .globl FUNCTION_NAME - .ent FUNCTION_NAME -FUNCTION_NAME: - - .frame $30,0,$26,0 - .prologue 0 - -/* Under the special calling convention, we have to preserve all register - values but $23 and $28. */ -#if SPECIAL_CALLING_CONVENTION - lda sp,-64(sp) -#if OPERATION == DIVISION - stq N,0(sp) -#endif - stq D,8(sp) - stq cnt,16(sp) - stq result_sign,24(sp) - stq tmp0,32(sp) -#endif - -/* If we are computing the remainder, move N to the register that is used - for the return value, and redefine what register is used for N. */ -#if OPERATION == REMAINDER - bis N,N,RETREG -#undef N -#define N RETREG -#endif - -/* Perform conversion from 32 bit types to 64 bit types. */ -#if SIZE == 32 -#if TYPE == SIGNED - /* If there are problems with the signed case, add these instructions. - The caller should already have done this. - addl N,0,N # sign extend N - addl D,0,D # sign extend D - */ -#else /* UNSIGNED */ - zap N,0xf0,N # zero extend N (caller required to sign extend) - zap D,0xf0,D # zero extend D -#endif -#endif - -/* Check for divide by zero. */ - bne D,$34 - lda $16,-2(zero) - call_pal 0xaa -$34: - -#if TYPE == SIGNED -#if OPERATION == DIVISION - xor N,D,result_sign -#else - bis N,N,result_sign -#endif -/* Get the absolute values of N and D. */ - subq zero,N,tmp0 - cmovlt N,tmp0,N - subq zero,D,tmp0 - cmovlt D,tmp0,D -#endif - -/* Compute CNT = ceil(log2(N)) - ceil(log2(D)). This is the number of - divide iterations we will have to perform. Should you wish to optimize - this, check a few bits at a time, preferably using zap/zapnot. Be - careful though, this code runs fast fro the most common cases, when the - quotient is small. */ - bge N,$35 - bis zero,1,cnt - blt D,$40 - .align 3 -$39: addq D,D,D - addl cnt,1,cnt - bge D,$39 - br zero,$40 -$35: cmpult N,D,tmp0 - bis zero,zero,cnt - bne tmp0,$42 - .align 3 -$44: addq D,D,D - cmpult N,D,tmp0 - addl cnt,1,cnt - beq tmp0,$44 -$42: srl D,1,D -$40: - subl cnt,1,cnt - - -/* Actual divide. Could be optimized with unrolling. */ -#if OPERATION == DIVISION - bis zero,zero,Q -#endif - blt cnt,$46 - .align 3 -$49: cmpule D,N,tmp1 - subq N,D,tmp0 - srl D,1,D - subl cnt,1,cnt - cmovne tmp1,tmp0,N -#if OPERATION == DIVISION - addq Q,Q,Q - bis Q,tmp1,Q -#endif - bge cnt,$49 -$46: - - -/* The result is now in RETREG. NOTE! It was written to RETREG using - either N or Q as a synonym! */ - - -/* Change the sign of the result as needed. */ -#if TYPE == SIGNED - subq zero,RETREG,tmp0 - cmovlt result_sign,tmp0,RETREG -#endif - - -/* Restore clobbered registers. */ -#if SPECIAL_CALLING_CONVENTION -#if OPERATION == DIVISION - ldq N,0(sp) -#endif - ldq D,8(sp) - ldq cnt,16(sp) - ldq result_sign,24(sp) - ldq tmp0,32(sp) - - lda sp,64(sp) -#endif - - -/* Sign extend an *unsigned* 32 bit result, as required by the Alpha - conventions. */ -#if TYPE == UNSIGNED && SIZE == 32 - /* This could be avoided by adding some CPP hair to the divide loop. - It is probably not worth the added complexity. */ - addl RETREG,0,RETREG -#endif - - -#if SPECIAL_CALLING_CONVENTION - ret zero,($23),1 -#else - ret zero,($26),1 -#endif - .end FUNCTION_NAME diff --git a/contrib/gcc/config/alpha/linux-ecoff.h b/contrib/gcc/config/alpha/linux-ecoff.h deleted file mode 100644 index 824d0280fce5..000000000000 --- a/contrib/gcc/config/alpha/linux-ecoff.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Definitions of target machine for GNU compiler - for Alpha Linux-based GNU systems using ECOFF. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. - Contributed by Bob Manson. - -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_VERSION -#define TARGET_VERSION fprintf (stderr, " (Alpha GNU/Linux for ECOFF)"); - -#undef CPP_SUBTARGET_SPEC -#define CPP_SUBTARGET_SPEC "-D__ECOFF__" - -#undef LINK_SPEC -#define LINK_SPEC "-G 8 %{O*:-O3} %{!O*:-O1}" - -/* stabs get slurped by the assembler into a queer ecoff format. */ -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG - -/* We support #pragma. */ -#define HANDLE_SYSV_PRAGMA diff --git a/contrib/gcc/config/alpha/linux-elf.h b/contrib/gcc/config/alpha/linux-elf.h deleted file mode 100644 index fc07127d757e..000000000000 --- a/contrib/gcc/config/alpha/linux-elf.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Definitions of target machine for GNU compiler - for Alpha Linux-based GNU systems using ELF. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. - Contributed by Richard Henderson. - -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_VERSION -#define TARGET_VERSION fprintf (stderr, " (Alpha GNU/Linux for ELF)"); - -#undef SUBTARGET_EXTRA_SPECS -#define SUBTARGET_EXTRA_SPECS \ -{ "elf_dynamic_linker", ELF_DYNAMIC_LINKER }, - -#undef SUB_CPP_PREDEFINES -#define SUB_CPP_PREDEFINES "-D__ELF__" - -#ifdef USE_GNULIBC_1 -#define ELF_DYNAMIC_LINKER "/lib/ld.so.1" -#else -#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2" -#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}} " -#endif diff --git a/contrib/gcc/config/alpha/linux.h b/contrib/gcc/config/alpha/linux.h deleted file mode 100644 index b8eb9e915e44..000000000000 --- a/contrib/gcc/config/alpha/linux.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for Alpha Linux-based GNU systems. - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. - Contributed by Richard Henderson. - -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_DEFAULT -#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS) - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES \ -"-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 - -#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 1 - -/* Don't care about faults in the prologue. */ -#undef TARGET_CAN_FAULT_IN_PROLOGUE -#define TARGET_CAN_FAULT_IN_PROLOGUE 1 diff --git a/contrib/gcc/config/alpha/netbsd-elf.h b/contrib/gcc/config/alpha/netbsd-elf.h deleted file mode 100644 index 6e4f4daf62b2..000000000000 --- a/contrib/gcc/config/alpha/netbsd-elf.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Definitions of target machine for GNU compiler - for Alpha NetBSD systems using ELF. - Copyright (C) 1998 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 TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (Alpha NetBSD/ELF)"); - -#undef SUB_CPP_PREDEFINES -#define SUB_CPP_PREDEFINES "-D__ELF__" - -#undef SUBTARGET_EXTRA_SPECS -#define SUBTARGET_EXTRA_SPECS \ -{ "elf_dynamic_linker", ELF_DYNAMIC_LINKER }, - -#define ELF_DYNAMIC_LINKER "/usr/libexec/ld.elf_so" diff --git a/contrib/gcc/config/alpha/netbsd.h b/contrib/gcc/config/alpha/netbsd.h deleted file mode 100644 index 51890643f88e..000000000000 --- a/contrib/gcc/config/alpha/netbsd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for Alpha NetBSD systems. - Copyright (C) 1998 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 TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS) - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-D_LONGLONG -Dnetbsd -Dunix " 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 - -#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 diff --git a/contrib/gcc/config/alpha/openbsd.h b/contrib/gcc/config/alpha/openbsd.h deleted file mode 100644 index 60591d554f56..000000000000 --- a/contrib/gcc/config/alpha/openbsd.h +++ /dev/null @@ -1,126 +0,0 @@ -/* Configuration file for an alpha OpenBSD target. - Copyright (C) 1999 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. */ - -/* We settle for little endian for now. */ -#define TARGET_ENDIAN_DEFAULT 0 - -#include <alpha/alpha.h> - -#define OBSD_NO_DYNAMIC_LIBRARIES -#define OBSD_HAS_DECLARE_FUNCTION_NAME -#define OBSD_HAS_DECLARE_FUNCTION_SIZE -#define OBSD_HAS_DECLARE_OBJECT - -/* alpha ecoff supports only weak aliases, see below. */ -#define ASM_WEAKEN_LABEL(FILE,NAME) ASM_OUTPUT_WEAK_ALIAS (FILE,NAME,0) - -#include <openbsd.h> - -/* Controlling the compilation driver. */ - -/* alpha needs __start. */ -#undef LINK_SPEC -#define LINK_SPEC \ - "%{!nostdlib:%{!r*:%{!e*:-e __start}}} -dc -dp %{assert*}" - -/* run-time target specifications */ -#define CPP_PREDEFINES "-D__unix__ -D__ANSI_COMPAT -Asystem(unix) \ --D__OpenBSD__ -D__alpha__ -D__alpha" - -/* Layout of source language data types. */ - -/* This must agree with <machine/ansi.h> */ -#undef SIZE_TYPE -#define SIZE_TYPE "long unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "int" - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 32 - - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG - -#define LOCAL_LABEL_PREFIX "." - -/* We don't have an init section yet. */ -#undef HAS_INIT_SECTION - -/* collect2 support (assembler format: macros for initialization). */ - -/* Don't tell collect2 we use COFF as we don't have (yet ?) a dynamic ld - library with the proper functions to handle this -> collect2 will - default to using nm. */ -#undef OBJECT_FORMAT_COFF -#undef EXTENDED_COFF - -/* Assembler format: exception region output. */ - -/* All configurations that don't use elf must be explicit about not using - dwarf unwind information. egcs doesn't try too hard to check internal - configuration files... */ -#ifdef INCOMING_RETURN_ADDR_RTX -#undef DWARF2_UNWIND_INFO -#define DWARF2_UNWIND_INFO 0 -#endif - -/* Assembler format: file framework. */ - -/* Taken from alpha/osf.h. This used to be common to all alpha - configurations, but elf has departed from it. - Check alpha/alpha.h, alpha/osf.h for it when egcs is upgraded. */ -#ifndef ASM_FILE_START -#define ASM_FILE_START(FILE) \ -{ \ - alpha_write_verstamp (FILE); \ - fprintf (FILE, "\t.set noreorder\n"); \ - fprintf (FILE, "\t.set volatile\n"); \ - 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_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5") \ - : "ev4")); \ - \ - ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \ -} -#endif - -/* Assembler format: label output. */ - -#define ASM_OUTPUT_WEAK_ALIAS(FILE,NAME,VALUE) \ - do { \ - fputs ("\t.weakext\t", FILE); \ - assemble_name (FILE, NAME); \ - if (VALUE) \ - { \ - fputs (" , ", FILE); \ - assemble_name (FILE, VALUE); \ - } \ - fputc ('\n', FILE); \ - } while (0) - - diff --git a/contrib/gcc/config/alpha/osf.h b/contrib/gcc/config/alpha/osf.h deleted file mode 100644 index 5054444a7599..000000000000 --- a/contrib/gcc/config/alpha/osf.h +++ /dev/null @@ -1,137 +0,0 @@ -/* 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. - 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, -Boston, MA 02111-1307, USA. */ - -/* As of OSF 4.0, as can subtract adjacent labels. */ - -#undef TARGET_AS_CAN_SUBTRACT_LABELS -#define TARGET_AS_CAN_SUBTRACT_LABELS 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)" - -/* 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 - doesn't invade the users' namespace. */ - -#undef CPP_SUBTARGET_SPEC -#define CPP_SUBTARGET_SPEC \ -"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4}" - -/* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf. */ - -#define LIB_SPEC \ -"%{p|pg:-lprof1%{pthread|threads:_r} -lpdf} %{a:-lprof2} \ - %{threads: -lpthreads} %{pthread|threads: -lpthread -lmach -lexc} -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*}" - -#define STARTFILE_SPEC \ - "%{!shared:%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}" - -#define MD_STARTFILE_PREFIX "/usr/lib/cmplrs/cc/" - -#define ASM_FILE_START(FILE) \ -{ \ - alpha_write_verstamp (FILE); \ - fprintf (FILE, "\t.set noreorder\n"); \ - fprintf (FILE, "\t.set volatile\n"); \ - 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_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5") \ - : "ev4")); \ - \ - ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \ -} - -/* 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}" -#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. - ??? Strictly speaking, we need -g only if the user specifies -g. Passing - it always means that we get slightly larger than necessary object files - 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" -#endif - -/* Specify to run a post-processor, mips-tfile after the assembler - has run to stuff the ecoff debug information into the object file. - This is needed because the Alpha assembler provides no way - of specifying such information in the assembly file. */ - -#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GAS) != 0 - -#define ASM_FINAL_SPEC "\ -%{malpha-as: %{!mno-mips-tfile: \ - \n mips-tfile %{v*: -v} \ - %{K: -I %b.o~} \ - %{!K: %{save-temps: -I %b.o~}} \ - %{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %U.o} \ - %{.s:%i} %{!.s:%g.s}}}" - -#else -#define ASM_FINAL_SPEC "\ -%{!mgas: %{!mno-mips-tfile: \ - \n mips-tfile %{v*: -v} \ - %{K: -I %b.o~} \ - %{!K: %{save-temps: -I %b.o~}} \ - %{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %U.o} \ - %{.s:%i} %{!.s:%g.s}}}" - -#endif - -/* Indicate that we have a stamp.h to use. */ -#ifndef CROSS_COMPILE -#define HAVE_STAMP_H 1 -#endif - -/* Attempt to turn on access permissions for the stack. */ - -#define TRANSFER_FROM_TRAMPOLINE \ -void \ -__enable_execute_stack (addr) \ - void *addr; \ -{ \ - long size = getpagesize (); \ - long mask = ~(size-1); \ - char *page = (char *) (((long) addr) & mask); \ - char *end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \ - \ - /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ \ - if (mprotect (page, end - page, 7) < 0) \ - perror ("mprotect of trampoline code"); \ -} diff --git a/contrib/gcc/config/alpha/osf12.h b/contrib/gcc/config/alpha/osf12.h deleted file mode 100644 index 87e21111f4dc..000000000000 --- a/contrib/gcc/config/alpha/osf12.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Definitions of target machine for GNU compiler, for DEC Alpha. - Copyright (C) 1992, 1993, 1995, 1996 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@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, -Boston, MA 02111-1307, USA. */ - -/* In OSF 1.2, there is a linker bug that prevents use of -O3 to - the linker. */ - -#undef LINK_SPEC -#define LINK_SPEC \ - "-G 8 -O1 %{static:-non_shared} %{rpath*} \ - %{!static:%{shared:-shared} %{!shared:-call_shared}} %{taso}" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "short unsigned int" -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 16 diff --git a/contrib/gcc/config/alpha/osf2.h b/contrib/gcc/config/alpha/osf2.h deleted file mode 100644 index 169af5a01c97..000000000000 --- a/contrib/gcc/config/alpha/osf2.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Definitions of target machine for GNU compiler, for DEC Alpha. - Copyright (C) 1992, 1993, 1994 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, -Boston, MA 02111-1307, USA. */ - - -#include "alpha/alpha.h" - -/* In OSF 2.0, the size of wchar_t was changed from short unsigned - to unsigned int. */ - -#undef WCHAR_TYPE -#define WCHAR_TYPE "unsigned int" - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 32 diff --git a/contrib/gcc/config/alpha/osf2or3.h b/contrib/gcc/config/alpha/osf2or3.h deleted file mode 100644 index 5abdb0e98b13..000000000000 --- a/contrib/gcc/config/alpha/osf2or3.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Definitions of target machine for GNU compiler, for DEC Alpha, osf[23]. - Copyright (C) 1997 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. */ - -/* In OSF 2 or 3, linking with -lprof1 doesn't require -lpdf. */ - -#undef LIB_SPEC -#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 - diff --git a/contrib/gcc/config/alpha/t-crtbe b/contrib/gcc/config/alpha/t-crtbe deleted file mode 100644 index 5e82b923c720..000000000000 --- a/contrib/gcc/config/alpha/t-crtbe +++ /dev/null @@ -1,9 +0,0 @@ -# Effectively disable the crtbegin/end rules using crtstuff.c -T = disable - -# Assemble startup files. -crtbegin.o: $(srcdir)/config/alpha/crtbegin.asm $(GCC_PASSES) - $(GCC_FOR_TARGET) -c -o crtbegin.o -x assembler $(srcdir)/config/alpha/crtbegin.asm - -crtend.o: $(srcdir)/config/alpha/crtend.asm $(GCC_PASSES) - $(GCC_FOR_TARGET) -c -o crtend.o -x assembler $(srcdir)/config/alpha/crtend.asm diff --git a/contrib/gcc/config/alpha/t-ieee b/contrib/gcc/config/alpha/t-ieee deleted file mode 100644 index a1f93db1b2d0..000000000000 --- a/contrib/gcc/config/alpha/t-ieee +++ /dev/null @@ -1,6 +0,0 @@ -# All alphas get an IEEE complaint set of libraries. -MULTILIB_OPTIONS = mieee -MULTILIB_DIRNAMES = ieee - -LIBGCC = stmp-multilib -INSTALL_LIBGCC = install-multilib diff --git a/contrib/gcc/config/alpha/t-interix b/contrib/gcc/config/alpha/t-interix deleted file mode 100644 index d6d80e9c085e..000000000000 --- a/contrib/gcc/config/alpha/t-interix +++ /dev/null @@ -1,16 +0,0 @@ -# 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 - -LIB1ASMSRC = alpha/lib1funcs.asm -LIB1ASMFUNCS = _divqu _divq _divlu _divl _remqu _remq _remlu _reml diff --git a/contrib/gcc/config/alpha/t-vms b/contrib/gcc/config/alpha/t-vms deleted file mode 100644 index 12ac24098ce7..000000000000 --- a/contrib/gcc/config/alpha/t-vms +++ /dev/null @@ -1,6 +0,0 @@ -# Do not build libgcc1. -LIBGCC1 = -CROSS_LIBGCC1 = - -LIB2FUNCS_EXTRA = tramp.s - diff --git a/contrib/gcc/config/alpha/va_list.h b/contrib/gcc/config/alpha/va_list.h deleted file mode 100644 index c9ab2b0b50e2..000000000000 --- a/contrib/gcc/config/alpha/va_list.h +++ /dev/null @@ -1,16 +0,0 @@ -/* A replacement for Digital Unix's <va_list.h>. */ - -#include <va-alpha.h> - -#if !defined(_VA_LIST) && !defined(_HIDDEN_VA_LIST) -#define _VA_LIST -typedef __gnuc_va_list va_list; - -#elif defined(_HIDDEN_VA_LIST) && !defined(_HIDDEN_VA_LIST_DONE) -#define _HIDDEN_VA_LIST_DONE -typedef __gnuc_va_list __va_list; - -#elif defined(_HIDDEN_VA_LIST) && defined(_VA_LIST) -#undef _HIDDEN_VA_LIST - -#endif diff --git a/contrib/gcc/config/alpha/vms-tramp.asm b/contrib/gcc/config/alpha/vms-tramp.asm deleted file mode 100644 index fce9ec539cad..000000000000 --- a/contrib/gcc/config/alpha/vms-tramp.asm +++ /dev/null @@ -1,22 +0,0 @@ -;# New Alpha OpenVMS trampoline -;# - .set noreorder - .set volatile - .set noat - .file 1 "tramp.s" -.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/vms.h b/contrib/gcc/config/alpha/vms.h deleted file mode 100644 index 44388b2cf33d..000000000000 --- a/contrib/gcc/config/alpha/vms.h +++ /dev/null @@ -1,506 +0,0 @@ -/* Output variables, constants and external declarations, for GNU compiler. - Copyright (C) 1996, 1997, 1998 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. */ - -#define OPEN_VMS 1 - -/* This enables certain macros in alpha.h, which will make an indirect - reference to an external symbol an invalid address. This needs to be - defined before we include alpha.h, since it determines which macros - are used for GO_IF_*. */ - -#define NO_EXTERNAL_INDIRECT_ADDRESS - -#include "alpha/alpha.h" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES \ -"-D__ALPHA -Dvms -DVMS -D__vms__ -D__VMS__ -Asystem(vms)" - -#undef CPP_SUBTARGET_SPEC -#define CPP_SUBTARGET_SPEC "\ -%{mfloat-ieee:-D__IEEE_FLOAT} \ -%{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_NAME -#define TARGET_NAME "OpenVMS/Alpha" -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (%s)", TARGET_NAME); - -/* The structure return address arrives as an "argument" on VMS. */ -#undef STRUCT_VALUE_REGNUM -#define STRUCT_VALUE 0 -#undef PCC_STATIC_STRUCT_RETURN - -/* no floating emulation. */ -#undef REAL_ARITHMETIC - -/* "long" is 32 bits. */ -#undef LONG_TYPE_SIZE -#define LONG_TYPE_SIZE 32 - -/* 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 - -#define MAX_OFILE_ALIGNMENT 524288 /* 8 x 2^16 by DEC Ada Test CD40VRA */ - -#undef FIXED_REGISTERS -#define FIXED_REGISTERS \ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } - -#undef CALL_USED_REGISTERS -#define CALL_USED_REGISTERS \ - {1, 1, 0, 0, 0, 0, 0, 0, 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, 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 } - -#undef HARD_FRAME_POINTER_REGNUM -#define HARD_FRAME_POINTER_REGNUM 29 - -#undef CAN_ELIMINATE -#define CAN_ELIMINATE(FROM, TO) \ -((TO) != STACK_POINTER_REGNUM || ! alpha_using_fp ()) - -#undef INITIAL_ELIMINATION_OFFSET -#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ -{ if ((FROM) == FRAME_POINTER_REGNUM) \ - (OFFSET) = alpha_sa_size () + alpha_pv_save_size (); \ - else if ((FROM) == ARG_POINTER_REGNUM) \ - (OFFSET) = (ALPHA_ROUND (alpha_sa_size () + alpha_pv_save_size () \ - + get_frame_size () \ - + current_function_pretend_args_size) \ - - current_function_pretend_args_size); \ - if ((TO) == STACK_POINTER_REGNUM) \ - (OFFSET) += ALPHA_ROUND (current_function_outgoing_args_size); \ -} - -/* 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 Alpha/VMS, this is a structure that contains the number of - arguments and, for each argument, the datatype of that argument. - - The number of arguments is a number of words of arguments scanned so far. - 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; - -#undef CUMULATIVE_ARGS -#define CUMULATIVE_ARGS avms_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) \ - (CUM).num_args = 0; \ - (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)) \ - (CUM).num_args += 6; \ - else \ - { \ - if ((CUM).num_args < 6) \ - (CUM).atypes[(CUM).num_args] = alpha_arg_type (MODE); \ - \ - (CUM).num_args += ALPHA_ARG_SIZE (MODE, TYPE, NAMED); \ - } - -/* For an arg passed partly in registers and partly in memory, - this is the number of registers used. - For args passed entirely in registers or entirely in memory, zero. */ - -#undef FUNCTION_ARG_PARTIAL_NREGS -#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ -((CUM).num_args < 6 && 6 < (CUM).num_args \ - + ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \ - ? 6 - (CUM).num_args : 0) - -/* Perform any needed actions needed for a function that is receiving a - variable number of arguments. - - CUM is as for INIT_CUMULATIVE_ARGS. - - MODE and TYPE are the mode and type of the current parameter. - - PRETEND_SIZE is a variable that should be set to the amount of stack - that must be pushed by the prolog to pretend that our caller pushed - it. - - Normally, this macro will push all remaining incoming registers on the - stack and set PRETEND_SIZE to the length of the registers pushed. - - For VMS, we allocate space for all 6 arg registers plus a count. - - However, if NO registers need to be saved, don't allocate any space. - This is not only because we won't need the space, but because AP includes - the current_pretend_args_size and we don't want to mess up any - ap-relative addresses already made. */ - -#undef SETUP_INCOMING_VARARGS -#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \ -{ if ((CUM).num_args < 6) \ - { \ - if (! (NO_RTL)) \ - { \ - emit_move_insn (gen_rtx (REG, DImode, 1), \ - virtual_incoming_args_rtx); \ - emit_insn (gen_arg_home ()); \ - } \ - \ - PRETEND_SIZE = 7 * UNITS_PER_WORD; \ - } \ -} - -#undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ -{ \ - alpha_write_verstamp (FILE); \ - fprintf (FILE, "\t.set noreorder\n"); \ - fprintf (FILE, "\t.set volatile\n"); \ - 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" - -#undef EXTRA_SECTIONS -#define EXTRA_SECTIONS in_link, in_rdata, in_literals, in_ctors, in_dtors - -#undef EXTRA_SECTION_FUNCTIONS -#define EXTRA_SECTION_FUNCTIONS \ -void \ -readonly_section () \ -{ \ - if (in_section != in_rdata) \ - { \ - fprintf (asm_out_file, "%s\n", READONLY_SECTION_ASM_OP); \ - in_section = in_rdata; \ - } \ -} \ -void \ -link_section () \ -{ \ - if (in_section != in_link) \ - { \ - fprintf (asm_out_file, "%s\n", LINK_SECTION_ASM_OP); \ - in_section = in_link; \ - } \ -} \ -void \ -literals_section () \ -{ \ - if (in_section != in_literals) \ - { \ - 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; \ - } \ -} - -#undef ASM_OUTPUT_ADDR_DIFF_ELT -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort () - -#undef ASM_OUTPUT_ADDR_VEC_ELT -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - fprintf (FILE, "\t.quad $L%d\n", (VALUE)) - -#undef READONLY_DATA_SECTION -#define READONLY_DATA_SECTION readonly_section - -#define ASM_FILE_END(FILE) alpha_write_linkage (FILE); - -#undef CASE_VECTOR_MODE -#define CASE_VECTOR_MODE DImode -#undef CASE_VECTOR_PC_RELATIVE - -#undef ASM_OUTPUT_CASE_LABEL -#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \ -{ ASM_OUTPUT_ALIGN (FILE, 3); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); } - -/* This says how to output assembler code to declare an - uninitialized external linkage data object. */ - -#define COMMON_ASM_OP ".comm" - -#undef ASM_OUTPUT_ALIGNED_COMMON -#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \ -do { \ - fprintf ((FILE), "\t%s\t", 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. - - 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. */ - -#undef TRAMPOLINE_TEMPLATE -#define TRAMPOLINE_TEMPLATE(FILE) \ -{ \ - fprintf (FILE, "\t.quad 0\n"); \ - fprintf (FILE, "\t.linkage __tramp\n"); \ - fprintf (FILE, "\t.quad 0\n"); \ -} - -/* Length in units of the trampoline for entering a nested function. */ - -#undef TRAMPOLINE_SIZE -#define TRAMPOLINE_SIZE 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. */ - -#undef INITIALIZE_TRAMPOLINE -#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 (); - -#undef SDB_DEBUGGING_INFO -#undef MIPS_DEBUGGING_INFO -#undef DBX_DEBUGGING_INFO - -#define DWARF2_DEBUGGING_INFO - -/* This is how to output an assembler line - that says to advance the location counter - to a multiple of 2**LOG bytes. */ - -#undef ASM_OUTPUT_ALIGN -#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) - -#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \ - do { literals_section(); \ - fprintf ((FILE), "\t"); \ - assemble_name (FILE, LABEL1); \ - fprintf (FILE, " = "); \ - assemble_name (FILE, LABEL2); \ - fprintf (FILE, "\n"); \ - } while (0) - -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG - -#undef ASM_FORMAT_PRIVATE_NAME -#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ -( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 12), \ - sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO))) - -/* ??? VMS uses different linkage. */ -#undef ASM_OUTPUT_MI_THUNK - -#undef ASM_SPEC -#undef ASM_FINAL_SPEC -#undef LINK_SPEC -#undef STARTFILE_SPEC -#define ASM_SPEC "-nocpp %{pg}" -#define LINK_SPEC "%{g3:-g3} %{g0:-g0} %{shared:-shared} %{v:-v}" - -/* Define the names of the division and modulus functions. */ -#define DIVSI3_LIBCALL "OTS$DIV_I" -#define DIVDI3_LIBCALL "OTS$DIV_L" -#define UDIVSI3_LIBCALL "OTS$DIV_UI" -#define UDIVDI3_LIBCALL "OTS$DIV_UL" -#define MODSI3_LIBCALL "OTS$REM_I" -#define MODDI3_LIBCALL "OTS$REM_L" -#define UMODSI3_LIBCALL "OTS$REM_UI" -#define UMODDI3_LIBCALL "OTS$REM_UL" - -#define DIR_SEPARATOR ']' - -#define PREFIX "GNU_ROOT:" diff --git a/contrib/gcc/config/alpha/vxworks.h b/contrib/gcc/config/alpha/vxworks.h deleted file mode 100644 index 7ef1feeb8028..000000000000 --- a/contrib/gcc/config/alpha/vxworks.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Definitions of target machine for GNU compiler. Vxworks Alpha version. - Copyright (C) 1998 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. */ - -/* This file just exists to give specs for the Alpha running on VxWorks. */ - -#undef CPP_SUBTARGET_SPEC -#define CPP_SUBTARGET_SPEC "\ -%{mvxsim:-DCPU=SIMALPHADUNIX} \ -%{!mvxsim: %{!mcpu*|mcpu=21064:-DCPU=21064} %{mcpu=21164:-DCPU=21164}} \ -%{posix: -D_POSIX_SOURCE}" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "\ --D__vxworks -D__alpha_vxworks -Asystem(vxworks) \ --Asystem(embedded) -D_LONGLONG" - -/* VxWorks does all the library stuff itself. */ - -#undef LIB_SPEC -#define LIB_SPEC "" - -/* VxWorks uses object files, not loadable images. Make linker just combine - objects. Also show using 32 bit mode and set start of text to 0. */ - -#undef LINK_SPEC -#define LINK_SPEC "-r -taso -T 0" - -/* VxWorks provides the functionality of crt0.o and friends itself. */ - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "" diff --git a/contrib/gcc/config/alpha/x-alpha b/contrib/gcc/config/alpha/x-alpha deleted file mode 100644 index 9686ab96472a..000000000000 --- a/contrib/gcc/config/alpha/x-alpha +++ /dev/null @@ -1,2 +0,0 @@ -CLIB=-lmld -EXTRA_HEADERS = $(srcdir)/config/alpha/va_list.h diff --git a/contrib/gcc/config/alpha/xm-alpha-interix.h b/contrib/gcc/config/alpha/xm-alpha-interix.h deleted file mode 100644 index 02c53b814129..000000000000 --- a/contrib/gcc/config/alpha/xm-alpha-interix.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Configuration for GNU compiler - for an DEC/Compaq Alpha - Copyright (C) 1999 Free Software Foundation, Inc. - Donn Terry, Softway Systems, Inc. - derived from code by Douglas B. Rupp (drupp@cs.washington.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, -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 -#else -# define HOST_WIDE_INT __int64 -#endif - - -#define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG -#ifdef __GNUC__ -# define HOST_WIDEST_INT long long -#else -# define HOST_WIDEST_INT __int64 -#endif -#define HOST_WIDEST_INT_PRINT_DEC "%lld" -#define HOST_WIDEST_INT_PRINT_UNSIGNED "%llu" -#define HOST_WIDEST_INT_PRINT_HEX "0x%llx" diff --git a/contrib/gcc/config/alpha/xm-alpha.h b/contrib/gcc/config/alpha/xm-alpha.h deleted file mode 100644 index c04844fdacde..000000000000 --- a/contrib/gcc/config/alpha/xm-alpha.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Configuration for GNU C-compiler for DEC Alpha. - Copyright (C) 1990, 1992, 1993, 1994, 1995 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, -Boston, MA 02111-1307, USA. */ - - -/* #defines that need visibility everywhere. */ -#define FALSE 0 -#define TRUE 1 - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 64 -#define HOST_BITS_PER_LONGLONG 64 - -/* #define HOST_WORDS_BIG_ENDIAN */ - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ -#include "tm.h" - -/* Arguments to use with `exit'. */ -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -/* If compiled with GNU C, use the builtin alloca. */ -#ifndef alloca -#if defined(__GNUC__) && !defined(USE_C_ALLOCA) -#define alloca __builtin_alloca -#else -#if !defined(_WIN32) && !defined(USE_C_ALLOCA) && !defined(OPEN_VMS) && !defined(__INTERIX) -#include <alloca.h> -#else -extern void *alloca (); -#endif -#endif -#endif - -/* The host compiler has problems with enum bitfields since it makes - them signed so we can't fit all our codes in. */ - -#ifndef __GNUC__ -#define ONLY_INT_FIELDS -#endif - -/* Declare some functions needed for this machine. We don't want to - include these in the sources since other machines might define them - differently. */ - -extern void *malloc (), *realloc (), *calloc (); - -#ifndef inhibit_libc -#include "string.h" -#endif - -/* OSF/1 is POSIX.1 compliant. */ - -#define POSIX diff --git a/contrib/gcc/config/alpha/xm-openbsd.h b/contrib/gcc/config/alpha/xm-openbsd.h deleted file mode 100644 index 50f436695a71..000000000000 --- a/contrib/gcc/config/alpha/xm-openbsd.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Configuration file for an host running alpha OpenBSD. - Copyright (C) 1999 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. */ - -#include <xm-openbsd.h> -#include <alpha/xm-alpha.h> - diff --git a/contrib/gcc/config/alpha/xm-vms.h b/contrib/gcc/config/alpha/xm-vms.h deleted file mode 100644 index 472a225672be..000000000000 --- a/contrib/gcc/config/alpha/xm-vms.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Configuration for GNU C-compiler for openVMS/Alpha. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. - Contributed by Klaus Kaempf (kkaempf@progis.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. */ - -/* 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 - -#define NO_SYS_PARAMS_H /* Don't have <sys/params.h> */ -#define USE_C_ALLOCA /* Using alloca.c */ - -#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 OBJECT_SUFFIX ".obj" -#define EXECUTABLE_SUFFIX ".exe" |