From: Richard Sandiford Date: Thu, 25 Jul 2002 10:16:00 +0000 (+0000) Subject: invoke.texi: Document -mabi=meabi, and expand on the EABI description. X-Git-Tag: releases/gcc-3.3.0~3638 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a27fb29b8039f0077b92dfb8a7687becc90d67a2;p=thirdparty%2Fgcc.git invoke.texi: Document -mabi=meabi, and expand on the EABI description. * doc/invoke.texi: Document -mabi=meabi, and expand on the EABI description. Document -mips32, -mips64, and the associated -march values. Describe the "mipsN" arguments to -march. Say that the -mipsN options are equivalent to -march. Reword the description of default type sizes. * toplev.h (target_flags_explicit): Declare. * toplev.c (target_flags_explicit): New var. (set_target_switch): Update target_flags_explicit. * config/mips/abi64.h (SUBTARGET_TARGET_OPTIONS): Undefine. * config/mips/elf64.h (MIPS_ISA_DEFAULT): Undefine. * config/mips/iris6.h (SUBTARGET_ASM_SPEC): -mabi=64 implies -mips3. * config/mips/isa3264.h (MIPS_ENABLE_EMBEDDED_O32): Undefine. * config/mips/mips.h (mips_cpu_info): New struct. (mips_cpu_string, mips_explicit_type_size_string): Remove. (mips_cpu_info_table, mips_arch_info, mips_tune_info): Declare. (MIPS_CPP_SET_PROCESSOR): New macro. (TARGET_CPP_BUILTINS): Declare a macro for each supported processor. Define _MIPS_ARCH and _MIPS_TUNE. (MIPS_ISA_DEFAULT): Don't provide a default value. Instead... (MIPS_CPU_STRING_DEFAULT): Set to "from-abi" if neither it nor MIPS_ISA_DEFAULT were already defined. (MULTILIB_DEFAULTS): Add MULTILIB_ABI_DEFAULT. (TARGET_OPTIONS): Remove -mcpu and -mexplicit-type-size. (ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New. (GAS_ASM_SPEC): Remove -march, -mcpu, -mgp* and -mabi rules. (ABI_GAS_ASM_SPEC): Remove. (MULTILIB_ABI_DEFAULT, ASM_ABI_DEFAULT_SPEC): New macros. (ASM_SPEC): Add -mgp32, -mgp64, -march, -mabi=eabi and -mabi=o64. Invoke %(asm_abi_default_spec) if no ABI was specified. (CC1_SPEC): Remove ISA -> register-size rules. (EXTRA_SPECS): Remove abi_gas_asm_spec. Add asm_abi_default_spec. * config/mips/mips.c (mips_arch_info, mips_tune_info): New vars. (mips_cpu_string, mips_explicit_type_size_string): Remove. (mips_cpu_info_table): New array. (mips_set_architecture, mips_set_tune): New fns. (override_options): Rework to make -mipsN equivalent to -march. Detect more erroneous cases, including those removed from CC1_SPEC. Don't change the ABI based on architecture, or vice versa. Unify logic with GAS. (mips_asm_file_start): Get architecture name from mips_arch_info. (mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns. (mips_parse_cpu): Take the name of the option as argument. Handle 'from-abi'. Raise an error if the option is wrong. (mips_cpu_info_from_isa): New fn. [gcc/testsuite] * gcc.dg/mips-args-[123].c: New tests. From-SVN: r55747 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e75a97d56f1d..ad40abd9b0bd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,50 @@ +2002-07-25 Richard Sandiford + + * doc/invoke.texi: Document -mabi=meabi, and expand on the EABI + description. Document -mips32, -mips64, and the associated -march + values. Describe the "mipsN" arguments to -march. Say that the + -mipsN options are equivalent to -march. Reword the description + of default type sizes. + * toplev.h (target_flags_explicit): Declare. + * toplev.c (target_flags_explicit): New var. + (set_target_switch): Update target_flags_explicit. + * config/mips/abi64.h (SUBTARGET_TARGET_OPTIONS): Undefine. + * config/mips/elf64.h (MIPS_ISA_DEFAULT): Undefine. + * config/mips/iris6.h (SUBTARGET_ASM_SPEC): -mabi=64 implies -mips3. + * config/mips/isa3264.h (MIPS_ENABLE_EMBEDDED_O32): Undefine. + * config/mips/mips.h (mips_cpu_info): New struct. + (mips_cpu_string, mips_explicit_type_size_string): Remove. + (mips_cpu_info_table, mips_arch_info, mips_tune_info): Declare. + (MIPS_CPP_SET_PROCESSOR): New macro. + (TARGET_CPP_BUILTINS): Declare a macro for each supported processor. + Define _MIPS_ARCH and _MIPS_TUNE. + (MIPS_ISA_DEFAULT): Don't provide a default value. Instead... + (MIPS_CPU_STRING_DEFAULT): Set to "from-abi" if neither it nor + MIPS_ISA_DEFAULT were already defined. + (MULTILIB_DEFAULTS): Add MULTILIB_ABI_DEFAULT. + (TARGET_OPTIONS): Remove -mcpu and -mexplicit-type-size. + (ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New. + (GAS_ASM_SPEC): Remove -march, -mcpu, -mgp* and -mabi rules. + (ABI_GAS_ASM_SPEC): Remove. + (MULTILIB_ABI_DEFAULT, ASM_ABI_DEFAULT_SPEC): New macros. + (ASM_SPEC): Add -mgp32, -mgp64, -march, -mabi=eabi and -mabi=o64. + Invoke %(asm_abi_default_spec) if no ABI was specified. + (CC1_SPEC): Remove ISA -> register-size rules. + (EXTRA_SPECS): Remove abi_gas_asm_spec. Add asm_abi_default_spec. + * config/mips/mips.c (mips_arch_info, mips_tune_info): New vars. + (mips_cpu_string, mips_explicit_type_size_string): Remove. + (mips_cpu_info_table): New array. + (mips_set_architecture, mips_set_tune): New fns. + (override_options): Rework to make -mipsN equivalent to -march. + Detect more erroneous cases, including those removed from CC1_SPEC. + Don't change the ABI based on architecture, or vice versa. + Unify logic with GAS. + (mips_asm_file_start): Get architecture name from mips_arch_info. + (mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns. + (mips_parse_cpu): Take the name of the option as argument. Handle + 'from-abi'. Raise an error if the option is wrong. + (mips_cpu_info_from_isa): New fn. + 2002-07-25 Richard Sandiford * config/mips/mips.md (tablejump_mips161): Use gen_rtx_LABEL_REF. diff --git a/gcc/config/mips/abi64.h b/gcc/config/mips/abi64.h index c5125d794413..86b8aa819d18 100644 --- a/gcc/config/mips/abi64.h +++ b/gcc/config/mips/abi64.h @@ -21,11 +21,6 @@ Boston, MA 02111-1307, USA. */ /* Macros to implement the 64 bit ABI. This file is meant to be included after mips.h. */ -#undef SUBTARGET_TARGET_OPTIONS -#define SUBTARGET_TARGET_OPTIONS \ - { "abi=", &mips_abi_string, \ - "Specify ABI to use"}, - #undef STACK_BOUNDARY #define STACK_BOUNDARY \ ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \ diff --git a/gcc/config/mips/elf64.h b/gcc/config/mips/elf64.h index ee226b916dd7..4fd74313ed0c 100644 --- a/gcc/config/mips/elf64.h +++ b/gcc/config/mips/elf64.h @@ -22,15 +22,12 @@ Boston, MA 02111-1307, USA. */ #define OBJECT_FORMAT_ELF -/* Default to -mips3. */ +/* If an embedded ABI is selected, prefer to generate 64-bit code. + Implies -mips3 in such cases. */ #ifndef TARGET_DEFAULT #define TARGET_DEFAULT MASK_FLOAT64|MASK_64BIT #endif -#ifndef MIPS_ISA_DEFAULT -#define MIPS_ISA_DEFAULT 3 -#endif - /* This should change to n32 when it is supported in gas. */ #ifndef MIPS_ABI_DEFAULT #define MIPS_ABI_DEFAULT ABI_O64 diff --git a/gcc/config/mips/iris6.h b/gcc/config/mips/iris6.h index 4dac304cbf9d..e42fa541ec1f 100644 --- a/gcc/config/mips/iris6.h +++ b/gcc/config/mips/iris6.h @@ -238,7 +238,7 @@ Boston, MA 02111-1307, USA. */ on the mipsX option. */ /* If no mips[3,4] option given, give the appropriate default for mabi=X */ #undef SUBTARGET_ASM_SPEC -#define SUBTARGET_ASM_SPEC "%{!mabi*:-n32} %{!mips*: %{!mabi*:-mips3} %{mabi=n32:-mips3} %{mabi=64:-mips4}}" +#define SUBTARGET_ASM_SPEC "%{!mabi*:-n32} %{!mips*: %{!mabi*:-mips3} %{mabi=n32|mabi=64:-mips3}}" /* Must pass -g0 to the assembler, otherwise it may overwrite our debug info with its own debug info. */ diff --git a/gcc/config/mips/isa3264.h b/gcc/config/mips/isa3264.h index fc2b2894225b..b7ab601cfec3 100644 --- a/gcc/config/mips/isa3264.h +++ b/gcc/config/mips/isa3264.h @@ -27,10 +27,6 @@ Boston, MA 02111-1307, USA. */ #define MIPS_ABI_DEFAULT ABI_MEABI #endif -#ifndef MIPS_ENABLE_EMBEDDED_O32 -#define MIPS_ENABLE_EMBEDDED_O32 1 -#endif - #ifndef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG #endif diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 56225f4e9e23..8c5a34ffbc78 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -119,7 +119,15 @@ static int symbolic_expression_p PARAMS ((rtx)); static bool mips_assemble_integer PARAMS ((rtx, unsigned int, int)); static void mips_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT)); static void mips_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT)); -static enum processor_type mips_parse_cpu PARAMS ((const char *)); +static void mips_set_architecture PARAMS ((const struct mips_cpu_info *)); +static void mips_set_tune PARAMS ((const struct mips_cpu_info *)); +static bool mips_strict_matching_cpu_name_p PARAMS ((const char *, + const char *)); +static bool mips_matching_cpu_name_p PARAMS ((const char *, + const char *)); +static const struct mips_cpu_info *mips_parse_cpu PARAMS ((const char *, + const char *)); +static const struct mips_cpu_info *mips_cpu_info_from_isa PARAMS ((int)); static void copy_file_data PARAMS ((FILE *, FILE *)); #ifdef TARGET_IRIX6 static void iris6_asm_named_section_1 PARAMS ((const char *, @@ -294,9 +302,11 @@ enum cmp_type branch_type; /* The target cpu for code generation. */ enum processor_type mips_arch; +const struct mips_cpu_info *mips_arch_info; /* The target cpu for optimization and scheduling. */ enum processor_type mips_tune; +const struct mips_cpu_info *mips_tune_info; /* which instruction set architecture to use. */ int mips_isa; @@ -305,7 +315,6 @@ int mips_isa; int mips_abi; /* Strings to hold which cpu and instruction set architecture to use. */ -const char *mips_cpu_string; /* for -mcpu= */ const char *mips_arch_string; /* for -march= */ const char *mips_tune_string; /* for -mtune= */ const char *mips_isa_string; /* for -mips{1,2,3,4} */ @@ -320,11 +329,6 @@ int mips16; just a way to avoid using up another bit in target_flags. */ const char *mips_no_mips16_string; -/* This is only used to determine if an type size setting option was - explicitly specified (-mlong64, -mint64, -mlong32). The specs - set this option if such an option is used. */ -const char *mips_explicit_type_size_string; - /* Whether we are generating mips16 hard float code. In mips16 mode we always set TARGET_SOFT_FLOAT; this variable is nonzero if -msoft-float was not specified by the user, which means that we @@ -562,6 +566,54 @@ enum reg_class mips_char_to_class[256] = NO_REGS, NO_REGS, NO_REGS, NO_REGS, }; +/* A table describing all the processors gcc knows about. Names are + matched in the order listed. The first mention of an ISA level is + taken as the canonical name for that ISA. + + To ease comparison, please keep this table in the same order as + gas's mips_cpu_info_table[]. */ +const struct mips_cpu_info mips_cpu_info_table[] = { + /* Entries for generic ISAs */ + { "mips1", PROCESSOR_R3000, 1 }, + { "mips2", PROCESSOR_R6000, 2 }, + { "mips3", PROCESSOR_R4000, 3 }, + { "mips4", PROCESSOR_R8000, 4 }, + { "mips32", PROCESSOR_R4KC, 32 }, + { "mips64", PROCESSOR_R5KC, 64 }, + + /* MIPS I */ + { "r3000", PROCESSOR_R3000, 1 }, + { "r2000", PROCESSOR_R3000, 1 }, /* = r3000 */ + { "r3900", PROCESSOR_R3900, 1 }, + + /* MIPS II */ + { "r6000", PROCESSOR_R6000, 2 }, + + /* MIPS III */ + { "r4000", PROCESSOR_R4000, 3 }, + { "vr4100", PROCESSOR_R4100, 3 }, + { "vr4300", PROCESSOR_R4300, 3 }, + { "r4400", PROCESSOR_R4000, 3 }, /* = r4000 */ + { "r4600", PROCESSOR_R4600, 3 }, + { "orion", PROCESSOR_R4600, 3 }, /* = r4600 */ + { "r4650", PROCESSOR_R4650, 3 }, + + /* MIPS IV */ + { "r8000", PROCESSOR_R8000, 4 }, + { "vr5000", PROCESSOR_R5000, 4 }, + + /* MIPS 32 */ + { "4kc", PROCESSOR_R4KC, 32 }, + { "4kp", PROCESSOR_R4KC, 32 }, /* = 4kc */ + + /* MIPS 64 */ + { "5kc", PROCESSOR_R5KC, 64 }, + { "20kc", PROCESSOR_R20KC, 64 }, + + /* End marker */ + { 0, 0, 0 } +}; + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -4931,16 +4983,44 @@ abort_with_insn (insn, reason) abort (); } +/* Set up globals to generate code for the ISA or processor + described by INFO. */ + +static void +mips_set_architecture (info) + const struct mips_cpu_info *info; +{ + if (info != 0) + { + mips_arch_info = info; + mips_arch = info->cpu; + mips_isa = info->isa; + } +} + + +/* Likewise for tuning. */ + +static void +mips_set_tune (info) + const struct mips_cpu_info *info; +{ + if (info != 0) + { + mips_tune_info = info; + mips_tune = info->cpu; + } +} + + /* Set up the threshold for data to go into the small data area, instead of the normal data area, and detect any conflicts in the switches. */ void override_options () { - register int i, start; - register int regno; - register enum machine_mode mode; - register enum processor_type mips_cpu; + int i, start, regno; + enum machine_mode mode; mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE; @@ -4958,250 +5038,137 @@ override_options () target_flags &= ~((TARGET_DEFAULT) & (MASK_SOFT_FLOAT | MASK_SINGLE_FLOAT)); #endif - /* Get the architectural level. */ - if (mips_isa_string == 0) - mips_isa = MIPS_ISA_DEFAULT; + /* Interpret -mabi. */ + mips_abi = MIPS_ABI_DEFAULT; + if (mips_abi_string != 0) + { + if (strcmp (mips_abi_string, "32") == 0) + mips_abi = ABI_32; + else if (strcmp (mips_abi_string, "o64") == 0) + mips_abi = ABI_O64; + else if (strcmp (mips_abi_string, "n32") == 0) + mips_abi = ABI_N32; + else if (strcmp (mips_abi_string, "64") == 0) + mips_abi = ABI_64; + else if (strcmp (mips_abi_string, "eabi") == 0) + mips_abi = ABI_EABI; + else if (strcmp (mips_abi_string, "meabi") == 0) + mips_abi = ABI_MEABI; + else + fatal_error ("bad value (%s) for -mabi= switch", mips_abi_string); + } + + /* The following code determines the architecture and register size. + Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()). + The GAS and GCC code should be kept in sync as much as possible. */ - else if (mips_isa_string != 0 - && mips_arch_string != 0) - warning ("The -march option is incompatible to -mipsN and therefore ignored."); + if (mips_arch_string != 0) + mips_set_architecture (mips_parse_cpu ("-march", mips_arch_string)); - else if (ISDIGIT (*mips_isa_string)) + if (mips_tune_string != 0) + mips_set_tune (mips_parse_cpu ("-mtune", mips_tune_string)); + + if (mips_isa_string != 0) { - mips_isa = atoi (mips_isa_string); - if (mips_isa == 16) + /* Handle -mipsN. */ + int level = atoi (mips_isa_string); + if (level == 16) { - /* -mno-mips16 overrides -mips16. */ + /* -mips16 specifies an ASE rather than a processor, so don't + change mips_arch here. -mno-mips16 overrides -mips16. */ if (mips_no_mips16_string == NULL) - { - target_flags |= MASK_MIPS16; - if (TARGET_64BIT) - mips_isa = 3; - else - mips_isa = MIPS_ISA_DEFAULT; - } - else - { - mips_isa = MIPS_ISA_DEFAULT; - } + target_flags |= MASK_MIPS16; } - else if (mips_isa < 1 - || (mips_isa > 4 - && mips_isa != 32 - && mips_isa != 64)) + else if (mips_arch_info != 0) { - error ("-mips%d not supported", mips_isa); - mips_isa = 1; + /* -march takes precedence over -mipsN, since it is more descriptive. + There's no harm in specifying both as long as the ISA levels + are the same. */ + if (mips_isa != level) + error ("-mips%d conflicts with the other architecture options, which specify a MIPS%d processor", + level, mips_isa); } - } - - else - { - error ("bad value (%s) for -mips switch", mips_isa_string); - mips_isa = 1; - } - -#ifdef MIPS_ABI_DEFAULT - /* Get the ABI to use. */ - if (mips_abi_string == (char *) 0) - mips_abi = MIPS_ABI_DEFAULT; - else if (! strcmp (mips_abi_string, "32")) - mips_abi = ABI_32; - else if (! strcmp (mips_abi_string, "o64")) - mips_abi = ABI_O64; - else if (! strcmp (mips_abi_string, "n32")) - mips_abi = ABI_N32; - else if (! strcmp (mips_abi_string, "64")) - mips_abi = ABI_64; - else if (! strcmp (mips_abi_string, "eabi")) - mips_abi = ABI_EABI; - else if (! strcmp (mips_abi_string, "meabi")) - mips_abi = ABI_MEABI; - else - error ("bad value (%s) for -mabi= switch", mips_abi_string); - - /* A specified ISA defaults the ABI if it was not specified. */ - if (mips_abi_string == 0 && mips_isa_string - && mips_abi != ABI_EABI - && mips_abi != ABI_O64 - && mips_abi != ABI_MEABI) - { - if (mips_isa == 64) - mips_abi = ABI_O64; else { - if (! ISA_HAS_64BIT_REGS) - mips_abi = ABI_32; - else if (mips_abi != ABI_N32) - mips_abi = ABI_64; + mips_set_architecture (mips_cpu_info_from_isa (level)); + if (mips_arch_info == 0) + error ("bad value (%s) for -mips switch", mips_isa_string); } } -#ifdef MIPS_CPU_STRING_DEFAULT - /* A specified ABI defaults the ISA if it was not specified. */ - else if (mips_isa_string == 0 && mips_abi_string - && mips_abi != ABI_EABI && mips_abi != ABI_O64) - { - if (mips_abi == ABI_32) - mips_isa = 1; - else if (mips_abi == ABI_N32) - mips_isa = 3; - else - mips_isa = 4; - } -#endif - - /* If both ABI and ISA were specified, check for conflicts. */ - else if (mips_isa_string && mips_abi_string) + if (mips_arch_info == 0) { - if (! ISA_HAS_64BIT_REGS && (mips_abi == ABI_N32 || mips_abi == ABI_64 - || mips_abi == ABI_O64)) - error ("-mabi=%s does not support -mips%d", mips_abi_string, mips_isa); - } - - /* Override TARGET_DEFAULT if necessary. */ - if (mips_abi == ABI_32) - target_flags &= ~ (MASK_FLOAT64|MASK_64BIT); - - /* If no type size setting options (-mlong64,-mint64,-mlong32) were used - then set the type sizes. In the EABI in 64 bit mode, longs and - pointers are 64 bits. Likewise for the SGI Irix6 N64 ABI. */ - if (mips_explicit_type_size_string == NULL - && ((mips_abi == ABI_EABI && TARGET_64BIT) - || mips_abi == ABI_64)) - target_flags |= MASK_LONG64; - +#ifdef MIPS_CPU_STRING_DEFAULT + mips_set_architecture (mips_parse_cpu ("default CPU", + MIPS_CPU_STRING_DEFAULT)); #else - if (mips_abi_string) - error ("this target does not support the -mabi switch"); + mips_set_architecture (mips_cpu_info_from_isa (MIPS_ISA_DEFAULT)); #endif + } -#ifdef MIPS_CPU_STRING_DEFAULT - /* ??? There is a minor inconsistency here. If the user specifies an ISA - greater than that supported by the default processor, then the user gets - an error. Normally, the compiler will just default to the base level cpu - for the indicated isa. */ - if (mips_arch_string == 0) - mips_arch_string = MIPS_CPU_STRING_DEFAULT; - if (mips_tune_string == 0) - mips_tune_string = MIPS_CPU_STRING_DEFAULT; -#endif + if (ABI_NEEDS_64BIT_REGS && !ISA_HAS_64BIT_REGS) + error ("-march=%s is not compatible with the selected ABI", + mips_arch_info->name); - /* Identify the processor type. */ + /* Optimize for mips_arch, unless -mtune selects a different processor. */ + if (mips_tune_info == 0) + mips_set_tune (mips_arch_info); - if (mips_cpu_string != 0) + if ((target_flags_explicit & MASK_64BIT) != 0) { - mips_cpu = mips_parse_cpu (mips_cpu_string); - if (mips_cpu == PROCESSOR_DEFAULT) - { - error ("bad value (%s) for -mcpu= switch", mips_cpu_string); - mips_cpu_string = "default"; - } - mips_arch = mips_cpu; - mips_tune = mips_cpu; - } - - if (mips_arch_string == 0 - || ! strcmp (mips_arch_string, "default") - || ! strcmp (mips_arch_string, "DEFAULT")) - { - switch (mips_isa) - { - default: - mips_arch_string = "3000"; - mips_arch = PROCESSOR_R3000; - break; - case 2: - mips_arch_string = "6000"; - mips_arch = PROCESSOR_R6000; - break; - case 3: - mips_arch_string = "4000"; - mips_arch = PROCESSOR_R4000; - break; - case 4: - mips_arch_string = "8000"; - mips_arch = PROCESSOR_R8000; - break; - case 32: - mips_arch_string = "4kc"; - mips_arch = PROCESSOR_R4KC; - break; - case 64: - mips_arch_string = "5kc"; - mips_arch = PROCESSOR_R5KC; - break; - } + /* The user specified the size of the integer registers. Make sure + it agrees with the ABI and ISA. */ + if (TARGET_64BIT && !ISA_HAS_64BIT_REGS) + error ("-mgp64 used with a 32-bit processor"); + else if (!TARGET_64BIT && ABI_NEEDS_64BIT_REGS) + error ("-mgp32 used with a 64-bit ABI"); + else if (TARGET_64BIT && ABI_NEEDS_32BIT_REGS) + error ("-mgp64 used with a 32-bit ABI"); } else { - mips_arch = mips_parse_cpu (mips_arch_string); - if (mips_arch == PROCESSOR_DEFAULT) - { - error ("bad value (%s) for -march= switch", mips_arch_string); - mips_arch_string = "default"; - } - } - if (mips_tune_string == 0 - || ! strcmp (mips_tune_string, "default") - || ! strcmp (mips_tune_string, "DEFAULT")) - { - if (mips_arch != PROCESSOR_DEFAULT) - mips_tune = mips_arch; + /* Infer the integer register size from the ABI and processor. + Restrict ourselves to 32-bit registers if that's all the + processor has, or if the ABI cannot handle 64-bit registers. */ + if (ABI_NEEDS_32BIT_REGS || !ISA_HAS_64BIT_REGS) + target_flags &= ~MASK_64BIT; else - switch (mips_isa) - { - default: - mips_tune_string = "3000"; - mips_tune = PROCESSOR_R3000; - break; - case 2: - mips_tune_string = "6000"; - mips_tune = PROCESSOR_R6000; - break; - case 3: - mips_tune_string = "4000"; - mips_tune = PROCESSOR_R4000; - break; - case 4: - mips_tune_string = "8000"; - mips_tune = PROCESSOR_R8000; - break; - case 32: - mips_tune_string = "4kc"; - mips_tune = PROCESSOR_R4KC; - break; - case 64: - mips_tune_string = "5kc"; - mips_tune = PROCESSOR_R5KC; - break; - } + target_flags |= MASK_64BIT; + } + if ((target_flags_explicit & MASK_FLOAT64) != 0) + { + /* Really, -mfp32 and -mfp64 are ornamental options. There's + only one right answer here. */ + if (TARGET_64BIT && TARGET_DOUBLE_FLOAT && !TARGET_FLOAT64) + error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float"); + else if (!TARGET_64BIT && TARGET_FLOAT64) + error ("unsupported combination: %s", "-mgp32 -mfp64"); + else if (TARGET_SINGLE_FLOAT && TARGET_FLOAT64) + error ("unsupported combination: %s", "-mfp64 -msingle-float"); } else { - mips_tune = mips_parse_cpu (mips_tune_string); - if (mips_tune == PROCESSOR_DEFAULT) - { - error ("bad value (%s) for -mtune= switch", mips_tune_string); - mips_tune_string = "default"; - } + /* -msingle-float selects 32-bit float registers. Otherwise the + float registers should be the same size as the integer ones. */ + if (TARGET_64BIT && TARGET_DOUBLE_FLOAT) + target_flags |= MASK_FLOAT64; + else + target_flags &= ~MASK_FLOAT64; } - /* make sure sizes of ints/longs/etc. are ok */ - if (! ISA_HAS_64BIT_REGS) - { - if (TARGET_FLOAT64) - { - error ("-mips%d does not support 64 bit fp registers", mips_isa); - target_flags &= ~ MASK_FLOAT64; - } + /* End of code shared with GAS. */ - else if (TARGET_64BIT) - { - error ("-mips%d does not support 64 bit gp registers", mips_isa); - target_flags &= ~MASK_64BIT; - } + if ((target_flags_explicit & MASK_LONG64) == 0) + { + /* If no type size setting options (-mlong64,-mint64,-mlong32) + were used, then set the type sizes. In the EABI in 64 bit mode, + longs and pointers are 64 bits. Likewise for the SGI Irix6 N64 + ABI. */ + if ((mips_abi == ABI_EABI && TARGET_64BIT) || mips_abi == ABI_64) + target_flags |= MASK_LONG64; + else + target_flags &= ~MASK_LONG64; } if (mips_abi != ABI_32 && mips_abi != ABI_O64) @@ -6361,7 +6328,7 @@ mips_asm_file_start (stream) if (flag_verbose_asm) fprintf (stream, "\n%s -G value = %d, Arch = %s, ISA = %d\n", ASM_COMMENT_START, - mips_section_threshold, mips_arch_string, mips_isa); + mips_section_threshold, mips_arch_info->name, mips_isa); } /* If we are optimizing the global pointer, emit the text section now and any @@ -10166,115 +10133,120 @@ mips_output_conditional_branch (insn, /* NOTREACHED */ return 0; } + +/* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL + with a final "000" replaced by "k". Ignore case. + + Note: this function is shared between GCC and GAS. */ -static enum processor_type -mips_parse_cpu (cpu_string) - const char *cpu_string; +static bool +mips_strict_matching_cpu_name_p (canonical, given) + const char *canonical, *given; { - const char *p = cpu_string; - int seen_v = 0; - enum processor_type cpu; - int warn_upper_case = 0; + while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical)) + given++, canonical++; - /* We need to cope with the various "vr" prefixes for the NEC 4300 - and 4100 processors. */ - if (*p == 'v' || *p == 'V') - { - if (*p == 'V') - warn_upper_case = 1; - seen_v = 1, p++; - } + return ((*given == 0 && *canonical == 0) + || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0)); +} - if (*p == 'r' || *p == 'R') - { - if (*p == 'R') - warn_upper_case = 1; - p++; - } - if (warn_upper_case) - warning ("the cpu name must be lower case"); +/* Return true if GIVEN matches CANONICAL, where GIVEN is a user-supplied + CPU name. We've traditionally allowed a lot of variation here. - /* Since there is no difference between a R2000 and R3000 in - terms of the scheduler, we collapse them into just an R3000. */ + Note: this function is shared between GCC and GAS. */ - cpu = PROCESSOR_DEFAULT; - switch (*p) - { - case '2': - if (!strcmp (p, "2000") || !strcmp (p, "2k") || !strcmp (p, "2K")) - cpu = PROCESSOR_R3000; - else if (!strcmp (p, "20kc") || !strcmp (p, "20Kc") ) - cpu = PROCESSOR_R20KC; - break; +static bool +mips_matching_cpu_name_p (canonical, given) + const char *canonical, *given; +{ + /* First see if the name matches exactly, or with a final "000" + turned into "k". */ + if (mips_strict_matching_cpu_name_p (canonical, given)) + return true; - case '3': - if (!strcmp (p, "3000") || !strcmp (p, "3k") || !strcmp (p, "3K")) - cpu = PROCESSOR_R3000; - else if (!strcmp (p, "3900")) - cpu = PROCESSOR_R3900; - break; + /* If not, try comparing based on numerical designation alone. + See if GIVEN is an unadorned number, or 'r' followed by a number. */ + if (TOLOWER (*given) == 'r') + given++; + if (!ISDIGIT (*given)) + return false; - case '4': - if (!strcmp (p, "4000") || !strcmp (p, "4k") || !strcmp (p, "4K")) - cpu = PROCESSOR_R4000; - /* The vr4100 is a non-FP ISA III processor with some extra - instructions. */ - else if (!strcmp (p, "4100")) - cpu = PROCESSOR_R4100; - /* The vr4300 is a standard ISA III processor, but with a different - pipeline. */ - else if (!strcmp (p, "4300")) - cpu = PROCESSOR_R4300; - /* The r4400 is exactly the same as the r4000 from the compiler's - viewpoint. */ - else if (!strcmp (p, "4400")) - cpu = PROCESSOR_R4000; - else if (!strcmp (p, "4600")) - cpu = PROCESSOR_R4600; - else if (!strcmp (p, "4650")) - cpu = PROCESSOR_R4650; - /* The 4kc and 4kp processor cores are the same for - scheduling purposes; they both implement the MIPS32 - ISA and only differ in their memory management - methods. */ - else if (!strcmp (p, "4kc") || !strcmp (p, "4Kc") - || !strcmp (p, "4kp") || !strcmp (p, "4Kp") ) - cpu = PROCESSOR_R4KC; - break; + /* Skip over some well-known prefixes in the canonical name, + hoping to find a number there too. */ + if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r') + canonical += 2; + else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm') + canonical += 2; + else if (TOLOWER (canonical[0]) == 'r') + canonical += 1; - case '5': - if (!strcmp (p, "5000") || !strcmp (p, "5k") || !strcmp (p, "5K")) - cpu = PROCESSOR_R5000; - else if (!strcmp (p, "5kc") || !strcmp (p, "5Kc") ) - cpu = PROCESSOR_R5KC; - break; + return mips_strict_matching_cpu_name_p (canonical, given); +} - case '6': - if (!strcmp (p, "6000") || !strcmp (p, "6k") || !strcmp (p, "6K")) - cpu = PROCESSOR_R6000; - break; - case '8': - if (!strcmp (p, "8000")) - cpu = PROCESSOR_R8000; - break; +/* Parse an option that takes the name of a processor as its argument. + OPTION is the name of the option and CPU_STRING is the argument. + Return the corresponding processor enumeration if the CPU_STRING is + recognized, otherwise report an error and return null. - case 'o': - if (!strcmp (p, "orion")) - cpu = PROCESSOR_R4600; - break; - } + A similar function exists in GAS. */ + +static const struct mips_cpu_info * +mips_parse_cpu (option, cpu_string) + const char *option, *cpu_string; +{ + const struct mips_cpu_info *p; + const char *s; - if (seen_v - && cpu != PROCESSOR_R4300 - && cpu != PROCESSOR_R4100 - && cpu != PROCESSOR_R5000) - cpu = PROCESSOR_DEFAULT; + /* In the past, we allowed upper-case CPU names, but it doesn't + work well with the multilib machinery. */ + for (s = cpu_string; *s != 0; s++) + if (ISUPPER (*s)) + { + warning ("the cpu name must be lower case"); + break; + } - return cpu; + /* 'from-abi' selects the most compatible architecture for the given + ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs. For the + EABIs, we have to decide whether we're using the 32-bit or 64-bit + version. Look first at the -mgp options, if given, otherwise base + the choice on MASK_64BIT in TARGET_DEFAULT. */ + if (strcasecmp (cpu_string, "from-abi") == 0) + return mips_cpu_info_from_isa (ABI_NEEDS_32BIT_REGS ? 1 + : ABI_NEEDS_64BIT_REGS ? 3 + : (TARGET_64BIT ? 3 : 1)); + + /* 'default' has traditionally been a no-op. Probably not very useful. */ + if (strcasecmp (cpu_string, "default") == 0) + return 0; + + for (p = mips_cpu_info_table; p->name != 0; p++) + if (mips_matching_cpu_name_p (p->name, cpu_string)) + return p; + + error ("bad value (%s) for %s", cpu_string, option); + return 0; } + +/* Return the processor associated with the given ISA level, or null + if the ISA isn't valid. */ + +static const struct mips_cpu_info * +mips_cpu_info_from_isa (isa) + int isa; +{ + const struct mips_cpu_info *p; + + for (p = mips_cpu_info_table; p->name != 0; p++) + if (p->isa == isa) + return p; + + return 0; +} + /* Adjust the cost of INSN based on the relationship between INSN that is dependent on DEP_INSN through the dependence LINK. The default is to make no adjustment to COST. diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 5f2b74ee9bd0..84b6880ddf1d 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -118,6 +118,23 @@ enum block_move_type { BLOCK_MOVE_LAST /* generate just the last store */ }; +/* Information about one recognised processor. Defined here for the + benefit of TARGET_CPU_CPP_BUILTINS. */ +struct mips_cpu_info { + /* The 'canonical' name of the processor as far as GCC is concerned. + It's typically a manufacturer's prefix followed by a numerical + designation. It should be lower case. */ + const char *name; + + /* The internal processor number that most closely matches this + entry. Several processors can have the same value, if there's no + difference between them from GCC's point of view. */ + enum processor_type cpu; + + /* The ISA level that the processor implements. */ + int isa; +}; + extern char mips_reg_names[][8]; /* register names (a0 vs. $4). */ extern char mips_print_operand_punct[256]; /* print_operand punctuation chars */ extern const char *current_function_file; /* filename current function is in */ @@ -146,14 +163,12 @@ extern int mips_isa; /* architectural level */ extern int mips16; /* whether generating mips16 code */ extern int mips16_hard_float; /* mips16 without -msoft-float */ extern int mips_entry; /* generate entry/exit for mips16 */ -extern const char *mips_cpu_string; /* for -mcpu= */ extern const char *mips_arch_string; /* for -march= */ extern const char *mips_tune_string; /* for -mtune= */ extern const char *mips_isa_string; /* for -mips{1,2,3,4} */ extern const char *mips_abi_string; /* for -mabi={32,n32,64} */ extern const char *mips_entry_string; /* for -mentry */ extern const char *mips_no_mips16_string;/* for -mno-mips16 */ -extern const char *mips_explicit_type_size_string;/* for -mexplicit-type-size */ extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */ extern int mips_split_addresses; /* perform high/lo_sum support */ extern int dslots_load_total; /* total # load related delay slots */ @@ -167,6 +182,9 @@ extern GTY(()) rtx mips_load_reg2; /* 2nd reg to check for load delay */ extern GTY(()) rtx mips_load_reg3; /* 3rd reg to check for load delay */ extern GTY(()) rtx mips_load_reg4; /* 4th reg to check for load delay */ extern int mips_string_length; /* length of strings for mips16 */ +extern const struct mips_cpu_info mips_cpu_info_table[]; +extern const struct mips_cpu_info *mips_arch_info; +extern const struct mips_cpu_info *mips_tune_info; /* Functions to change what output section we are using. */ extern void sdata_section PARAMS ((void)); @@ -342,6 +360,25 @@ extern void sbss_section PARAMS ((void)); #define TUNE_MIPS5000 (mips_tune == PROCESSOR_R5000) #define TUNE_MIPS6000 (mips_tune == PROCESSOR_R6000) +/* Define preprocessor macros for the -march and -mtune options. + PREFIX is either _MIPS_ARCH or _MIPS_TUNE, INFO is the selected + processor. If INFO's canonical name is "foo", define PREFIX to + be "foo", and define an additional macro PREFIX_FOO. */ +#define MIPS_CPP_SET_PROCESSOR(PREFIX, INFO) \ + do \ + { \ + char *macro, *p; \ + \ + macro = concat ((PREFIX), "_", (INFO)->name, NULL); \ + for (p = macro; *p != 0; p++) \ + *p = TOUPPER (*p); \ + \ + builtin_define (macro); \ + builtin_define_with_value ((PREFIX), (INFO)->name, 1); \ + free (macro); \ + } \ + while (0) + /* Target CPU builtins. */ #define TARGET_CPU_CPP_BUILTINS() \ do \ @@ -355,16 +392,16 @@ extern void sbss_section PARAMS ((void)); if (!flag_iso) \ builtin_define ("mips"); \ \ + /* Treat _R3000 and _R4000 like register-size defines, \ + which is how they've historically been used. */ \ if (TARGET_64BIT) \ { \ builtin_define ("__mips64"); \ - /* Silly, but will do until processor defines. */ \ builtin_define_std ("R4000"); \ builtin_define ("_R4000"); \ } \ else \ { \ - /* Ditto. */ \ builtin_define_std ("R3000"); \ builtin_define ("_R3000"); \ } \ @@ -376,6 +413,9 @@ extern void sbss_section PARAMS ((void)); if (TARGET_MIPS16) \ builtin_define ("__mips16"); \ \ + MIPS_CPP_SET_PROCESSOR ("_MIPS_ARCH", mips_arch_info); \ + MIPS_CPP_SET_PROCESSOR ("_MIPS_TUNE", mips_tune_info); \ + \ if (ISA_MIPS1) \ { \ builtin_define ("__mips=1"); \ @@ -605,8 +645,11 @@ extern void sbss_section PARAMS ((void)); #define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN #endif +/* 'from-abi' makes a good default: you get whatever the ABI requires. */ #ifndef MIPS_ISA_DEFAULT -#define MIPS_ISA_DEFAULT 1 +#ifndef MIPS_CPU_STRING_DEFAULT +#define MIPS_CPU_STRING_DEFAULT "from-abi" +#endif #endif #ifdef IN_LIBGCC2 @@ -656,7 +699,8 @@ extern void sbss_section PARAMS ((void)); #endif #ifndef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { MULTILIB_ENDIAN_DEFAULT, MULTILIB_ISA_DEFAULT } +#define MULTILIB_DEFAULTS \ + { MULTILIB_ENDIAN_DEFAULT, MULTILIB_ISA_DEFAULT, MULTILIB_ABI_DEFAULT } #endif /* We must pass -EL to the linker by default for little endian embedded @@ -675,20 +719,18 @@ extern void sbss_section PARAMS ((void)); #define TARGET_OPTIONS \ { \ SUBTARGET_TARGET_OPTIONS \ - { "cpu=", &mips_cpu_string, \ - N_("Specify CPU for scheduling purposes")}, \ { "tune=", &mips_tune_string, \ N_("Specify CPU for scheduling purposes")}, \ { "arch=", &mips_arch_string, \ N_("Specify CPU for code generation purposes")}, \ + { "abi=", &mips_abi_string, \ + N_("Specify an ABI")}, \ { "ips", &mips_isa_string, \ N_("Specify a Standard MIPS ISA")}, \ { "entry", &mips_entry_string, \ N_("Use mips16 entry/exit psuedo ops")}, \ { "no-mips16", &mips_no_mips16_string, \ N_("Don't use MIPS16 instructions")}, \ - { "explicit-type-size", &mips_explicit_type_size_string, \ - NULL}, \ { "no-flush-func", &mips_cache_flush_func, \ N_("Don't call any cache flush functions")}, \ { "flush-func=", &mips_cache_flush_func, \ @@ -716,6 +758,16 @@ extern void sbss_section PARAMS ((void)); #define BRANCH_LIKELY_P() GENERATE_BRANCHLIKELY #define HAVE_SQRT_P() (!ISA_MIPS1) +/* True if the ABI can only work with 64-bit integer registers. We + generally allow ad-hoc variations for TARGET_SINGLE_FLOAT, but + otherwise floating-point registers must also be 64-bit. */ +#define ABI_NEEDS_64BIT_REGS (mips_abi == ABI_64 \ + || mips_abi == ABI_O64 \ + || mips_abi == ABI_N32) + +/* Likewise for 32-bit regs. */ +#define ABI_NEEDS_32BIT_REGS (mips_abi == ABI_32) + /* ISA has instructions for managing 64 bit fp and gp regs (eg. mips3). */ #define ISA_HAS_64BIT_REGS (ISA_MIPS3 \ || ISA_MIPS4 \ @@ -911,7 +963,7 @@ while (0) /* GAS_ASM_SPEC is passed when using gas, rather than the MIPS assembler. */ -#define GAS_ASM_SPEC "%{march=*} %{mtune=*} %{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{v} %{mgp32} %{mgp64} %(abi_gas_asm_spec) %{mabi=32:%{!mips*:-mips1}}" +#define GAS_ASM_SPEC "%{mtune=*} %{v}" extern int mips_abi; @@ -920,8 +972,43 @@ extern int mips_abi; #define MIPS_ABI_DEFAULT ABI_32 #endif -#ifndef ABI_GAS_ASM_SPEC -#define ABI_GAS_ASM_SPEC "" +/* Use the most portable ABI flag for the ASM specs. */ + +#if MIPS_ABI_DEFAULT == ABI_32 +#define MULTILIB_ABI_DEFAULT "mabi=32" +#define ASM_ABI_DEFAULT_SPEC "-32" +#endif + +#if MIPS_ABI_DEFAULT == ABI_O64 +#define MULTILIB_ABI_DEFAULT "mabi=o64" +#define ASM_ABI_DEFAULT_SPEC "-mabi=o64" +#endif + +#if MIPS_ABI_DEFAULT == ABI_N32 +#define MULTILIB_ABI_DEFAULT "mabi=n32" +#define ASM_ABI_DEFAULT_SPEC "-n32" +#endif + +#if MIPS_ABI_DEFAULT == ABI_64 +#define MULTILIB_ABI_DEFAULT "mabi=64" +#define ASM_ABI_DEFAULT_SPEC "-64" +#endif + +#if MIPS_ABI_DEFAULT == ABI_EABI +#define MULTILIB_ABI_DEFAULT "mabi=eabi" +#define ASM_ABI_DEFAULT_SPEC "-mabi=eabi" +#endif + +#if MIPS_ABI_DEFAULT == ABI_MEABI +/* Most GAS don't know about MEABI. */ +#define MULTILIB_ABI_DEFAULT "mabi=meabi" +#define ASM_ABI_DEFAULT_SPEC "" +#endif + +/* Only ELF targets can switch the ABI. */ +#ifndef OBJECT_FORMAT_ELF +#undef ASM_ABI_DEFAULT_SPEC +#define ASM_ABI_DEFAULT_SPEC "" #endif /* TARGET_ASM_SPEC is used to select either MIPS_AS_ASM_SPEC or @@ -969,7 +1056,11 @@ extern int mips_abi; #define SUBTARGET_ASM_SPEC "" #endif -/* ASM_SPEC is the set of arguments to pass to the assembler. */ +/* ASM_SPEC is the set of arguments to pass to the assembler. Note: we + pass -mgp32, -mgp64, -march, -mabi=eabi and -meabi=o64 regardless of + whether we're using GAS. These options can only be used properly + with GAS, and it is better to get an error from a non-GAS assembler + than to silently generate bad code. */ #undef ASM_SPEC #define ASM_SPEC "\ @@ -978,7 +1069,9 @@ extern int mips_abi; %(subtarget_asm_optimizing_spec) \ %(subtarget_asm_debugging_spec) \ %{membedded-pic} \ -%{mabi=32:-32}%{mabi=o32:-32}%{mabi=n32:-n32}%{mabi=64:-64}%{mabi=n64:-64} \ +%{mabi=32:-32}%{mabi=n32:-n32}%{mabi=64:-64}%{mabi=n64:-64} \ +%{mabi=eabi} %{mabi=o64} %{!mabi*: %(asm_abi_default_spec)} \ +%{mgp32} %{mgp64} %{march=*} \ %(target_asm_spec) \ %(subtarget_asm_spec)" @@ -1049,15 +1142,6 @@ extern int mips_abi; #ifndef CC1_SPEC #define CC1_SPEC "\ %{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \ -%{mips1:-mfp32 -mgp32} %{mips2:-mfp32 -mgp32}\ -%{mips3:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \ -%{mips4:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \ -%{mips32:-mfp32 -mgp32} \ -%{mips64:%{!msingle-float:-mfp64} -mgp64} \ -%{mfp64:%{msingle-float:%emay not use both -mfp64 and -msingle-float}} \ -%{mfp64:%{m4650:%emay not use both -mfp64 and -m4650}} \ -%{mint64|mlong64|mlong32:-mexplicit-type-size }\ -%{mgp32: %{mfp64:%emay not use both -mgp32 and -mfp64} %{!mfp32: -mfp32}} \ %{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} \ %{save-temps: } \ %(subtarget_cc1_spec)" @@ -1088,12 +1172,12 @@ extern int mips_abi; { "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \ { "mips_as_asm_spec", MIPS_AS_ASM_SPEC }, \ { "gas_asm_spec", GAS_ASM_SPEC }, \ - { "abi_gas_asm_spec", ABI_GAS_ASM_SPEC }, \ { "target_asm_spec", TARGET_ASM_SPEC }, \ { "subtarget_mips_as_asm_spec", SUBTARGET_MIPS_AS_ASM_SPEC }, \ { "subtarget_asm_optimizing_spec", SUBTARGET_ASM_OPTIMIZING_SPEC }, \ { "subtarget_asm_debugging_spec", SUBTARGET_ASM_DEBUGGING_SPEC }, \ { "subtarget_asm_spec", SUBTARGET_ASM_SPEC }, \ + { "asm_abi_default_spec", ASM_ABI_DEFAULT_SPEC }, \ { "endian_spec", ENDIAN_SPEC }, \ SUBTARGET_EXTRA_SPECS diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index f5e0febc5b05..427f5c47384a 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -6976,65 +6976,77 @@ These @samp{-m} options are defined for the MIPS family of computers: @table @gcctabopt -@item -march=@var{cpu-type} +@item -march=@var{arch} @opindex march -Assume the defaults for the machine type @var{cpu-type} when generating -instructions. The choices for @var{cpu-type} are @samp{r2000}, @samp{r3000}, -@samp{r3900}, @samp{r4000}, @samp{r4100}, @samp{r4300}, @samp{r4400}, -@samp{r4600}, @samp{r4650}, @samp{r5000}, @samp{r6000}, @samp{r8000}, -and @samp{orion}. Additionally, the @samp{r2000}, @samp{r3000}, -@samp{r4000}, @samp{r5000}, and @samp{r6000} can be abbreviated as -@samp{r2k} (or @samp{r2K}), @samp{r3k}, etc. - -@item -mtune=@var{cpu-type} +Generate code that will run on @var{arch}, which can be the name of a +generic MIPS ISA, or the name of a particular processor. The ISA names +are: @samp{mips1}, @samp{mips2}, @samp{mips3}, @samp{mips4}, @samp{mips32} +and @samp{mips64}. The processor names are: @samp{r2000}, +@samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{vr4100}, @samp{vr4300}, +@samp{r4400}, @samp{r4600}, @samp{r4650}, @samp{vr5000}, @samp{r6000}, +@samp{r8000}, @samp{4kc}, @samp{4kp}, @samp{5kc}, @samp{20kc} +and @samp{orion}. The special value @samp{from-abi} selects the +most compatible architecture for the selected ABI (that is, +@samp{mips1} for 32-bit ABIs and @samp{mips3} for 64-bit ABIs)@. + +In processor names, a final @samp{000} can be abbreviated as @samp{k} +(for example, @samp{-march=r2k}). Prefixes are optional, and +@samp{vr} may be written @samp{r}. + +GCC defines two macros based on the value of this option. The first +is @samp{_MIPS_ARCH}, which gives the name of target architecture, as +a string. The second has the form @samp{_MIPS_ARCH_@var{foo}}, +where @var{foo} is the capitialized value of @samp{_MIPS_ARCH}@. +For example, @samp{-march=r2000} will set @samp{_MIPS_ARCH} +to @samp{"r2000"} and define the macro @samp{_MIPS_ARCH_R2000}. + +Note that the @samp{_MIPS_ARCH} macro uses the processor names given +above. In other words, it will have the full prefix and will not +abbreviate @samp{000} as @samp{k}. In the case of @samp{from-abi}, +the macro names the resolved architecture (either @samp{"mips1"} or +@samp{"mips3"}). It names the default architecture when no +@option{-march} option is given. + +@item -mtune=@var{arch} @opindex mtune -Assume the defaults for the machine type @var{cpu-type} when scheduling -instructions. The choices for @var{cpu-type} are @samp{r2000}, @samp{r3000}, -@samp{r3900}, @samp{r4000}, @samp{r4100}, @samp{r4300}, @samp{r4400}, -@samp{r4600}, @samp{r4650}, @samp{r5000}, @samp{r6000}, @samp{r8000}, -and @samp{orion}. Additionally, the @samp{r2000}, @samp{r3000}, -@samp{r4000}, @samp{r5000}, and @samp{r6000} can be abbreviated as -@samp{r2k} (or @samp{r2K}), @samp{r3k}, etc. While picking a specific -@var{cpu-type} will schedule things appropriately for that particular -chip, the compiler will not generate any code that does not meet level 1 -of the MIPS ISA (instruction set architecture) without a @option{-mipsX} -or @option{-mabi} switch being used. +Optimize for @var{arch}. Among other things, this option controls +the way instructions are scheduled, and the perceived cost of arithmetic +operations. The list of @var{arch} values is the same as for +@option{-march}. -@item -mcpu=@var{cpu-type} -@opindex mcpu -This is identical to specifying both @option{-march} and @option{-mtune}. +When this option is not used, GCC will optimize for the processor +specified by @option{-march}. By using @option{-march} and +@option{-mtune} together, it is possible to generate code that will +run on a family of processors, but optimize the code for one +particular member of that family. + +@samp{-mtune} defines the macros @samp{_MIPS_TUNE} and +@samp{_MIPS_TUNE_@var{foo}}, which work in the same way as the +@samp{-march} ones described above. @item -mips1 @opindex mips1 -Issue instructions from level 1 of the MIPS ISA@. This is the default. -@samp{r3000} is the default @var{cpu-type} at this ISA level. +Equivalent to @samp{-march=mips1}. @item -mips2 @opindex mips2 -Issue instructions from level 2 of the MIPS ISA (branch likely, square -root instructions). @samp{r6000} is the default @var{cpu-type} at this -ISA level. +Equivalent to @samp{-march=mips2}. @item -mips3 @opindex mips3 -Issue instructions from level 3 of the MIPS ISA (64-bit instructions). -@samp{r4000} is the default @var{cpu-type} at this ISA level. +Equivalent to @samp{-march=mips3}. @item -mips4 @opindex mips4 -Issue instructions from level 4 of the MIPS ISA (conditional move, -prefetch, enhanced FPU instructions). @samp{r8000} is the default -@var{cpu-type} at this ISA level. +Equivalent to @samp{-march=mips4}. -@item -mfp32 -@opindex mfp32 -Assume that 32 32-bit floating point registers are available. This is -the default. +@item -mips32 +@opindex mips32 +Equivalent to @samp{-march=mips32}. -@item -mfp64 -@opindex mfp64 -Assume that 32 64-bit floating point registers are available. This is -the default when the @option{-mips3} option is used. +@item -mips64 +@opindex mips64 +Equivalent to @samp{-march=mips64}. @item -mfused-madd @itemx -mno-fused-madd @@ -7048,15 +7060,21 @@ in the mode where denormals are rounded to zero where denormals generated by multiply and accumulate instructions cause exceptions anyway. +@item -mfp32 +@opindex mfp32 +Assume that floating point registers are 32 bits wide. + +@item -mfp64 +@opindex mfp64 +Assume that floating point registers are 64 bits wide. + @item -mgp32 @opindex mgp32 -Assume that 32 32-bit general purpose registers are available. This is -the default. +Assume that general purpose registers are 32 bits wide. @item -mgp64 @opindex mgp64 -Assume that 32 64-bit general purpose registers are available. This is -the default when the @option{-mips3} option is used. +Assume that general purpose registers are 64 bits wide. @item -mint64 @opindex mint64 @@ -7072,31 +7090,32 @@ explanation of the default, and the width of pointers. @opindex mlong32 Force long, int, and pointer types to be 32 bits wide. -If none of @option{-mlong32}, @option{-mlong64}, or @option{-mint64} are set, -the size of ints, longs, and pointers depends on the ABI and ISA chosen. -For @option{-mabi=32}, and @option{-mabi=n32}, ints and longs are 32 bits -wide. For @option{-mabi=64}, ints are 32 bits, and longs are 64 bits wide. -For @option{-mabi=eabi} and either @option{-mips1} or @option{-mips2}, ints -and longs are 32 bits wide. For @option{-mabi=eabi} and higher ISAs, ints -are 32 bits, and longs are 64 bits wide. The width of pointer types is -the smaller of the width of longs or the width of general purpose -registers (which in turn depends on the ISA)@. +The default size of ints, longs and pointers depends on the ABI@. All +the supported ABIs use 32-bit ints. The n64 ABI uses 64-bit longs, as +does the 64-bit Cygnus EABI; the others use 32-bit longs. Pointers +are the same size as longs, or the same size as integer registers, +whichever is smaller. @item -mabi=32 @itemx -mabi=o64 @itemx -mabi=n32 @itemx -mabi=64 @itemx -mabi=eabi +@itemx -mabi=meabi @opindex mabi=32 @opindex mabi=o64 @opindex mabi=n32 @opindex mabi=64 @opindex mabi=eabi -Generate code for the indicated ABI@. The default instruction level is -@option{-mips1} for @samp{32}, @option{-mips3} for @samp{n32}, and -@option{-mips4} otherwise. Conversely, with @option{-mips1} or -@option{-mips2}, the default ABI is @samp{32}; otherwise, the default ABI -is @samp{64}. +@opindex mabi=meabi +Generate code for the given ABI@. + +Note that there are two embedded ABIs: @option{-mabi=eabi} +selects the one defined by Cygnus while @option{-meabi=meabi} +selects the one defined by MIPS@. Both these ABIs have +32-bit and 64-bit variants. Normally, GCC will generate +64-bit code when you select a 64-bit architecture, but you +can use @option{-mgp32} to get 32-bit code instead. @item -mmips-as @opindex mmips-as diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 531e68802830..991d5e1349b7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-07-25 Richard Sandiford + + * gcc.dg/mips-args-[123].c: New tests. + 2002-07-24 Aldy Hernandez * gcc.dg/ppc-spe.c: New. diff --git a/gcc/testsuite/gcc.dg/mips-args-1.c b/gcc/testsuite/gcc.dg/mips-args-1.c new file mode 100644 index 000000000000..d5799fae0e64 --- /dev/null +++ b/gcc/testsuite/gcc.dg/mips-args-1.c @@ -0,0 +1,35 @@ +/* Check that certain preprocessor macros are defined, and do some + consistency checks. */ +/* { dg-do compile { target mips*-*-* } } */ + +const char *compiled_for = _MIPS_ARCH; +const char *optimized_for = _MIPS_TUNE; + +#if __mips_fpr != 32 && __mips_fpr != 64 +#error Bad __mips_fpr +#endif + +/* Test complementary macro pairs: exactly one of each pair + must be defined. */ + +#if defined (_R3000) == defined (_R4000) +#error _R3000 / _R4000 mismatch +#endif + +#if defined (__mips_hard_float) == defined (__mips_soft_float) +#error __mips_hard_float / __mips_soft_float mismatch +#endif + +#if defined (_MIPSEL) == defined (_MIPSEB) +#error _MIPSEL / _MIPSEB mismatch +#endif + +/* Check for __mips64 consistency. */ + +#if defined (__mips64) != defined (_R4000) +#error __mips64 / _R4000 mismatch +#endif + +#if defined (__mips64) && __mips != 3 && __mips != 4 && __mips != 64 +#error __mips64 / __mips mismatch +#endif diff --git a/gcc/testsuite/gcc.dg/mips-args-2.c b/gcc/testsuite/gcc.dg/mips-args-2.c new file mode 100644 index 000000000000..f53bfb2cde5f --- /dev/null +++ b/gcc/testsuite/gcc.dg/mips-args-2.c @@ -0,0 +1,15 @@ +/* Check the _MIPSEB and _MIPSEL macros are accurate. */ +/* { dg-do run { target mips*-*-* } } */ +short foo = 1; +int main () +{ + char *p = (char *) &foo; + +#ifdef _MIPSEB + if (p[0] != 0 || p[1] != 1) +#else + if (p[0] != 1 || p[1] != 0) +#endif + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/mips-args-3.c b/gcc/testsuite/gcc.dg/mips-args-3.c new file mode 100644 index 000000000000..9ce3553fa94f --- /dev/null +++ b/gcc/testsuite/gcc.dg/mips-args-3.c @@ -0,0 +1,35 @@ +/* __mips, and related defines, guarantee that certain assembly + instructions can be used. Check a few examples. */ +/* { dg-do run { target mips*-*-* } } */ +typedef int int32 __attribute__ ((mode (SI))); +typedef int int64 __attribute__ ((mode (DI))); +int foo (float inf, int64 in64, int32 in32) +{ + int64 res64; + int32 res32; + +#if __mips != 1 && defined (__mips_hard_float) + __asm__ ("trunc.w.s %0, %1" : "=f" (res32) : "f" (inf)); + if (res32 != 11) + abort (); +#endif + +#if defined (__mips64) + __asm__ ("daddu %0, %1, %1" : "=r" (res64) : "r" (in64)); + if (res64 != 50) + abort (); +#endif + +#if (__mips == 4 || __mips == 32 || __mips == 64) && !defined (__mips16) + __asm__ ("move %0,%.\n\tmovn %0,%1,%2" + : "=&r" (res32) : "r" (in32), "r" (in64 != 0)); + if (res32 != 60) + abort (); +#endif +} + +int main () +{ + foo (11.4f, 25, 60); + exit (0); +} diff --git a/gcc/toplev.c b/gcc/toplev.c index c72d37c8f27f..0022fcb289cb 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -179,6 +179,11 @@ const char *dump_base_name; extern int target_flags; +/* A mask of target_flags that includes bit X if X was set or cleared + on the command line. */ + +int target_flags_explicit; + /* Debug hooks - dependent upon command line options. */ const struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks; @@ -4411,6 +4416,13 @@ set_target_switch (name) target_flags &= ~-target_switches[j].value; else target_flags |= target_switches[j].value; + if (name[0] != 0) + { + if (target_switches[j].value < 0) + target_flags_explicit |= -target_switches[j].value; + else + target_flags_explicit |= target_switches[j].value; + } valid_target_option = 1; } diff --git a/gcc/toplev.h b/gcc/toplev.h index 24deaaee8ec3..aa7345b477e6 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -108,6 +108,7 @@ extern void check_global_declarations PARAMS ((union tree_node **, int)); extern const char *progname; extern const char *dump_base_name; +extern int target_flags_explicit; /* The hashtable, so that the C front ends can pass it to cpplib. */ extern struct ht *ident_hash;