Commit a27fb29b by Richard Sandiford Committed by Richard Sandiford

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
parent 6bbdc759
2002-07-25 Richard Sandiford <rsandifo@redhat.com> 2002-07-25 Richard Sandiford <rsandifo@redhat.com>
* 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 <rsandifo@redhat.com>
* config/mips/mips.md (tablejump_mips161): Use gen_rtx_LABEL_REF. * config/mips/mips.md (tablejump_mips161): Use gen_rtx_LABEL_REF.
(tablejump_mips162): Likewise. (tablejump_mips162): Likewise.
......
...@@ -21,11 +21,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -21,11 +21,6 @@ Boston, MA 02111-1307, USA. */
/* Macros to implement the 64 bit ABI. This file is meant to be included /* Macros to implement the 64 bit ABI. This file is meant to be included
after mips.h. */ after mips.h. */
#undef SUBTARGET_TARGET_OPTIONS
#define SUBTARGET_TARGET_OPTIONS \
{ "abi=", &mips_abi_string, \
"Specify ABI to use"},
#undef STACK_BOUNDARY #undef STACK_BOUNDARY
#define STACK_BOUNDARY \ #define STACK_BOUNDARY \
((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \ ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \
......
...@@ -22,15 +22,12 @@ Boston, MA 02111-1307, USA. */ ...@@ -22,15 +22,12 @@ Boston, MA 02111-1307, USA. */
#define OBJECT_FORMAT_ELF #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 #ifndef TARGET_DEFAULT
#define TARGET_DEFAULT MASK_FLOAT64|MASK_64BIT #define TARGET_DEFAULT MASK_FLOAT64|MASK_64BIT
#endif #endif
#ifndef MIPS_ISA_DEFAULT
#define MIPS_ISA_DEFAULT 3
#endif
/* This should change to n32 when it is supported in gas. */ /* This should change to n32 when it is supported in gas. */
#ifndef MIPS_ABI_DEFAULT #ifndef MIPS_ABI_DEFAULT
#define MIPS_ABI_DEFAULT ABI_O64 #define MIPS_ABI_DEFAULT ABI_O64
......
...@@ -238,7 +238,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -238,7 +238,7 @@ Boston, MA 02111-1307, USA. */
on the mipsX option. */ on the mipsX option. */
/* If no mips[3,4] option given, give the appropriate default for mabi=X */ /* If no mips[3,4] option given, give the appropriate default for mabi=X */
#undef SUBTARGET_ASM_SPEC #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 /* Must pass -g0 to the assembler, otherwise it may overwrite our
debug info with its own debug info. */ debug info with its own debug info. */
......
...@@ -27,10 +27,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -27,10 +27,6 @@ Boston, MA 02111-1307, USA. */
#define MIPS_ABI_DEFAULT ABI_MEABI #define MIPS_ABI_DEFAULT ABI_MEABI
#endif #endif
#ifndef MIPS_ENABLE_EMBEDDED_O32
#define MIPS_ENABLE_EMBEDDED_O32 1
#endif
#ifndef PREFERRED_DEBUGGING_TYPE #ifndef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#endif #endif
......
...@@ -119,7 +119,15 @@ static int symbolic_expression_p PARAMS ((rtx)); ...@@ -119,7 +119,15 @@ static int symbolic_expression_p PARAMS ((rtx));
static bool mips_assemble_integer PARAMS ((rtx, unsigned int, int)); 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_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void mips_output_function_prologue 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 *)); static void copy_file_data PARAMS ((FILE *, FILE *));
#ifdef TARGET_IRIX6 #ifdef TARGET_IRIX6
static void iris6_asm_named_section_1 PARAMS ((const char *, static void iris6_asm_named_section_1 PARAMS ((const char *,
...@@ -294,9 +302,11 @@ enum cmp_type branch_type; ...@@ -294,9 +302,11 @@ enum cmp_type branch_type;
/* The target cpu for code generation. */ /* The target cpu for code generation. */
enum processor_type mips_arch; enum processor_type mips_arch;
const struct mips_cpu_info *mips_arch_info;
/* The target cpu for optimization and scheduling. */ /* The target cpu for optimization and scheduling. */
enum processor_type mips_tune; enum processor_type mips_tune;
const struct mips_cpu_info *mips_tune_info;
/* which instruction set architecture to use. */ /* which instruction set architecture to use. */
int mips_isa; int mips_isa;
...@@ -305,7 +315,6 @@ int mips_isa; ...@@ -305,7 +315,6 @@ int mips_isa;
int mips_abi; int mips_abi;
/* Strings to hold which cpu and instruction set architecture to use. */ /* Strings to hold which cpu and instruction set architecture to use. */
const char *mips_cpu_string; /* for -mcpu=<xxx> */
const char *mips_arch_string; /* for -march=<xxx> */ const char *mips_arch_string; /* for -march=<xxx> */
const char *mips_tune_string; /* for -mtune=<xxx> */ const char *mips_tune_string; /* for -mtune=<xxx> */
const char *mips_isa_string; /* for -mips{1,2,3,4} */ const char *mips_isa_string; /* for -mips{1,2,3,4} */
...@@ -320,11 +329,6 @@ int mips16; ...@@ -320,11 +329,6 @@ int mips16;
just a way to avoid using up another bit in target_flags. */ just a way to avoid using up another bit in target_flags. */
const char *mips_no_mips16_string; 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 /* Whether we are generating mips16 hard float code. In mips16 mode
we always set TARGET_SOFT_FLOAT; this variable is nonzero if we always set TARGET_SOFT_FLOAT; this variable is nonzero if
-msoft-float was not specified by the user, which means that we -msoft-float was not specified by the user, which means that we
...@@ -562,6 +566,54 @@ enum reg_class mips_char_to_class[256] = ...@@ -562,6 +566,54 @@ enum reg_class mips_char_to_class[256] =
NO_REGS, NO_REGS, NO_REGS, NO_REGS, 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. */ /* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP #undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
...@@ -4931,16 +4983,44 @@ abort_with_insn (insn, reason) ...@@ -4931,16 +4983,44 @@ abort_with_insn (insn, reason)
abort (); 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 /* 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. */ of the normal data area, and detect any conflicts in the switches. */
void void
override_options () override_options ()
{ {
register int i, start; int i, start, regno;
register int regno; enum machine_mode mode;
register enum machine_mode mode;
register enum processor_type mips_cpu;
mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE; mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE;
...@@ -4958,250 +5038,137 @@ override_options () ...@@ -4958,250 +5038,137 @@ override_options ()
target_flags &= ~((TARGET_DEFAULT) & (MASK_SOFT_FLOAT | MASK_SINGLE_FLOAT)); target_flags &= ~((TARGET_DEFAULT) & (MASK_SOFT_FLOAT | MASK_SINGLE_FLOAT));
#endif #endif
/* Get the architectural level. */ /* Interpret -mabi. */
if (mips_isa_string == 0)
mips_isa = MIPS_ISA_DEFAULT;
else if (mips_isa_string != 0
&& mips_arch_string != 0)
warning ("The -march option is incompatible to -mipsN and therefore ignored.");
else if (ISDIGIT (*mips_isa_string))
{
mips_isa = atoi (mips_isa_string);
if (mips_isa == 16)
{
/* -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;
}
}
else if (mips_isa < 1
|| (mips_isa > 4
&& mips_isa != 32
&& mips_isa != 64))
{
error ("-mips%d not supported", mips_isa);
mips_isa = 1;
}
}
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; mips_abi = MIPS_ABI_DEFAULT;
else if (! strcmp (mips_abi_string, "32")) if (mips_abi_string != 0)
{
if (strcmp (mips_abi_string, "32") == 0)
mips_abi = ABI_32; mips_abi = ABI_32;
else if (! strcmp (mips_abi_string, "o64")) else if (strcmp (mips_abi_string, "o64") == 0)
mips_abi = ABI_O64; mips_abi = ABI_O64;
else if (! strcmp (mips_abi_string, "n32")) else if (strcmp (mips_abi_string, "n32") == 0)
mips_abi = ABI_N32; mips_abi = ABI_N32;
else if (! strcmp (mips_abi_string, "64")) else if (strcmp (mips_abi_string, "64") == 0)
mips_abi = ABI_64; mips_abi = ABI_64;
else if (! strcmp (mips_abi_string, "eabi")) else if (strcmp (mips_abi_string, "eabi") == 0)
mips_abi = ABI_EABI; mips_abi = ABI_EABI;
else if (! strcmp (mips_abi_string, "meabi")) else if (strcmp (mips_abi_string, "meabi") == 0)
mips_abi = ABI_MEABI; mips_abi = ABI_MEABI;
else else
error ("bad value (%s) for -mabi= switch", mips_abi_string); fatal_error ("bad value (%s) for -mabi= switch", mips_abi_string);
}
/* A specified ISA defaults the ABI if it was not specified. */ /* The following code determines the architecture and register size.
if (mips_abi_string == 0 && mips_isa_string Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()).
&& mips_abi != ABI_EABI The GAS and GCC code should be kept in sync as much as possible. */
&& mips_abi != ABI_O64
&& mips_abi != ABI_MEABI) if (mips_arch_string != 0)
mips_set_architecture (mips_parse_cpu ("-march", mips_arch_string));
if (mips_tune_string != 0)
mips_set_tune (mips_parse_cpu ("-mtune", mips_tune_string));
if (mips_isa_string != 0)
{ {
if (mips_isa == 64) /* Handle -mipsN. */
mips_abi = ABI_O64; int level = atoi (mips_isa_string);
else if (level == 16)
{ {
if (! ISA_HAS_64BIT_REGS) /* -mips16 specifies an ASE rather than a processor, so don't
mips_abi = ABI_32; change mips_arch here. -mno-mips16 overrides -mips16. */
else if (mips_abi != ABI_N32) if (mips_no_mips16_string == NULL)
mips_abi = ABI_64; target_flags |= MASK_MIPS16;
}
} }
else if (mips_arch_info != 0)
#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) /* -march takes precedence over -mipsN, since it is more descriptive.
mips_isa = 1; There's no harm in specifying both as long as the ISA levels
else if (mips_abi == ABI_N32) are the same. */
mips_isa = 3; if (mips_isa != level)
else error ("-mips%d conflicts with the other architecture options, which specify a MIPS%d processor",
mips_isa = 4; level, mips_isa);
} }
#endif else
/* If both ABI and ISA were specified, check for conflicts. */
else if (mips_isa_string && mips_abi_string)
{ {
if (! ISA_HAS_64BIT_REGS && (mips_abi == ABI_N32 || mips_abi == ABI_64 mips_set_architecture (mips_cpu_info_from_isa (level));
|| mips_abi == ABI_O64)) if (mips_arch_info == 0)
error ("-mabi=%s does not support -mips%d", mips_abi_string, mips_isa); error ("bad value (%s) for -mips switch", mips_isa_string);
}
} }
/* Override TARGET_DEFAULT if necessary. */ if (mips_arch_info == 0)
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;
#else
if (mips_abi_string)
error ("this target does not support the -mabi switch");
#endif
#ifdef MIPS_CPU_STRING_DEFAULT #ifdef MIPS_CPU_STRING_DEFAULT
/* ??? There is a minor inconsistency here. If the user specifies an ISA mips_set_architecture (mips_parse_cpu ("default CPU",
greater than that supported by the default processor, then the user gets MIPS_CPU_STRING_DEFAULT));
an error. Normally, the compiler will just default to the base level cpu #else
for the indicated isa. */ mips_set_architecture (mips_cpu_info_from_isa (MIPS_ISA_DEFAULT));
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 #endif
}
/* Identify the processor type. */ if (ABI_NEEDS_64BIT_REGS && !ISA_HAS_64BIT_REGS)
error ("-march=%s is not compatible with the selected ABI",
mips_arch_info->name);
if (mips_cpu_string != 0) /* Optimize for mips_arch, unless -mtune selects a different processor. */
{ if (mips_tune_info == 0)
mips_cpu = mips_parse_cpu (mips_cpu_string); mips_set_tune (mips_arch_info);
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 if ((target_flags_explicit & MASK_64BIT) != 0)
|| ! strcmp (mips_arch_string, "default")
|| ! strcmp (mips_arch_string, "DEFAULT"))
{
switch (mips_isa)
{ {
default: /* The user specified the size of the integer registers. Make sure
mips_arch_string = "3000"; it agrees with the ABI and ISA. */
mips_arch = PROCESSOR_R3000; if (TARGET_64BIT && !ISA_HAS_64BIT_REGS)
break; error ("-mgp64 used with a 32-bit processor");
case 2: else if (!TARGET_64BIT && ABI_NEEDS_64BIT_REGS)
mips_arch_string = "6000"; error ("-mgp32 used with a 64-bit ABI");
mips_arch = PROCESSOR_R6000; else if (TARGET_64BIT && ABI_NEEDS_32BIT_REGS)
break; error ("-mgp64 used with a 32-bit ABI");
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;
}
} }
else else
{ {
mips_arch = mips_parse_cpu (mips_arch_string); /* Infer the integer register size from the ABI and processor.
if (mips_arch == PROCESSOR_DEFAULT) Restrict ourselves to 32-bit registers if that's all the
{ processor has, or if the ABI cannot handle 64-bit registers. */
error ("bad value (%s) for -march= switch", mips_arch_string); if (ABI_NEEDS_32BIT_REGS || !ISA_HAS_64BIT_REGS)
mips_arch_string = "default"; target_flags &= ~MASK_64BIT;
}
}
if (mips_tune_string == 0
|| ! strcmp (mips_tune_string, "default")
|| ! strcmp (mips_tune_string, "DEFAULT"))
{
if (mips_arch != PROCESSOR_DEFAULT)
mips_tune = mips_arch;
else else
switch (mips_isa) target_flags |= MASK_64BIT;
{
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;
} }
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 else
{ {
mips_tune = mips_parse_cpu (mips_tune_string); /* -msingle-float selects 32-bit float registers. Otherwise the
if (mips_tune == PROCESSOR_DEFAULT) float registers should be the same size as the integer ones. */
{ if (TARGET_64BIT && TARGET_DOUBLE_FLOAT)
error ("bad value (%s) for -mtune= switch", mips_tune_string); target_flags |= MASK_FLOAT64;
mips_tune_string = "default"; else
} target_flags &= ~MASK_FLOAT64;
} }
/* make sure sizes of ints/longs/etc. are ok */ /* End of code shared with GAS. */
if (! ISA_HAS_64BIT_REGS)
{
if (TARGET_FLOAT64)
{
error ("-mips%d does not support 64 bit fp registers", mips_isa);
target_flags &= ~ MASK_FLOAT64;
}
else if (TARGET_64BIT) if ((target_flags_explicit & MASK_LONG64) == 0)
{ {
error ("-mips%d does not support 64 bit gp registers", mips_isa); /* If no type size setting options (-mlong64,-mint64,-mlong32)
target_flags &= ~MASK_64BIT; 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) if (mips_abi != ABI_32 && mips_abi != ABI_O64)
...@@ -6361,7 +6328,7 @@ mips_asm_file_start (stream) ...@@ -6361,7 +6328,7 @@ mips_asm_file_start (stream)
if (flag_verbose_asm) if (flag_verbose_asm)
fprintf (stream, "\n%s -G value = %d, Arch = %s, ISA = %d\n", fprintf (stream, "\n%s -G value = %d, Arch = %s, ISA = %d\n",
ASM_COMMENT_START, 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 /* If we are optimizing the global pointer, emit the text section now and any
...@@ -10167,112 +10134,117 @@ mips_output_conditional_branch (insn, ...@@ -10167,112 +10134,117 @@ mips_output_conditional_branch (insn,
return 0; return 0;
} }
static enum processor_type /* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL
mips_parse_cpu (cpu_string) with a final "000" replaced by "k". Ignore case.
const char *cpu_string;
Note: this function is shared between GCC and GAS. */
static bool
mips_strict_matching_cpu_name_p (canonical, given)
const char *canonical, *given;
{ {
const char *p = cpu_string; while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical))
int seen_v = 0; given++, canonical++;
enum processor_type cpu;
int warn_upper_case = 0;
/* We need to cope with the various "vr" prefixes for the NEC 4300 return ((*given == 0 && *canonical == 0)
and 4100 processors. */ || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0));
if (*p == 'v' || *p == 'V') }
{
if (*p == 'V')
warn_upper_case = 1;
seen_v = 1, p++;
}
if (*p == 'r' || *p == 'R')
{
if (*p == 'R')
warn_upper_case = 1;
p++;
}
if (warn_upper_case) /* Return true if GIVEN matches CANONICAL, where GIVEN is a user-supplied
warning ("the cpu name must be lower case"); CPU name. We've traditionally allowed a lot of variation here.
/* Since there is no difference between a R2000 and R3000 in Note: this function is shared between GCC and GAS. */
terms of the scheduler, we collapse them into just an R3000. */
cpu = PROCESSOR_DEFAULT; static bool
switch (*p) mips_matching_cpu_name_p (canonical, given)
{ const char *canonical, *given;
case '2': {
if (!strcmp (p, "2000") || !strcmp (p, "2k") || !strcmp (p, "2K")) /* First see if the name matches exactly, or with a final "000"
cpu = PROCESSOR_R3000; turned into "k". */
else if (!strcmp (p, "20kc") || !strcmp (p, "20Kc") ) if (mips_strict_matching_cpu_name_p (canonical, given))
cpu = PROCESSOR_R20KC; return true;
break;
case '3': /* If not, try comparing based on numerical designation alone.
if (!strcmp (p, "3000") || !strcmp (p, "3k") || !strcmp (p, "3K")) See if GIVEN is an unadorned number, or 'r' followed by a number. */
cpu = PROCESSOR_R3000; if (TOLOWER (*given) == 'r')
else if (!strcmp (p, "3900")) given++;
cpu = PROCESSOR_R3900; if (!ISDIGIT (*given))
break; return false;
case '4': /* Skip over some well-known prefixes in the canonical name,
if (!strcmp (p, "4000") || !strcmp (p, "4k") || !strcmp (p, "4K")) hoping to find a number there too. */
cpu = PROCESSOR_R4000; if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r')
/* The vr4100 is a non-FP ISA III processor with some extra canonical += 2;
instructions. */ else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm')
else if (!strcmp (p, "4100")) canonical += 2;
cpu = PROCESSOR_R4100; else if (TOLOWER (canonical[0]) == 'r')
/* The vr4300 is a standard ISA III processor, but with a different canonical += 1;
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;
case '5': return mips_strict_matching_cpu_name_p (canonical, given);
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;
case '6':
if (!strcmp (p, "6000") || !strcmp (p, "6k") || !strcmp (p, "6K"))
cpu = PROCESSOR_R6000;
break;
case '8': /* Parse an option that takes the name of a processor as its argument.
if (!strcmp (p, "8000")) OPTION is the name of the option and CPU_STRING is the argument.
cpu = PROCESSOR_R8000; Return the corresponding processor enumeration if the CPU_STRING is
break; recognized, otherwise report an error and return null.
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;
case 'o': /* In the past, we allowed upper-case CPU names, but it doesn't
if (!strcmp (p, "orion")) work well with the multilib machinery. */
cpu = PROCESSOR_R4600; for (s = cpu_string; *s != 0; s++)
if (ISUPPER (*s))
{
warning ("the cpu name must be lower case");
break; break;
} }
if (seen_v /* 'from-abi' selects the most compatible architecture for the given
&& cpu != PROCESSOR_R4300 ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs. For the
&& cpu != PROCESSOR_R4100 EABIs, we have to decide whether we're using the 32-bit or 64-bit
&& cpu != PROCESSOR_R5000) version. Look first at the -mgp options, if given, otherwise base
cpu = PROCESSOR_DEFAULT; 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;
return cpu; 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 /* Adjust the cost of INSN based on the relationship between INSN that
......
...@@ -118,6 +118,23 @@ enum block_move_type { ...@@ -118,6 +118,23 @@ enum block_move_type {
BLOCK_MOVE_LAST /* generate just the last store */ 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_reg_names[][8]; /* register names (a0 vs. $4). */
extern char mips_print_operand_punct[256]; /* print_operand punctuation chars */ extern char mips_print_operand_punct[256]; /* print_operand punctuation chars */
extern const char *current_function_file; /* filename current function is in */ extern const char *current_function_file; /* filename current function is in */
...@@ -146,14 +163,12 @@ extern int mips_isa; /* architectural level */ ...@@ -146,14 +163,12 @@ extern int mips_isa; /* architectural level */
extern int mips16; /* whether generating mips16 code */ extern int mips16; /* whether generating mips16 code */
extern int mips16_hard_float; /* mips16 without -msoft-float */ extern int mips16_hard_float; /* mips16 without -msoft-float */
extern int mips_entry; /* generate entry/exit for mips16 */ extern int mips_entry; /* generate entry/exit for mips16 */
extern const char *mips_cpu_string; /* for -mcpu=<xxx> */
extern const char *mips_arch_string; /* for -march=<xxx> */ extern const char *mips_arch_string; /* for -march=<xxx> */
extern const char *mips_tune_string; /* for -mtune=<xxx> */ extern const char *mips_tune_string; /* for -mtune=<xxx> */
extern const char *mips_isa_string; /* for -mips{1,2,3,4} */ 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_abi_string; /* for -mabi={32,n32,64} */
extern const char *mips_entry_string; /* for -mentry */ extern const char *mips_entry_string; /* for -mentry */
extern const char *mips_no_mips16_string;/* for -mno-mips16 */ 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 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 mips_split_addresses; /* perform high/lo_sum support */
extern int dslots_load_total; /* total # load related delay slots */ 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 */ ...@@ -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_reg3; /* 3rd reg to check for load delay */
extern GTY(()) rtx mips_load_reg4; /* 4th 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 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. */ /* Functions to change what output section we are using. */
extern void sdata_section PARAMS ((void)); extern void sdata_section PARAMS ((void));
...@@ -342,6 +360,25 @@ extern void sbss_section PARAMS ((void)); ...@@ -342,6 +360,25 @@ extern void sbss_section PARAMS ((void));
#define TUNE_MIPS5000 (mips_tune == PROCESSOR_R5000) #define TUNE_MIPS5000 (mips_tune == PROCESSOR_R5000)
#define TUNE_MIPS6000 (mips_tune == PROCESSOR_R6000) #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. */ /* Target CPU builtins. */
#define TARGET_CPU_CPP_BUILTINS() \ #define TARGET_CPU_CPP_BUILTINS() \
do \ do \
...@@ -355,16 +392,16 @@ extern void sbss_section PARAMS ((void)); ...@@ -355,16 +392,16 @@ extern void sbss_section PARAMS ((void));
if (!flag_iso) \ if (!flag_iso) \
builtin_define ("mips"); \ builtin_define ("mips"); \
\ \
/* Treat _R3000 and _R4000 like register-size defines, \
which is how they've historically been used. */ \
if (TARGET_64BIT) \ if (TARGET_64BIT) \
{ \ { \
builtin_define ("__mips64"); \ builtin_define ("__mips64"); \
/* Silly, but will do until processor defines. */ \
builtin_define_std ("R4000"); \ builtin_define_std ("R4000"); \
builtin_define ("_R4000"); \ builtin_define ("_R4000"); \
} \ } \
else \ else \
{ \ { \
/* Ditto. */ \
builtin_define_std ("R3000"); \ builtin_define_std ("R3000"); \
builtin_define ("_R3000"); \ builtin_define ("_R3000"); \
} \ } \
...@@ -376,6 +413,9 @@ extern void sbss_section PARAMS ((void)); ...@@ -376,6 +413,9 @@ extern void sbss_section PARAMS ((void));
if (TARGET_MIPS16) \ if (TARGET_MIPS16) \
builtin_define ("__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) \ if (ISA_MIPS1) \
{ \ { \
builtin_define ("__mips=1"); \ builtin_define ("__mips=1"); \
...@@ -605,8 +645,11 @@ extern void sbss_section PARAMS ((void)); ...@@ -605,8 +645,11 @@ extern void sbss_section PARAMS ((void));
#define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN #define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN
#endif #endif
/* 'from-abi' makes a good default: you get whatever the ABI requires. */
#ifndef MIPS_ISA_DEFAULT #ifndef MIPS_ISA_DEFAULT
#define MIPS_ISA_DEFAULT 1 #ifndef MIPS_CPU_STRING_DEFAULT
#define MIPS_CPU_STRING_DEFAULT "from-abi"
#endif
#endif #endif
#ifdef IN_LIBGCC2 #ifdef IN_LIBGCC2
...@@ -656,7 +699,8 @@ extern void sbss_section PARAMS ((void)); ...@@ -656,7 +699,8 @@ extern void sbss_section PARAMS ((void));
#endif #endif
#ifndef MULTILIB_DEFAULTS #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 #endif
/* We must pass -EL to the linker by default for little endian embedded /* We must pass -EL to the linker by default for little endian embedded
...@@ -675,20 +719,18 @@ extern void sbss_section PARAMS ((void)); ...@@ -675,20 +719,18 @@ extern void sbss_section PARAMS ((void));
#define TARGET_OPTIONS \ #define TARGET_OPTIONS \
{ \ { \
SUBTARGET_TARGET_OPTIONS \ SUBTARGET_TARGET_OPTIONS \
{ "cpu=", &mips_cpu_string, \
N_("Specify CPU for scheduling purposes")}, \
{ "tune=", &mips_tune_string, \ { "tune=", &mips_tune_string, \
N_("Specify CPU for scheduling purposes")}, \ N_("Specify CPU for scheduling purposes")}, \
{ "arch=", &mips_arch_string, \ { "arch=", &mips_arch_string, \
N_("Specify CPU for code generation purposes")}, \ N_("Specify CPU for code generation purposes")}, \
{ "abi=", &mips_abi_string, \
N_("Specify an ABI")}, \
{ "ips", &mips_isa_string, \ { "ips", &mips_isa_string, \
N_("Specify a Standard MIPS ISA")}, \ N_("Specify a Standard MIPS ISA")}, \
{ "entry", &mips_entry_string, \ { "entry", &mips_entry_string, \
N_("Use mips16 entry/exit psuedo ops")}, \ N_("Use mips16 entry/exit psuedo ops")}, \
{ "no-mips16", &mips_no_mips16_string, \ { "no-mips16", &mips_no_mips16_string, \
N_("Don't use MIPS16 instructions")}, \ N_("Don't use MIPS16 instructions")}, \
{ "explicit-type-size", &mips_explicit_type_size_string, \
NULL}, \
{ "no-flush-func", &mips_cache_flush_func, \ { "no-flush-func", &mips_cache_flush_func, \
N_("Don't call any cache flush functions")}, \ N_("Don't call any cache flush functions")}, \
{ "flush-func=", &mips_cache_flush_func, \ { "flush-func=", &mips_cache_flush_func, \
...@@ -716,6 +758,16 @@ extern void sbss_section PARAMS ((void)); ...@@ -716,6 +758,16 @@ extern void sbss_section PARAMS ((void));
#define BRANCH_LIKELY_P() GENERATE_BRANCHLIKELY #define BRANCH_LIKELY_P() GENERATE_BRANCHLIKELY
#define HAVE_SQRT_P() (!ISA_MIPS1) #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). */ /* ISA has instructions for managing 64 bit fp and gp regs (eg. mips3). */
#define ISA_HAS_64BIT_REGS (ISA_MIPS3 \ #define ISA_HAS_64BIT_REGS (ISA_MIPS3 \
|| ISA_MIPS4 \ || ISA_MIPS4 \
...@@ -911,7 +963,7 @@ while (0) ...@@ -911,7 +963,7 @@ while (0)
/* GAS_ASM_SPEC is passed when using gas, rather than the MIPS /* GAS_ASM_SPEC is passed when using gas, rather than the MIPS
assembler. */ 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; extern int mips_abi;
...@@ -920,8 +972,43 @@ extern int mips_abi; ...@@ -920,8 +972,43 @@ extern int mips_abi;
#define MIPS_ABI_DEFAULT ABI_32 #define MIPS_ABI_DEFAULT ABI_32
#endif #endif
#ifndef ABI_GAS_ASM_SPEC /* Use the most portable ABI flag for the ASM specs. */
#define ABI_GAS_ASM_SPEC ""
#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 #endif
/* TARGET_ASM_SPEC is used to select either MIPS_AS_ASM_SPEC or /* TARGET_ASM_SPEC is used to select either MIPS_AS_ASM_SPEC or
...@@ -969,7 +1056,11 @@ extern int mips_abi; ...@@ -969,7 +1056,11 @@ extern int mips_abi;
#define SUBTARGET_ASM_SPEC "" #define SUBTARGET_ASM_SPEC ""
#endif #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 #undef ASM_SPEC
#define ASM_SPEC "\ #define ASM_SPEC "\
...@@ -978,7 +1069,9 @@ extern int mips_abi; ...@@ -978,7 +1069,9 @@ extern int mips_abi;
%(subtarget_asm_optimizing_spec) \ %(subtarget_asm_optimizing_spec) \
%(subtarget_asm_debugging_spec) \ %(subtarget_asm_debugging_spec) \
%{membedded-pic} \ %{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) \ %(target_asm_spec) \
%(subtarget_asm_spec)" %(subtarget_asm_spec)"
...@@ -1049,15 +1142,6 @@ extern int mips_abi; ...@@ -1049,15 +1142,6 @@ extern int mips_abi;
#ifndef CC1_SPEC #ifndef CC1_SPEC
#define CC1_SPEC "\ #define CC1_SPEC "\
%{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \ %{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}} \ %{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} \
%{save-temps: } \ %{save-temps: } \
%(subtarget_cc1_spec)" %(subtarget_cc1_spec)"
...@@ -1088,12 +1172,12 @@ extern int mips_abi; ...@@ -1088,12 +1172,12 @@ extern int mips_abi;
{ "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \ { "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \
{ "mips_as_asm_spec", MIPS_AS_ASM_SPEC }, \ { "mips_as_asm_spec", MIPS_AS_ASM_SPEC }, \
{ "gas_asm_spec", GAS_ASM_SPEC }, \ { "gas_asm_spec", GAS_ASM_SPEC }, \
{ "abi_gas_asm_spec", ABI_GAS_ASM_SPEC }, \
{ "target_asm_spec", TARGET_ASM_SPEC }, \ { "target_asm_spec", TARGET_ASM_SPEC }, \
{ "subtarget_mips_as_asm_spec", SUBTARGET_MIPS_AS_ASM_SPEC }, \ { "subtarget_mips_as_asm_spec", SUBTARGET_MIPS_AS_ASM_SPEC }, \
{ "subtarget_asm_optimizing_spec", SUBTARGET_ASM_OPTIMIZING_SPEC }, \ { "subtarget_asm_optimizing_spec", SUBTARGET_ASM_OPTIMIZING_SPEC }, \
{ "subtarget_asm_debugging_spec", SUBTARGET_ASM_DEBUGGING_SPEC }, \ { "subtarget_asm_debugging_spec", SUBTARGET_ASM_DEBUGGING_SPEC }, \
{ "subtarget_asm_spec", SUBTARGET_ASM_SPEC }, \ { "subtarget_asm_spec", SUBTARGET_ASM_SPEC }, \
{ "asm_abi_default_spec", ASM_ABI_DEFAULT_SPEC }, \
{ "endian_spec", ENDIAN_SPEC }, \ { "endian_spec", ENDIAN_SPEC }, \
SUBTARGET_EXTRA_SPECS SUBTARGET_EXTRA_SPECS
......
...@@ -6976,65 +6976,77 @@ These @samp{-m} options are defined for the MIPS family of computers: ...@@ -6976,65 +6976,77 @@ These @samp{-m} options are defined for the MIPS family of computers:
@table @gcctabopt @table @gcctabopt
@item -march=@var{cpu-type} @item -march=@var{arch}
@opindex march @opindex march
Assume the defaults for the machine type @var{cpu-type} when generating Generate code that will run on @var{arch}, which can be the name of a
instructions. The choices for @var{cpu-type} are @samp{r2000}, @samp{r3000}, generic MIPS ISA, or the name of a particular processor. The ISA names
@samp{r3900}, @samp{r4000}, @samp{r4100}, @samp{r4300}, @samp{r4400}, are: @samp{mips1}, @samp{mips2}, @samp{mips3}, @samp{mips4}, @samp{mips32}
@samp{r4600}, @samp{r4650}, @samp{r5000}, @samp{r6000}, @samp{r8000}, and @samp{mips64}. The processor names are: @samp{r2000},
and @samp{orion}. Additionally, the @samp{r2000}, @samp{r3000}, @samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{vr4100}, @samp{vr4300},
@samp{r4000}, @samp{r5000}, and @samp{r6000} can be abbreviated as @samp{r4400}, @samp{r4600}, @samp{r4650}, @samp{vr5000}, @samp{r6000},
@samp{r2k} (or @samp{r2K}), @samp{r3k}, etc. @samp{r8000}, @samp{4kc}, @samp{4kp}, @samp{5kc}, @samp{20kc}
and @samp{orion}. The special value @samp{from-abi} selects the
@item -mtune=@var{cpu-type} 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 @opindex mtune
Assume the defaults for the machine type @var{cpu-type} when scheduling Optimize for @var{arch}. Among other things, this option controls
instructions. The choices for @var{cpu-type} are @samp{r2000}, @samp{r3000}, the way instructions are scheduled, and the perceived cost of arithmetic
@samp{r3900}, @samp{r4000}, @samp{r4100}, @samp{r4300}, @samp{r4400}, operations. The list of @var{arch} values is the same as for
@samp{r4600}, @samp{r4650}, @samp{r5000}, @samp{r6000}, @samp{r8000}, @option{-march}.
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.
@item -mcpu=@var{cpu-type} When this option is not used, GCC will optimize for the processor
@opindex mcpu specified by @option{-march}. By using @option{-march} and
This is identical to specifying both @option{-march} and @option{-mtune}. @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 @item -mips1
@opindex mips1 @opindex mips1
Issue instructions from level 1 of the MIPS ISA@. This is the default. Equivalent to @samp{-march=mips1}.
@samp{r3000} is the default @var{cpu-type} at this ISA level.
@item -mips2 @item -mips2
@opindex mips2 @opindex mips2
Issue instructions from level 2 of the MIPS ISA (branch likely, square Equivalent to @samp{-march=mips2}.
root instructions). @samp{r6000} is the default @var{cpu-type} at this
ISA level.
@item -mips3 @item -mips3
@opindex mips3 @opindex mips3
Issue instructions from level 3 of the MIPS ISA (64-bit instructions). Equivalent to @samp{-march=mips3}.
@samp{r4000} is the default @var{cpu-type} at this ISA level.
@item -mips4 @item -mips4
@opindex mips4 @opindex mips4
Issue instructions from level 4 of the MIPS ISA (conditional move, Equivalent to @samp{-march=mips4}.
prefetch, enhanced FPU instructions). @samp{r8000} is the default
@var{cpu-type} at this ISA level.
@item -mfp32 @item -mips32
@opindex mfp32 @opindex mips32
Assume that 32 32-bit floating point registers are available. This is Equivalent to @samp{-march=mips32}.
the default.
@item -mfp64 @item -mips64
@opindex mfp64 @opindex mips64
Assume that 32 64-bit floating point registers are available. This is Equivalent to @samp{-march=mips64}.
the default when the @option{-mips3} option is used.
@item -mfused-madd @item -mfused-madd
@itemx -mno-fused-madd @itemx -mno-fused-madd
...@@ -7048,15 +7060,21 @@ in the mode where denormals are rounded to zero where denormals ...@@ -7048,15 +7060,21 @@ in the mode where denormals are rounded to zero where denormals
generated by multiply and accumulate instructions cause exceptions generated by multiply and accumulate instructions cause exceptions
anyway. 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 @item -mgp32
@opindex mgp32 @opindex mgp32
Assume that 32 32-bit general purpose registers are available. This is Assume that general purpose registers are 32 bits wide.
the default.
@item -mgp64 @item -mgp64
@opindex mgp64 @opindex mgp64
Assume that 32 64-bit general purpose registers are available. This is Assume that general purpose registers are 64 bits wide.
the default when the @option{-mips3} option is used.
@item -mint64 @item -mint64
@opindex mint64 @opindex mint64
...@@ -7072,31 +7090,32 @@ explanation of the default, and the width of pointers. ...@@ -7072,31 +7090,32 @@ explanation of the default, and the width of pointers.
@opindex mlong32 @opindex mlong32
Force long, int, and pointer types to be 32 bits wide. Force long, int, and pointer types to be 32 bits wide.
If none of @option{-mlong32}, @option{-mlong64}, or @option{-mint64} are set, The default size of ints, longs and pointers depends on the ABI@. All
the size of ints, longs, and pointers depends on the ABI and ISA chosen. the supported ABIs use 32-bit ints. The n64 ABI uses 64-bit longs, as
For @option{-mabi=32}, and @option{-mabi=n32}, ints and longs are 32 bits does the 64-bit Cygnus EABI; the others use 32-bit longs. Pointers
wide. For @option{-mabi=64}, ints are 32 bits, and longs are 64 bits wide. are the same size as longs, or the same size as integer registers,
For @option{-mabi=eabi} and either @option{-mips1} or @option{-mips2}, ints whichever is smaller.
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)@.
@item -mabi=32 @item -mabi=32
@itemx -mabi=o64 @itemx -mabi=o64
@itemx -mabi=n32 @itemx -mabi=n32
@itemx -mabi=64 @itemx -mabi=64
@itemx -mabi=eabi @itemx -mabi=eabi
@itemx -mabi=meabi
@opindex mabi=32 @opindex mabi=32
@opindex mabi=o64 @opindex mabi=o64
@opindex mabi=n32 @opindex mabi=n32
@opindex mabi=64 @opindex mabi=64
@opindex mabi=eabi @opindex mabi=eabi
Generate code for the indicated ABI@. The default instruction level is @opindex mabi=meabi
@option{-mips1} for @samp{32}, @option{-mips3} for @samp{n32}, and Generate code for the given ABI@.
@option{-mips4} otherwise. Conversely, with @option{-mips1} or
@option{-mips2}, the default ABI is @samp{32}; otherwise, the default ABI Note that there are two embedded ABIs: @option{-mabi=eabi}
is @samp{64}. 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 @item -mmips-as
@opindex mmips-as @opindex mmips-as
......
2002-07-25 Richard Sandiford <rsandifo@redhat.com>
* gcc.dg/mips-args-[123].c: New tests.
2002-07-24 Aldy Hernandez <aldyh@redhat.com> 2002-07-24 Aldy Hernandez <aldyh@redhat.com>
* gcc.dg/ppc-spe.c: New. * gcc.dg/ppc-spe.c: New.
......
/* 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
/* 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);
}
/* __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);
}
...@@ -179,6 +179,11 @@ const char *dump_base_name; ...@@ -179,6 +179,11 @@ const char *dump_base_name;
extern int target_flags; 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. */ /* Debug hooks - dependent upon command line options. */
const struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks; const struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks;
...@@ -4411,6 +4416,13 @@ set_target_switch (name) ...@@ -4411,6 +4416,13 @@ set_target_switch (name)
target_flags &= ~-target_switches[j].value; target_flags &= ~-target_switches[j].value;
else else
target_flags |= target_switches[j].value; 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; valid_target_option = 1;
} }
......
...@@ -108,6 +108,7 @@ extern void check_global_declarations PARAMS ((union tree_node **, int)); ...@@ -108,6 +108,7 @@ extern void check_global_declarations PARAMS ((union tree_node **, int));
extern const char *progname; extern const char *progname;
extern const char *dump_base_name; extern const char *dump_base_name;
extern int target_flags_explicit;
/* The hashtable, so that the C front ends can pass it to cpplib. */ /* The hashtable, so that the C front ends can pass it to cpplib. */
extern struct ht *ident_hash; extern struct ht *ident_hash;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment