aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2002-07-25 09:48:07 +0000
committerRichard Sandiford <rdsandiford@googlemail.com>2002-07-25 09:48:07 +0000
commit316f5878b98e1adb7ddf6d18c3d3283afebd23a6 (patch)
tree67792470d817a8c9265a46decf1505270c404b3e /gas/config
parent2061187ab5c4a929b2e361107dd69cc8bdf1ae8c (diff)
downloadgdb-316f5878b98e1adb7ddf6d18c3d3283afebd23a6.zip
gdb-316f5878b98e1adb7ddf6d18c3d3283afebd23a6.tar.gz
gdb-316f5878b98e1adb7ddf6d18c3d3283afebd23a6.tar.bz2
[gas/]
* doc/c-mips.texi: Remove -mcpu. Document -mabi. * configure.in (MIPS_CPU_STRING_DEFAULT): New configuration macro. (USE_E_MIPS_ABI_O32, MIPS_DEFAULT_64BIT): New configuration macros. * configure, config.in: Regenerate. * config/tc-mips.c (file_mips_abi): Rename to mips_abi. (mips_set_options): Remove "abi" field. (mips_opts): Update accordingly. Replace all uses of mips_opts.abi with mips_abi. (mips_cpu): Remove. (mips_arch_string, mips_arch_info): New vars. (mips_tune_string, mips_tune_info): New vars. (ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New macros. (HAVE_32BIT_GPRS, HAVE_32BIT_FPRS): Don't check the ABI. (mips_isa_to_str, mips_cpu_to_str): Remove. (mips_ip): If the selected architecture is a generic ISA rather than a processor, only mention the ISA level in error messages. (OPTION_MCPU): Remove. (OPTION_FP64): New. (md_longopts): Add -mfp64, remove -mcpu. (mips_set_option_string): New fn. (md_parse_option): Make -mipsN update file_mips_isa rather than mips_opts.isa. Use mips_set_option_string to set -march or -mtune. Don't let -mgp32 and -mfp32 change the ABI. (show): Move to end of file. Constify string argument. (md_show_usage): Move to the end of the file. Read available architectures from mips_cpu_info_table. (mips_set_architecture): New fn. (mips_after_parse_args): Rework. Remove -mcpu handling. -mipsN is an alias for -march=mipsN. Don't change the ABI based on other flags. Infer the register size from the ABI as well as the architecture. Complain about more conflicting arguments. Unify logic with GCC. (s_mipsset): Don't change the ABI. (mips_elf_final_processing): Check USE_E_MIPS_ABI_O32. (mips_cpu_info_table): Remove Generic-MIPS* entries, keeping just "mipsN"-type entries. Remove entries that vary only in the manufacturer's prefix, or that have "000" replaced by "k". Remove TARGET_CPU entries. Make r2000 entry use CPU_R3000. (mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns. (mips_parse_cpu): New fn. (mips_cpu_info_from_name, mips_cpu_info_from_cpu): Remove. (mips_cpu_info_from_isa): Minor formatting tweak. [gas/testsuite] * gas/mips/mips-gp32-fp64.d, * gas/mips/mips-gp32-fp64-pic.d: Add -mfp64.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-mips.c1053
1 files changed, 436 insertions, 617 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 2ed32d9..2ab8bbe9 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -129,7 +129,7 @@ enum mips_abi_level
};
/* MIPS ABI we are using for this output file. */
-static enum mips_abi_level file_mips_abi = NO_ABI;
+static enum mips_abi_level mips_abi = NO_ABI;
/* This is the set of options which may be modified by the .set
pseudo-op. We use a struct so that .set push and .set pop are more
@@ -177,9 +177,6 @@ struct mips_set_options
is passed but can changed if the assembler code uses .set mipsN. */
int gp32;
int fp32;
- /* The ABI currently in use. This is changed by .set mipsN to loosen
- restrictions and doesn't affect the whole file. */
- enum mips_abi_level abi;
};
/* True if -mgp32 was passed. */
@@ -194,7 +191,7 @@ static int file_mips_fp32 = -1;
static struct mips_set_options mips_opts =
{
- ISA_UNKNOWN, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, NO_ABI
+ ISA_UNKNOWN, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0
};
/* These variables are filled in with the masks of registers used.
@@ -218,18 +215,18 @@ static int file_ase_mips3d;
command line (e.g., by -march). */
static int file_ase_mdmx;
-/* The argument of the -mcpu= flag. Historical for code generation. */
-static int mips_cpu = CPU_UNKNOWN;
-
/* The argument of the -march= flag. The architecture we are assembling. */
static int mips_arch = CPU_UNKNOWN;
+static const char *mips_arch_string;
+static const struct mips_cpu_info *mips_arch_info;
/* The argument of the -mtune= flag. The architecture for which we
are optimizing. */
static int mips_tune = CPU_UNKNOWN;
+static const char *mips_tune_string;
+static const struct mips_cpu_info *mips_tune_info;
-/* If they asked for mips1 or mips2 and a cpu that is
- mips3 or greater, then mark the object file 32BITMODE. */
+/* True when generating 32-bit code for a 64-bit processor. */
static int mips_32bitmode = 0;
/* Some ISA's have delay slots for instructions which read or write
@@ -246,6 +243,15 @@ static int mips_32bitmode = 0;
|| (ISA) == ISA_MIPS3 \
)
+/* True if the given ABI requires 32-bit registers. */
+#define ABI_NEEDS_32BIT_REGS(ABI) ((ABI) == O32_ABI)
+
+/* Likewise 64-bit registers. */
+#define ABI_NEEDS_64BIT_REGS(ABI) \
+ ((ABI) == N32_ABI \
+ || (ABI) == N64_ABI \
+ || (ABI) == O64_ABI)
+
/* Return true if ISA supports 64 bit gp register instructions. */
#define ISA_HAS_64BIT_REGS(ISA) ( \
(ISA) == ISA_MIPS3 \
@@ -255,21 +261,17 @@ static int mips_32bitmode = 0;
)
#define HAVE_32BIT_GPRS \
- (mips_opts.gp32 \
- || mips_opts.abi == O32_ABI \
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
+ (mips_opts.gp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
#define HAVE_32BIT_FPRS \
- (mips_opts.fp32 \
- || mips_opts.abi == O32_ABI \
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
+ (mips_opts.fp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
#define HAVE_64BIT_GPRS (! HAVE_32BIT_GPRS)
#define HAVE_64BIT_FPRS (! HAVE_32BIT_FPRS)
-#define HAVE_NEWABI (mips_opts.abi == N32_ABI || mips_opts.abi == N64_ABI)
+#define HAVE_NEWABI (mips_abi == N32_ABI || mips_abi == N64_ABI)
-#define HAVE_64BIT_OBJECTS (mips_opts.abi == N64_ABI)
+#define HAVE_64BIT_OBJECTS (mips_abi == N64_ABI)
/* We can only have 64bit addresses if the object file format
supports it. */
@@ -737,6 +739,7 @@ static void my_getExpression PARAMS ((expressionS *, char *));
#ifdef OBJ_ELF
static int support_64bit_objects PARAMS((void));
#endif
+static void mips_set_option_string PARAMS ((const char **, const char *));
static symbolS *get_symbol PARAMS ((void));
static void mips_align PARAMS ((int to, int fill, symbolS *label));
static void s_align PARAMS ((int));
@@ -768,10 +771,8 @@ static void s_mips_weakext PARAMS ((int));
static void s_mips_file PARAMS ((int));
static void s_mips_loc PARAMS ((int));
static int mips16_extended_frag PARAMS ((fragS *, asection *, long));
-static const char *mips_isa_to_str PARAMS ((int));
-static const char *mips_cpu_to_str PARAMS ((int));
static int validate_mips_insn PARAMS ((const struct mips_opcode *));
-static void show PARAMS ((FILE *, char *, int *, int *));
+static void show PARAMS ((FILE *, const char *, int *, int *));
#ifdef OBJ_ELF
static int mips_need_elf_addend_fixup PARAMS ((fixS *));
#endif
@@ -813,9 +814,14 @@ struct mips_cpu_info
int cpu; /* CPU number (default CPU if ISA). */
};
-static const struct mips_cpu_info *mips_cpu_info_from_name 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 boolean mips_strict_matching_cpu_name_p PARAMS ((const char *,
+ const char *));
+static boolean 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 const struct mips_cpu_info *mips_cpu_info_from_cpu PARAMS ((int));
/* Pseudo-op table.
@@ -968,36 +974,6 @@ static boolean mips16_small, mips16_ext;
static segT pdr_seg;
-static const char *
-mips_isa_to_str (isa)
- int isa;
-{
- const struct mips_cpu_info *ci;
- static char s[20];
-
- ci = mips_cpu_info_from_isa (isa);
- if (ci != NULL)
- return (ci->name);
-
- sprintf (s, "ISA#%d", isa);
- return s;
-}
-
-static const char *
-mips_cpu_to_str (cpu)
- int cpu;
-{
- const struct mips_cpu_info *ci;
- static char s[16];
-
- ci = mips_cpu_info_from_cpu (cpu);
- if (ci != NULL)
- return (ci->name);
-
- sprintf (s, "CPU#%d", cpu);
- return s;
-}
-
/* The default target format to use. */
const char *
@@ -1173,7 +1149,7 @@ md_begin ()
if (strcmp (TARGET_OS, "elf") != 0)
flags |= SEC_ALLOC | SEC_LOAD;
- if (file_mips_abi != N64_ABI)
+ if (mips_abi != N64_ABI)
{
sec = subseg_new (".reginfo", (subsegT) 0);
@@ -7759,11 +7735,15 @@ mips_ip (str, ip)
if (!insn_error)
{
static char buf[100];
- sprintf (buf,
- _("opcode not supported on this processor: %s (%s)"),
- mips_cpu_to_str (mips_arch),
- mips_isa_to_str (mips_opts.isa));
-
+ if (mips_arch_info->is_isa)
+ sprintf (buf,
+ _("opcode not supported at this ISA level (%s)"),
+ mips_cpu_info_from_isa (mips_opts.isa)->name);
+ else
+ sprintf (buf,
+ _("opcode not supported on this processor: %s (%s)"),
+ mips_arch_info->name,
+ mips_cpu_info_from_isa (mips_opts.isa)->name);
insn_error = buf;
}
if (save_c)
@@ -9888,8 +9868,8 @@ struct option md_longopts[] =
{"march", required_argument, NULL, OPTION_MARCH},
#define OPTION_MTUNE (OPTION_MD_BASE + 22)
{"mtune", required_argument, NULL, OPTION_MTUNE},
-#define OPTION_MCPU (OPTION_MD_BASE + 23)
- {"mcpu", required_argument, NULL, OPTION_MCPU},
+#define OPTION_FP64 (OPTION_MD_BASE + 23)
+ {"mfp64", no_argument, NULL, OPTION_FP64},
#define OPTION_M4650 (OPTION_MD_BASE + 24)
{"m4650", no_argument, NULL, OPTION_M4650},
#define OPTION_NO_M4650 (OPTION_MD_BASE + 25)
@@ -9942,6 +9922,24 @@ struct option md_longopts[] =
};
size_t md_longopts_size = sizeof (md_longopts);
+/* Set STRING_PTR (either &mips_arch_string or &mips_tune_string) to
+ NEW_VALUE. Warn if another value was already specified. Note:
+ we have to defer parsing the -march and -mtune arguments in order
+ to handle 'from-abi' correctly, since the ABI might be specified
+ in a later argument. */
+
+static void
+mips_set_option_string (string_ptr, new_value)
+ const char **string_ptr, *new_value;
+{
+ if (*string_ptr != 0 && strcasecmp (*string_ptr, new_value) != 0)
+ as_warn (_("A different %s was already specified, is now %s"),
+ string_ptr == &mips_arch_string ? "-march" : "-mtune",
+ new_value);
+
+ *string_ptr = new_value;
+}
+
int
md_parse_option (c, arg)
int c;
@@ -9997,130 +9995,68 @@ md_parse_option (c, arg)
break;
case OPTION_MIPS1:
- mips_opts.isa = ISA_MIPS1;
+ file_mips_isa = ISA_MIPS1;
break;
case OPTION_MIPS2:
- mips_opts.isa = ISA_MIPS2;
+ file_mips_isa = ISA_MIPS2;
break;
case OPTION_MIPS3:
- mips_opts.isa = ISA_MIPS3;
+ file_mips_isa = ISA_MIPS3;
break;
case OPTION_MIPS4:
- mips_opts.isa = ISA_MIPS4;
+ file_mips_isa = ISA_MIPS4;
break;
case OPTION_MIPS5:
- mips_opts.isa = ISA_MIPS5;
+ file_mips_isa = ISA_MIPS5;
break;
case OPTION_MIPS32:
- mips_opts.isa = ISA_MIPS32;
+ file_mips_isa = ISA_MIPS32;
break;
case OPTION_MIPS64:
- mips_opts.isa = ISA_MIPS64;
+ file_mips_isa = ISA_MIPS64;
break;
case OPTION_MTUNE:
- case OPTION_MARCH:
- case OPTION_MCPU:
- {
- int cpu = CPU_UNKNOWN;
-
- /* Identify the processor type. */
- if (strcasecmp (arg, "default") != 0)
- {
- const struct mips_cpu_info *ci;
-
- ci = mips_cpu_info_from_name (arg);
- if (ci == NULL || ci->is_isa)
- {
- switch (c)
- {
- case OPTION_MTUNE:
- as_fatal (_("invalid architecture -mtune=%s"), arg);
- break;
- case OPTION_MARCH:
- as_fatal (_("invalid architecture -march=%s"), arg);
- break;
- case OPTION_MCPU:
- as_fatal (_("invalid architecture -mcpu=%s"), arg);
- break;
- }
- }
- else
- cpu = ci->cpu;
- }
+ mips_set_option_string (&mips_tune_string, arg);
+ break;
- switch (c)
- {
- case OPTION_MTUNE:
- if (mips_tune != CPU_UNKNOWN && mips_tune != cpu)
- as_warn (_("A different -mtune= was already specified, is now "
- "-mtune=%s"), arg);
- mips_tune = cpu;
- break;
- case OPTION_MARCH:
- if (mips_arch != CPU_UNKNOWN && mips_arch != cpu)
- as_warn (_("A different -march= was already specified, is now "
- "-march=%s"), arg);
- mips_arch = cpu;
- break;
- case OPTION_MCPU:
- if (mips_cpu != CPU_UNKNOWN && mips_cpu != cpu)
- as_warn (_("A different -mcpu= was already specified, is now "
- "-mcpu=%s"), arg);
- mips_cpu = cpu;
- }
- }
+ case OPTION_MARCH:
+ mips_set_option_string (&mips_arch_string, arg);
break;
case OPTION_M4650:
- if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_R4650)
- || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_R4650))
- as_warn (_("A different -march= or -mtune= was already specified, "
- "is now -m4650"));
- mips_arch = CPU_R4650;
- mips_tune = CPU_R4650;
+ mips_set_option_string (&mips_arch_string, "4650");
+ mips_set_option_string (&mips_tune_string, "4650");
break;
case OPTION_NO_M4650:
break;
case OPTION_M4010:
- if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_R4010)
- || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_R4010))
- as_warn (_("A different -march= or -mtune= was already specified, "
- "is now -m4010"));
- mips_arch = CPU_R4010;
- mips_tune = CPU_R4010;
+ mips_set_option_string (&mips_arch_string, "4010");
+ mips_set_option_string (&mips_tune_string, "4010");
break;
case OPTION_NO_M4010:
break;
case OPTION_M4100:
- if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_VR4100)
- || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_VR4100))
- as_warn (_("A different -march= or -mtune= was already specified, "
- "is now -m4100"));
- mips_arch = CPU_VR4100;
- mips_tune = CPU_VR4100;
+ mips_set_option_string (&mips_arch_string, "4100");
+ mips_set_option_string (&mips_tune_string, "4100");
break;
case OPTION_NO_M4100:
break;
case OPTION_M3900:
- if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_R3900)
- || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_R3900))
- as_warn (_("A different -march= or -mtune= was already specified, "
- "is now -m3900"));
- mips_arch = CPU_R3900;
- mips_tune = CPU_R3900;
+ mips_set_option_string (&mips_arch_string, "3900");
+ mips_set_option_string (&mips_tune_string, "3900");
break;
case OPTION_NO_M3900:
@@ -10223,7 +10159,7 @@ md_parse_option (c, arg)
as_bad (_("-32 is supported for ELF format only"));
return 0;
}
- mips_opts.abi = O32_ABI;
+ mips_abi = O32_ABI;
break;
case OPTION_N32:
@@ -10232,7 +10168,7 @@ md_parse_option (c, arg)
as_bad (_("-n32 is supported for ELF format only"));
return 0;
}
- mips_opts.abi = N32_ABI;
+ mips_abi = N32_ABI;
break;
case OPTION_64:
@@ -10241,7 +10177,7 @@ md_parse_option (c, arg)
as_bad (_("-64 is supported for ELF format only"));
return 0;
}
- mips_opts.abi = N64_ABI;
+ mips_abi = N64_ABI;
if (! support_64bit_objects())
as_fatal (_("No compiled in support for 64 bit object file format"));
break;
@@ -10249,20 +10185,18 @@ md_parse_option (c, arg)
case OPTION_GP32:
file_mips_gp32 = 1;
- if (mips_opts.abi != O32_ABI)
- mips_opts.abi = NO_ABI;
break;
case OPTION_GP64:
file_mips_gp32 = 0;
- if (mips_opts.abi == O32_ABI)
- mips_opts.abi = NO_ABI;
break;
case OPTION_FP32:
file_mips_fp32 = 1;
- if (mips_opts.abi != O32_ABI)
- mips_opts.abi = NO_ABI;
+ break;
+
+ case OPTION_FP64:
+ file_mips_fp32 = 0;
break;
#ifdef OBJ_ELF
@@ -10273,20 +10207,20 @@ md_parse_option (c, arg)
return 0;
}
if (strcmp (arg, "32") == 0)
- mips_opts.abi = O32_ABI;
+ mips_abi = O32_ABI;
else if (strcmp (arg, "o64") == 0)
- mips_opts.abi = O64_ABI;
+ mips_abi = O64_ABI;
else if (strcmp (arg, "n32") == 0)
- mips_opts.abi = N32_ABI;
+ mips_abi = N32_ABI;
else if (strcmp (arg, "64") == 0)
{
- mips_opts.abi = N64_ABI;
+ mips_abi = N64_ABI;
if (! support_64bit_objects())
as_fatal (_("No compiled in support for 64 bit object file "
"format"));
}
else if (strcmp (arg, "eabi") == 0)
- mips_opts.abi = EABI_ABI;
+ mips_abi = EABI_ABI;
else
{
as_fatal (_("invalid abi -mabi=%s"), arg);
@@ -10319,144 +10253,40 @@ md_parse_option (c, arg)
return 1;
}
+
+/* Set up globals to generate code for the ISA or processor
+ described by INFO. */
static void
-show (stream, string, col_p, first_p)
- FILE *stream;
- char *string;
- int *col_p;
- int *first_p;
+mips_set_architecture (info)
+ const struct mips_cpu_info *info;
{
- if (*first_p)
+ if (info != 0)
{
- fprintf (stream, "%24s", "");
- *col_p = 24;
+ mips_arch_info = info;
+ mips_arch = info->cpu;
+ mips_opts.isa = info->isa;
}
- else
- {
- fprintf (stream, ", ");
- *col_p += 2;
- }
-
- if (*col_p + strlen (string) > 72)
- {
- fprintf (stream, "\n%24s", "");
- *col_p = 24;
- }
-
- fprintf (stream, "%s", string);
- *col_p += strlen (string);
-
- *first_p = 0;
}
-void
-md_show_usage (stream)
- FILE *stream;
-{
- int column, first;
-
- fprintf (stream, _("\
-MIPS options:\n\
--membedded-pic generate embedded position independent code\n\
--EB generate big endian output\n\
--EL generate little endian output\n\
--g, -g2 do not remove unneeded NOPs or swap branches\n\
--G NUM allow referencing objects up to NUM bytes\n\
- implicitly with the gp register [default 8]\n"));
- fprintf (stream, _("\
--mips1 generate MIPS ISA I instructions\n\
--mips2 generate MIPS ISA II instructions\n\
--mips3 generate MIPS ISA III instructions\n\
--mips4 generate MIPS ISA IV instructions\n\
--mips5 generate MIPS ISA V instructions\n\
--mips32 generate MIPS32 ISA instructions\n\
--mips64 generate MIPS64 ISA instructions\n\
--march=CPU/-mtune=CPU generate code/schedule for CPU, where CPU is one of:\n"));
-
- first = 1;
-
- show (stream, "2000", &column, &first);
- show (stream, "3000", &column, &first);
- show (stream, "3900", &column, &first);
- show (stream, "4000", &column, &first);
- show (stream, "4010", &column, &first);
- show (stream, "4100", &column, &first);
- show (stream, "4111", &column, &first);
- show (stream, "4300", &column, &first);
- show (stream, "4400", &column, &first);
- show (stream, "4600", &column, &first);
- show (stream, "4650", &column, &first);
- show (stream, "5000", &column, &first);
- show (stream, "5200", &column, &first);
- show (stream, "5230", &column, &first);
- show (stream, "5231", &column, &first);
- show (stream, "5261", &column, &first);
- show (stream, "5721", &column, &first);
- show (stream, "6000", &column, &first);
- show (stream, "8000", &column, &first);
- show (stream, "10000", &column, &first);
- show (stream, "12000", &column, &first);
- show (stream, "sb1", &column, &first);
- fputc ('\n', stream);
-
- fprintf (stream, _("\
--mCPU equivalent to -march=CPU -mtune=CPU. Deprecated.\n\
--no-mCPU don't generate code specific to CPU.\n\
- For -mCPU and -no-mCPU, CPU must be one of:\n"));
-
- first = 1;
- show (stream, "3900", &column, &first);
- show (stream, "4010", &column, &first);
- show (stream, "4100", &column, &first);
- show (stream, "4650", &column, &first);
- fputc ('\n', stream);
+/* Likewise for tuning. */
- fprintf (stream, _("\
--mips16 generate mips16 instructions\n\
--no-mips16 do not generate mips16 instructions\n"));
- fprintf (stream, _("\
--mgp32 use 32-bit GPRs, regardless of the chosen ISA\n\
--mfp32 use 32-bit FPRs, regardless of the chosen ISA\n\
--O0 remove unneeded NOPs, do not swap branches\n\
--O remove unneeded NOPs and swap branches\n\
--n warn about NOPs generated from macros\n\
---[no-]construct-floats [dis]allow floating point values to be constructed\n\
---trap, --no-break trap exception on div by 0 and mult overflow\n\
---break, --no-trap break exception on div by 0 and mult overflow\n"));
-#ifdef OBJ_ELF
- fprintf (stream, _("\
--KPIC, -call_shared generate SVR4 position independent code\n\
--non_shared do not generate position independent code\n\
--xgot assume a 32 bit GOT\n\
--mabi=ABI create ABI conformant object file for:\n"));
-
- first = 1;
-
- show (stream, "32", &column, &first);
- show (stream, "o64", &column, &first);
- show (stream, "n32", &column, &first);
- show (stream, "64", &column, &first);
- show (stream, "eabi", &column, &first);
+static void
+mips_set_tune (info)
+ const struct mips_cpu_info *info;
+{
+ if (info != 0)
+ {
+ mips_tune_info = info;
+ mips_tune = info->cpu;
+ }
+}
- fputc ('\n', stream);
- fprintf (stream, _("\
--32 create o32 ABI object file (default)\n\
--n32 create n32 ABI object file\n\
--64 create 64 ABI object file\n"));
-#endif
-}
-
void
mips_after_parse_args ()
{
- const char *cpu;
- char *a = NULL;
- int mips_isa_from_cpu;
- const struct mips_cpu_info *ci;
-
/* GP relative stuff not working for PE */
if (strncmp (TARGET_OS, "pe", 2) == 0
&& g_switch_value != 0)
@@ -10466,184 +10296,88 @@ mips_after_parse_args ()
g_switch_value = 0;
}
- cpu = TARGET_CPU;
- if (strcmp (cpu + (sizeof TARGET_CPU) - 3, "el") == 0)
- {
- a = xmalloc (sizeof TARGET_CPU);
- strcpy (a, TARGET_CPU);
- a[(sizeof TARGET_CPU) - 3] = '\0';
- cpu = a;
- }
+ /* The following code determines the architecture, ABI and register
+ size. Similar code was added to GCC 3.2 (see override_options()
+ in config/mips/mips.c). The GAS and GCC code should be kept in
+ sync as much as possible. */
- /* Backward compatibility for historic -mcpu= option. Check for
- incompatible options, warn if -mcpu is used. */
- if (mips_cpu != CPU_UNKNOWN
- && mips_arch != CPU_UNKNOWN
- && mips_cpu != mips_arch)
- {
- as_fatal (_("The -mcpu option can't be used together with -march. "
- "Use -mtune instead of -mcpu."));
- }
+ if (mips_arch_string != 0)
+ mips_set_architecture (mips_parse_cpu ("-march", mips_arch_string));
- if (mips_cpu != CPU_UNKNOWN
- && mips_tune != CPU_UNKNOWN
- && mips_cpu != mips_tune)
- {
- as_fatal (_("The -mcpu option can't be used together with -mtune. "
- "Use -march instead of -mcpu."));
- }
+ if (mips_tune_string != 0)
+ mips_set_tune (mips_parse_cpu ("-mtune", mips_tune_string));
-#if 1
- /* For backward compatibility, let -mipsN set various defaults. */
- /* This code should go away, to be replaced with something rather more
- draconian. Until GCC 3.1 has been released for some reasonable
- amount of time, however, we need to support this. */
- if (mips_opts.isa != ISA_UNKNOWN)
+ if (file_mips_isa != ISA_UNKNOWN)
{
- /* Translate -mipsN to the appropriate settings of file_mips_gp32
- and file_mips_fp32. Tag binaries as using the mipsN ISA. */
- if (file_mips_gp32 < 0)
- {
- if (ISA_HAS_64BIT_REGS (mips_opts.isa))
- file_mips_gp32 = 0;
- else
- file_mips_gp32 = 1;
- }
- if (file_mips_fp32 < 0)
- {
- if (ISA_HAS_64BIT_REGS (mips_opts.isa))
- file_mips_fp32 = 0;
- else
- file_mips_fp32 = 1;
- }
-
- ci = mips_cpu_info_from_isa (mips_opts.isa);
- assert (ci != NULL);
- /* -mipsN has higher priority than -mcpu but lower than -march. */
- if (mips_arch == CPU_UNKNOWN)
- mips_arch = ci->cpu;
-
- /* Default mips_abi. */
- if (mips_opts.abi == NO_ABI)
+ /* Handle -mipsN. At this point, file_mips_isa contains the
+ ISA level specified by -mipsN, while mips_opts.isa contains
+ the -march selection (if any). */
+ if (mips_arch_info != 0)
{
- if (mips_opts.isa == ISA_MIPS1 || mips_opts.isa == ISA_MIPS2)
- mips_opts.abi = O32_ABI;
- else if (mips_opts.isa == ISA_MIPS3 || mips_opts.isa == ISA_MIPS4)
- mips_opts.abi = O64_ABI;
+ /* -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 (file_mips_isa != mips_opts.isa)
+ as_bad (_("-%s conflicts with the other architecture options, which imply -%s"),
+ mips_cpu_info_from_isa (file_mips_isa)->name,
+ mips_cpu_info_from_isa (mips_opts.isa)->name);
}
+ else
+ mips_set_architecture (mips_cpu_info_from_isa (file_mips_isa));
}
- if (mips_arch == CPU_UNKNOWN && mips_cpu != CPU_UNKNOWN)
- {
- ci = mips_cpu_info_from_cpu (mips_cpu);
- assert (ci != NULL);
- mips_arch = ci->cpu;
- as_warn (_("The -mcpu option is deprecated. Please use -march and "
- "-mtune instead."));
- }
+ if (mips_arch_info == 0)
+ mips_set_architecture (mips_parse_cpu ("default CPU",
+ MIPS_CPU_STRING_DEFAULT));
- /* Set tune from -mcpu, not from -mipsN. */
- if (mips_tune == CPU_UNKNOWN && mips_cpu != CPU_UNKNOWN)
- {
- ci = mips_cpu_info_from_cpu (mips_cpu);
- assert (ci != NULL);
- mips_tune = ci->cpu;
- }
+ if (ABI_NEEDS_64BIT_REGS (mips_abi) && !ISA_HAS_64BIT_REGS (mips_opts.isa))
+ as_bad ("-march=%s is not compatible with the selected ABI",
+ mips_arch_info->name);
- /* At this point, mips_arch will either be CPU_UNKNOWN if no ARCH was
- specified on the command line, or some other value if one was.
- Similarly, mips_opts.isa will be ISA_UNKNOWN if not specified on
- the command line, or will be set otherwise if one was. */
+ /* Optimize for mips_arch, unless -mtune selects a different processor. */
+ if (mips_tune_info == 0)
+ mips_set_tune (mips_arch_info);
- if (mips_arch != CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN)
- /* Handled above. */;
-#else
- if (mips_arch == CPU_UNKNOWN && mips_cpu != CPU_UNKNOWN)
+ if (file_mips_gp32 >= 0)
{
- ci = mips_cpu_info_from_cpu (mips_cpu);
- assert (ci != NULL);
- mips_arch = ci->cpu;
- as_warn (_("The -mcpu option is deprecated. Please use -march and "
- "-mtune instead."));
- }
-
- /* At this point, mips_arch will either be CPU_UNKNOWN if no ARCH was
- specified on the command line, or some other value if one was.
- Similarly, mips_opts.isa will be ISA_UNKNOWN if not specified on
- the command line, or will be set otherwise if one was. */
-
- if (mips_arch != CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN)
- {
- /* We have to check if the isa is the default isa of arch. Otherwise
- we'll get invalid object file headers. */
- ci = mips_cpu_info_from_cpu (mips_arch);
- assert (ci != NULL);
- if (mips_opts.isa != ci->isa)
- {
- /* This really should be an error instead of a warning, but old
- compilers only have -mcpu which sets both arch and tune. For
- now, we discard arch and preserve tune. */
- as_warn (_("The -march option is incompatible to -mipsN and "
- "therefore ignored."));
- if (mips_tune == CPU_UNKNOWN)
- mips_tune = mips_arch;
- ci = mips_cpu_info_from_isa (mips_opts.isa);
- assert (ci != NULL);
- mips_arch = ci->cpu;
- }
- }
-#endif
- else if (mips_arch != CPU_UNKNOWN && mips_opts.isa == ISA_UNKNOWN)
- {
- /* We have ARCH, we need ISA. */
- ci = mips_cpu_info_from_cpu (mips_arch);
- assert (ci != NULL);
- mips_opts.isa = ci->isa;
- }
- else if (mips_arch == CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN)
- {
- /* We have ISA, we need default ARCH. */
- ci = mips_cpu_info_from_isa (mips_opts.isa);
- assert (ci != NULL);
- mips_arch = ci->cpu;
+ /* The user specified the size of the integer registers. Make sure
+ it agrees with the ABI and ISA. */
+ if (file_mips_gp32 == 0 && !ISA_HAS_64BIT_REGS (mips_opts.isa))
+ as_bad (_("-mgp64 used with a 32-bit processor"));
+ else if (file_mips_gp32 == 1 && ABI_NEEDS_64BIT_REGS (mips_abi))
+ as_bad (_("-mgp32 used with a 64-bit ABI"));
+ else if (file_mips_gp32 == 0 && ABI_NEEDS_32BIT_REGS (mips_abi))
+ as_bad (_("-mgp64 used with a 32-bit ABI"));
}
else
{
- /* We need to set both ISA and ARCH from target cpu. */
- ci = mips_cpu_info_from_name (cpu);
- if (ci == NULL)
- ci = mips_cpu_info_from_cpu (CPU_R3000);
- assert (ci != NULL);
- mips_opts.isa = ci->isa;
- mips_arch = ci->cpu;
+ /* 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. */
+ file_mips_gp32 = (ABI_NEEDS_32BIT_REGS (mips_abi)
+ || !ISA_HAS_64BIT_REGS (mips_opts.isa));
}
- if (mips_tune == CPU_UNKNOWN)
- mips_tune = mips_arch;
+ /* ??? GAS treats single-float processors as though they had 64-bit
+ float registers (although it complains when double-precision
+ instructions are used). As things stand, saying they have 32-bit
+ registers would lead to spurious "register must be even" messages.
+ So here we assume float registers are always the same size as
+ integer ones, unless the user says otherwise. */
+ if (file_mips_fp32 < 0)
+ file_mips_fp32 = file_mips_gp32;
- ci = mips_cpu_info_from_cpu (mips_arch);
- assert (ci != NULL);
- mips_isa_from_cpu = ci->isa;
+ /* End of GCC-shared inference code. */
- /* End of TARGET_CPU processing, get rid of malloced memory
- if necessary. */
- cpu = NULL;
- if (a != NULL)
- {
- free (a);
- a = NULL;
- }
+ /* ??? When do we want this flag to be set? Who uses it? */
+ if (file_mips_gp32 == 1
+ && mips_abi == NO_ABI
+ && ISA_HAS_64BIT_REGS (mips_opts.isa))
+ mips_32bitmode = 1;
if (mips_opts.isa == ISA_MIPS1 && mips_trap)
as_bad (_("trap exception not supported at ISA 1"));
- /* If they asked for mips1 or mips2 and a cpu that is
- mips3 or greater, then mark the object file 32BITMODE. */
- if (mips_isa_from_cpu != ISA_UNKNOWN
- && ! ISA_HAS_64BIT_REGS (mips_opts.isa)
- && ISA_HAS_64BIT_REGS (mips_isa_from_cpu))
- mips_32bitmode = 1;
-
/* If the selected architecture includes support for ASEs, enable
generation of code for them. */
if (mips_opts.mips16 == -1)
@@ -10653,13 +10387,7 @@ mips_after_parse_args ()
if (mips_opts.ase_mdmx == -1)
mips_opts.ase_mdmx = (CPU_HAS_MDMX (mips_arch)) ? 1 : 0;
- if (file_mips_gp32 < 0)
- file_mips_gp32 = 0;
- if (file_mips_fp32 < 0)
- file_mips_fp32 = 0;
-
file_mips_isa = mips_opts.isa;
- file_mips_abi = mips_opts.abi;
file_ase_mips16 = mips_opts.mips16;
file_ase_mips3d = mips_opts.ase_mips3d;
file_ase_mdmx = mips_opts.ase_mdmx;
@@ -11734,7 +11462,6 @@ s_mipsset (x)
case 0:
mips_opts.gp32 = file_mips_gp32;
mips_opts.fp32 = file_mips_fp32;
- mips_opts.abi = file_mips_abi;
break;
case 1:
case 2:
@@ -11746,9 +11473,6 @@ s_mipsset (x)
case 4:
case 5:
case 64:
- /* Loosen ABI register width restriction. */
- if (mips_opts.abi == O32_ABI)
- mips_opts.abi = NO_ABI;
mips_opts.gp32 = 0;
mips_opts.fp32 = 0;
break;
@@ -13198,7 +12922,7 @@ void
mips_elf_final_processing ()
{
/* Write out the register information. */
- if (file_mips_abi != N64_ABI)
+ if (mips_abi != N64_ABI)
{
Elf32_RegInfo s;
@@ -13248,22 +12972,18 @@ mips_elf_final_processing ()
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_MDMX;
/* Set the MIPS ELF ABI flags. */
- if (file_mips_abi == NO_ABI)
- ;
- else if (file_mips_abi == O32_ABI)
+ if (mips_abi == O32_ABI && USE_E_MIPS_ABI_O32)
elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O32;
- else if (file_mips_abi == O64_ABI)
+ else if (mips_abi == O64_ABI)
elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O64;
- else if (file_mips_abi == EABI_ABI)
+ else if (mips_abi == EABI_ABI)
{
- /* Set the EABI kind based on the ISA. This isn't really
- the best, but then neither is basing the abi on the isa. */
- if (ISA_HAS_64BIT_REGS (file_mips_isa))
+ if (!file_mips_gp32)
elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI64;
else
elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI32;
}
- else if (file_mips_abi == N32_ABI)
+ else if (mips_abi == N32_ABI)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ABI2;
/* Nothing to do for N64_ABI. */
@@ -13704,176 +13424,178 @@ s_loc (x)
}
#endif
-/* CPU name/ISA/number mapping table.
-
- Entries are grouped by type. The first matching CPU or ISA entry
- gets chosen by CPU or ISA, so it should be the 'canonical' name
- for that type. Entries after that within the type are sorted
- alphabetically.
+/* A table describing all the processors gas knows about. Names are
+ matched in the order listed.
- Case is ignored in comparison, so put the canonical entry in the
- appropriate case but everything else in lower case to ease eye pain. */
+ To ease comparison, please keep this table in the same order as
+ gcc's mips_cpu_info_table[]. */
static const struct mips_cpu_info mips_cpu_info_table[] =
{
- /* MIPS1 ISA */
- { "MIPS1", 1, ISA_MIPS1, CPU_R3000, },
- { "mips", 1, ISA_MIPS1, CPU_R3000, },
+ /* Entries for generic ISAs */
+ { "mips1", 1, ISA_MIPS1, CPU_R3000 },
+ { "mips2", 1, ISA_MIPS2, CPU_R6000 },
+ { "mips3", 1, ISA_MIPS3, CPU_R4000 },
+ { "mips4", 1, ISA_MIPS4, CPU_R8000 },
+ { "mips5", 1, ISA_MIPS5, CPU_MIPS5 },
+ { "mips32", 1, ISA_MIPS32, CPU_MIPS32 },
+ { "mips64", 1, ISA_MIPS64, CPU_MIPS64 },
+
+ /* MIPS I */
+ { "r3000", 0, ISA_MIPS1, CPU_R3000 },
+ { "r2000", 0, ISA_MIPS1, CPU_R3000 },
+ { "r3900", 0, ISA_MIPS1, CPU_R3900 },
+
+ /* MIPS II */
+ { "r6000", 0, ISA_MIPS2, CPU_R6000 },
+
+ /* MIPS III */
+ { "r4000", 0, ISA_MIPS3, CPU_R4000 },
+ { "r4010", 0, ISA_MIPS2, CPU_R4010 },
+ { "vr4100", 0, ISA_MIPS3, CPU_VR4100 },
+ { "vr4111", 0, ISA_MIPS3, CPU_R4111 },
+ { "vr4300", 0, ISA_MIPS3, CPU_R4300 },
+ { "r4400", 0, ISA_MIPS3, CPU_R4400 },
+ { "r4600", 0, ISA_MIPS3, CPU_R4600 },
+ { "orion", 0, ISA_MIPS3, CPU_R4600 },
+ { "r4650", 0, ISA_MIPS3, CPU_R4650 },
+
+ /* MIPS IV */
+ { "r8000", 0, ISA_MIPS4, CPU_R8000 },
+ { "r10000", 0, ISA_MIPS4, CPU_R10000 },
+ { "r12000", 0, ISA_MIPS4, CPU_R12000 },
+ { "vr5000", 0, ISA_MIPS4, CPU_R5000 },
+ { "rm5200", 0, ISA_MIPS4, CPU_R5000 },
+ { "rm5230", 0, ISA_MIPS4, CPU_R5000 },
+ { "rm5231", 0, ISA_MIPS4, CPU_R5000 },
+ { "rm5261", 0, ISA_MIPS4, CPU_R5000 },
+ { "rm5721", 0, ISA_MIPS4, CPU_R5000 },
+ { "r7000", 0, ISA_MIPS4, CPU_R5000 },
+
+ /* MIPS 32 */
+ { "4kc", 0, ISA_MIPS32, CPU_MIPS32, },
+ { "4km", 0, ISA_MIPS32, CPU_MIPS32 },
+ { "4kp", 0, ISA_MIPS32, CPU_MIPS32 },
- /* MIPS2 ISA */
- { "MIPS2", 1, ISA_MIPS2, CPU_R6000, },
+ /* MIPS 64 */
+ { "5kc", 0, ISA_MIPS64, CPU_MIPS64 },
+ { "20kc", 0, ISA_MIPS64, CPU_MIPS64 },
- /* MIPS3 ISA */
- { "MIPS3", 1, ISA_MIPS3, CPU_R4000, },
+ /* Broadcom SB-1 CPU */
+ { "SB-1", 0, ISA_MIPS64, CPU_SB1 },
+ { "sb-1250", 0, ISA_MIPS64, CPU_SB1 },
+ { "sb1", 0, ISA_MIPS64, CPU_SB1 },
+ { "sb1250", 0, ISA_MIPS64, CPU_SB1 },
- /* MIPS4 ISA */
- { "MIPS4", 1, ISA_MIPS4, CPU_R8000, },
+ /* End marker */
+ { NULL, 0, 0, 0 }
+};
- /* MIPS5 ISA */
- { "MIPS5", 1, ISA_MIPS5, CPU_MIPS5, },
- { "Generic-MIPS5", 0, ISA_MIPS5, CPU_MIPS5, },
- /* MIPS32 ISA */
- { "MIPS32", 1, ISA_MIPS32, CPU_MIPS32, },
- { "mipsisa32", 0, ISA_MIPS32, CPU_MIPS32, },
- { "Generic-MIPS32", 0, ISA_MIPS32, CPU_MIPS32, },
- { "4kc", 0, ISA_MIPS32, CPU_MIPS32, },
- { "4km", 0, ISA_MIPS32, CPU_MIPS32, },
- { "4kp", 0, ISA_MIPS32, CPU_MIPS32, },
-
- /* For historical reasons. */
- { "MIPS64", 1, ISA_MIPS3, CPU_R4000, },
-
- /* MIPS64 ISA */
- { "mipsisa64", 1, ISA_MIPS64, CPU_MIPS64, },
- { "Generic-MIPS64", 0, ISA_MIPS64, CPU_MIPS64, },
- { "5kc", 0, ISA_MIPS64, CPU_MIPS64, },
- { "20kc", 0, ISA_MIPS64, CPU_MIPS64, },
-
- /* R2000 CPU */
- { "R2000", 0, ISA_MIPS1, CPU_R2000, },
- { "2000", 0, ISA_MIPS1, CPU_R2000, },
- { "2k", 0, ISA_MIPS1, CPU_R2000, },
- { "r2k", 0, ISA_MIPS1, CPU_R2000, },
-
- /* R3000 CPU */
- { "R3000", 0, ISA_MIPS1, CPU_R3000, },
- { "3000", 0, ISA_MIPS1, CPU_R3000, },
- { "3k", 0, ISA_MIPS1, CPU_R3000, },
- { "r3k", 0, ISA_MIPS1, CPU_R3000, },
-
- /* TX3900 CPU */
- { "R3900", 0, ISA_MIPS1, CPU_R3900, },
- { "3900", 0, ISA_MIPS1, CPU_R3900, },
- { "mipstx39", 0, ISA_MIPS1, CPU_R3900, },
-
- /* R4000 CPU */
- { "R4000", 0, ISA_MIPS3, CPU_R4000, },
- { "4000", 0, ISA_MIPS3, CPU_R4000, },
- { "4k", 0, ISA_MIPS3, CPU_R4000, }, /* beware */
- { "r4k", 0, ISA_MIPS3, CPU_R4000, },
-
- /* R4010 CPU */
- { "R4010", 0, ISA_MIPS2, CPU_R4010, },
- { "4010", 0, ISA_MIPS2, CPU_R4010, },
-
- /* R4400 CPU */
- { "R4400", 0, ISA_MIPS3, CPU_R4400, },
- { "4400", 0, ISA_MIPS3, CPU_R4400, },
-
- /* R4600 CPU */
- { "R4600", 0, ISA_MIPS3, CPU_R4600, },
- { "4600", 0, ISA_MIPS3, CPU_R4600, },
- { "mips64orion", 0, ISA_MIPS3, CPU_R4600, },
- { "orion", 0, ISA_MIPS3, CPU_R4600, },
-
- /* R4650 CPU */
- { "R4650", 0, ISA_MIPS3, CPU_R4650, },
- { "4650", 0, ISA_MIPS3, CPU_R4650, },
-
- /* R6000 CPU */
- { "R6000", 0, ISA_MIPS2, CPU_R6000, },
- { "6000", 0, ISA_MIPS2, CPU_R6000, },
- { "6k", 0, ISA_MIPS2, CPU_R6000, },
- { "r6k", 0, ISA_MIPS2, CPU_R6000, },
-
- /* R8000 CPU */
- { "R8000", 0, ISA_MIPS4, CPU_R8000, },
- { "8000", 0, ISA_MIPS4, CPU_R8000, },
- { "8k", 0, ISA_MIPS4, CPU_R8000, },
- { "r8k", 0, ISA_MIPS4, CPU_R8000, },
-
- /* R10000 CPU */
- { "R10000", 0, ISA_MIPS4, CPU_R10000, },
- { "10000", 0, ISA_MIPS4, CPU_R10000, },
- { "10k", 0, ISA_MIPS4, CPU_R10000, },
- { "r10k", 0, ISA_MIPS4, CPU_R10000, },
-
- /* R12000 CPU */
- { "R12000", 0, ISA_MIPS4, CPU_R12000, },
- { "12000", 0, ISA_MIPS4, CPU_R12000, },
- { "12k", 0, ISA_MIPS4, CPU_R12000, },
- { "r12k", 0, ISA_MIPS4, CPU_R12000, },
-
- /* VR4100 CPU */
- { "VR4100", 0, ISA_MIPS3, CPU_VR4100, },
- { "4100", 0, ISA_MIPS3, CPU_VR4100, },
- { "mips64vr4100", 0, ISA_MIPS3, CPU_VR4100, },
- { "r4100", 0, ISA_MIPS3, CPU_VR4100, },
-
- /* VR4111 CPU */
- { "VR4111", 0, ISA_MIPS3, CPU_R4111, },
- { "4111", 0, ISA_MIPS3, CPU_R4111, },
- { "mips64vr4111", 0, ISA_MIPS3, CPU_R4111, },
- { "r4111", 0, ISA_MIPS3, CPU_R4111, },
-
- /* VR4300 CPU */
- { "VR4300", 0, ISA_MIPS3, CPU_R4300, },
- { "4300", 0, ISA_MIPS3, CPU_R4300, },
- { "mips64vr4300", 0, ISA_MIPS3, CPU_R4300, },
- { "r4300", 0, ISA_MIPS3, CPU_R4300, },
-
- /* VR5000 CPU */
- { "VR5000", 0, ISA_MIPS4, CPU_R5000, },
- { "5000", 0, ISA_MIPS4, CPU_R5000, },
- { "5k", 0, ISA_MIPS4, CPU_R5000, },
- { "mips64vr5000", 0, ISA_MIPS4, CPU_R5000, },
- { "r5000", 0, ISA_MIPS4, CPU_R5000, },
- { "r5200", 0, ISA_MIPS4, CPU_R5000, },
- { "rm5200", 0, ISA_MIPS4, CPU_R5000, },
- { "r5230", 0, ISA_MIPS4, CPU_R5000, },
- { "rm5230", 0, ISA_MIPS4, CPU_R5000, },
- { "r5231", 0, ISA_MIPS4, CPU_R5000, },
- { "rm5231", 0, ISA_MIPS4, CPU_R5000, },
- { "r5261", 0, ISA_MIPS4, CPU_R5000, },
- { "rm5261", 0, ISA_MIPS4, CPU_R5000, },
- { "r5721", 0, ISA_MIPS4, CPU_R5000, },
- { "rm5721", 0, ISA_MIPS4, CPU_R5000, },
- { "r5k", 0, ISA_MIPS4, CPU_R5000, },
- { "r7000", 0, ISA_MIPS4, CPU_R5000, },
+/* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL
+ with a final "000" replaced by "k". Ignore case.
- /* Broadcom SB-1 CPU */
- { "SB-1", 0, ISA_MIPS64, CPU_SB1, },
- { "sb-1250", 0, ISA_MIPS64, CPU_SB1, },
- { "sb1", 0, ISA_MIPS64, CPU_SB1, },
- { "sb1250", 0, ISA_MIPS64, CPU_SB1, },
+ Note: this function is shared between GCC and GAS. */
- /* End marker. */
- { NULL, 0, 0, 0, },
-};
+static boolean
+mips_strict_matching_cpu_name_p (canonical, given)
+ const char *canonical, *given;
+{
+ while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical))
+ given++, canonical++;
+
+ return ((*given == 0 && *canonical == 0)
+ || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0));
+}
+
+
+/* Return true if GIVEN matches CANONICAL, where GIVEN is a user-supplied
+ CPU name. We've traditionally allowed a lot of variation here.
+
+ Note: this function is shared between GCC and GAS. */
+
+static boolean
+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;
+
+ /* 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;
+
+ /* 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;
+
+ return mips_strict_matching_cpu_name_p (canonical, given);
+}
+
+
+/* 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.
+
+ A similar function exists in GCC. */
static const struct mips_cpu_info *
-mips_cpu_info_from_name (name)
- const char *name;
+mips_parse_cpu (option, cpu_string)
+ const char *option, *cpu_string;
{
- int i;
+ const struct mips_cpu_info *p;
- for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
- if (strcasecmp (name, mips_cpu_info_table[i].name) == 0)
- return (&mips_cpu_info_table[i]);
+ /* '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 MIPS_DEFAULT_64BIT.
- return NULL;
+ Treat NO_ABI like the EABIs. One reason to do this is that the
+ plain 'mips' and 'mips64' configs have 'from-abi' as their default
+ architecture. This code picks MIPS I for 'mips' and MIPS III for
+ 'mips64', just as we did in the days before 'from-abi'. */
+ if (strcasecmp (cpu_string, "from-abi") == 0)
+ {
+ if (ABI_NEEDS_32BIT_REGS (mips_abi))
+ return mips_cpu_info_from_isa (ISA_MIPS1);
+
+ if (ABI_NEEDS_64BIT_REGS (mips_abi))
+ return mips_cpu_info_from_isa (ISA_MIPS3);
+
+ if (file_mips_gp32 >= 0)
+ return mips_cpu_info_from_isa (file_mips_gp32 ? ISA_MIPS1 : ISA_MIPS3);
+
+ return mips_cpu_info_from_isa (MIPS_DEFAULT_64BIT
+ ? ISA_MIPS3
+ : ISA_MIPS1);
+ }
+
+ /* '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;
+
+ as_bad ("Bad value (%s) for %s", cpu_string, option);
+ return 0;
}
+/* Return the canonical processor information for ISA (a member of the
+ ISA_MIPS* enumeration). */
+
static const struct mips_cpu_info *
mips_cpu_info_from_isa (isa)
int isa;
@@ -13882,22 +13604,119 @@ mips_cpu_info_from_isa (isa)
for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
if (mips_cpu_info_table[i].is_isa
- && isa == mips_cpu_info_table[i].isa)
+ && isa == mips_cpu_info_table[i].isa)
return (&mips_cpu_info_table[i]);
return NULL;
}
+
+static void
+show (stream, string, col_p, first_p)
+ FILE *stream;
+ const char *string;
+ int *col_p;
+ int *first_p;
+{
+ if (*first_p)
+ {
+ fprintf (stream, "%24s", "");
+ *col_p = 24;
+ }
+ else
+ {
+ fprintf (stream, ", ");
+ *col_p += 2;
+ }
-static const struct mips_cpu_info *
-mips_cpu_info_from_cpu (cpu)
- int cpu;
+ if (*col_p + strlen (string) > 72)
+ {
+ fprintf (stream, "\n%24s", "");
+ *col_p = 24;
+ }
+
+ fprintf (stream, "%s", string);
+ *col_p += strlen (string);
+
+ *first_p = 0;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
{
- int i;
+ int column, first;
+ size_t i;
+
+ fprintf (stream, _("\
+MIPS options:\n\
+-membedded-pic generate embedded position independent code\n\
+-EB generate big endian output\n\
+-EL generate little endian output\n\
+-g, -g2 do not remove unneeded NOPs or swap branches\n\
+-G NUM allow referencing objects up to NUM bytes\n\
+ implicitly with the gp register [default 8]\n"));
+ fprintf (stream, _("\
+-mips1 generate MIPS ISA I instructions\n\
+-mips2 generate MIPS ISA II instructions\n\
+-mips3 generate MIPS ISA III instructions\n\
+-mips4 generate MIPS ISA IV instructions\n\
+-mips5 generate MIPS ISA V instructions\n\
+-mips32 generate MIPS32 ISA instructions\n\
+-mips64 generate MIPS64 ISA instructions\n\
+-march=CPU/-mtune=CPU generate code/schedule for CPU, where CPU is one of:\n"));
+
+ first = 1;
for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
- if (!mips_cpu_info_table[i].is_isa
- && cpu == mips_cpu_info_table[i].cpu)
- return (&mips_cpu_info_table[i]);
+ show (stream, mips_cpu_info_table[i].name, &column, &first);
+ show (stream, "from-abi", &column, &first);
+ fputc ('\n', stream);
- return NULL;
+ fprintf (stream, _("\
+-mCPU equivalent to -march=CPU -mtune=CPU. Deprecated.\n\
+-no-mCPU don't generate code specific to CPU.\n\
+ For -mCPU and -no-mCPU, CPU must be one of:\n"));
+
+ first = 1;
+
+ show (stream, "3900", &column, &first);
+ show (stream, "4010", &column, &first);
+ show (stream, "4100", &column, &first);
+ show (stream, "4650", &column, &first);
+ fputc ('\n', stream);
+
+ fprintf (stream, _("\
+-mips16 generate mips16 instructions\n\
+-no-mips16 do not generate mips16 instructions\n"));
+ fprintf (stream, _("\
+-mgp32 use 32-bit GPRs, regardless of the chosen ISA\n\
+-mfp32 use 32-bit FPRs, regardless of the chosen ISA\n\
+-O0 remove unneeded NOPs, do not swap branches\n\
+-O remove unneeded NOPs and swap branches\n\
+-n warn about NOPs generated from macros\n\
+--[no-]construct-floats [dis]allow floating point values to be constructed\n\
+--trap, --no-break trap exception on div by 0 and mult overflow\n\
+--break, --no-trap break exception on div by 0 and mult overflow\n"));
+#ifdef OBJ_ELF
+ fprintf (stream, _("\
+-KPIC, -call_shared generate SVR4 position independent code\n\
+-non_shared do not generate position independent code\n\
+-xgot assume a 32 bit GOT\n\
+-mabi=ABI create ABI conformant object file for:\n"));
+
+ first = 1;
+
+ show (stream, "32", &column, &first);
+ show (stream, "o64", &column, &first);
+ show (stream, "n32", &column, &first);
+ show (stream, "64", &column, &first);
+ show (stream, "eabi", &column, &first);
+
+ fputc ('\n', stream);
+
+ fprintf (stream, _("\
+-32 create o32 ABI object file (default)\n\
+-n32 create n32 ABI object file\n\
+-64 create 64 ABI object file\n"));
+#endif
}