+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.
/* 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) \
#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
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. */
#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
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 *,
/* 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;
int mips_abi;
/* 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_tune_string; /* for -mtune=<xxx> */
const char *mips_isa_string; /* for -mips{1,2,3,4} */
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
NO_REGS, NO_REGS, NO_REGS, NO_REGS,
};
\f
+/* 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 }
+};
+\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
abort ();
}
\f
+/* 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;
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)
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);
}
\f
/* If we are optimizing the global pointer, emit the text section now and any
/* NOTREACHED */
return 0;
}
+\f
+/* 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;
+}
+\f
/* 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.
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 */
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=<xxx> */
extern const char *mips_arch_string; /* for -march=<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_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 */
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));
#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 \
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"); \
} \
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"); \
#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
#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
#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, \
#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 \
/* 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;
#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
#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 "\
%(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)"
#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)"
{ "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
@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
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
@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
+2002-07-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcc.dg/mips-args-[123].c: New tests.
+
2002-07-24 Aldy Hernandez <aldyh@redhat.com>
* gcc.dg/ppc-spe.c: New.
--- /dev/null
+/* 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
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* __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);
+}
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;
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;
}
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;