aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-mips.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2000-12-01 21:35:38 +0000
committerNick Clifton <nickc@redhat.com>2000-12-01 21:35:38 +0000
commite7af610e147b2f6f35e2f7dcec4c707027a53757 (patch)
tree981ed717ac072d086d1100528456686af62f1bf2 /gas/config/tc-mips.c
parentb23da31b1cf7d0b7d2ae1d1c4378f8ff77feaf43 (diff)
downloadgdb-e7af610e147b2f6f35e2f7dcec4c707027a53757.zip
gdb-e7af610e147b2f6f35e2f7dcec4c707027a53757.tar.gz
gdb-e7af610e147b2f6f35e2f7dcec4c707027a53757.tar.bz2
Add MIPS32 as a seperate MIPS architecture
Diffstat (limited to 'gas/config/tc-mips.c')
-rw-r--r--gas/config/tc-mips.c673
1 files changed, 323 insertions, 350 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 568d261..fb8c5e6 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -187,10 +187,13 @@ struct mips_set_options
};
/* This is the struct we use to hold the current set of options. Note
- that we must set the isa and mips16 fields to -1 to indicate that
- they have not been initialized. */
+ that we must set the isa field to ISA_UNKNOWN and the mips16 field to
+ -1 to indicate that they have not been initialized. */
-static struct mips_set_options mips_opts = { -1, -1, 0, 0, 0, 0, 0, 0 };
+static struct mips_set_options mips_opts =
+{
+ ISA_UNKNOWN, -1, 0, 0, 0, 0, 0, 0
+};
/* These variables are filled in with the masks of registers used.
The object format code reads them and puts them in the appropriate
@@ -199,10 +202,10 @@ unsigned long mips_gprmask;
unsigned long mips_cprmask[4];
/* MIPS ISA we are using for this output file. */
-static int file_mips_isa;
+static int file_mips_isa = ISA_UNKNOWN;
-/* The CPU type as a number: 2000, 3000, 4000, 4400, etc. */
-static int mips_cpu = -1;
+/* The CPU type we are using for this output file. */
+static int mips_cpu = CPU_UNKNOWN;
/* The argument of the -mabi= flag. */
static char* mips_abi_string = 0;
@@ -226,15 +229,15 @@ static int mips_gp32 = 0;
also assume that ISAs which don't have delays for these insns, don't
have delays for the INSN_LOAD_MEMORY_DELAY instructions either. */
#define ISA_HAS_COPROC_DELAYS(ISA) ( \
- (ISA) == 1 \
- || (ISA) == 2 \
- || (ISA) == 3 \
+ (ISA) == ISA_MIPS1 \
+ || (ISA) == ISA_MIPS2 \
+ || (ISA) == ISA_MIPS3 \
)
/* Return true if ISA supports 64 bit gp register instructions. */
#define ISA_HAS_64BIT_REGS(ISA) ( \
- (ISA) == 3 \
- || (ISA) == 4 \
+ (ISA) == ISA_MIPS3 \
+ || (ISA) == ISA_MIPS4 \
)
/* Whether the processor uses hardware interlocks to protect
@@ -270,7 +273,7 @@ static int mips_gp32 = 0;
/* Whether the processor uses hardware interlocks to protect reads
from the GPRs, and thus does not require nops to be inserted. */
#define gpr_interlocks \
- (mips_opts.isa != 1 \
+ (mips_opts.isa != ISA_MIPS1 \
|| mips_cpu == CPU_R3900)
/* As with other "interlocks" this is used by hardware that has FP
@@ -706,9 +709,24 @@ static void s_mips_stab PARAMS ((int));
static void s_mips_weakext PARAMS ((int));
static void s_file PARAMS ((int));
static int mips16_extended_frag PARAMS ((fragS *, asection *, long));
-static char *mips_cpu_to_str PARAMS ((int));
-
+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 *));
+
+/* Table and functions used to map between CPU/ISA names, and
+ ISA levels, and CPU numbers. */
+
+struct mips_cpu_info
+{
+ const char *name; /* CPU or ISA name. */
+ int is_isa; /* Is this an ISA? (If 0, a CPU.) */
+ int isa; /* ISA level. */
+ int cpu; /* CPU number (default CPU if ISA). */
+};
+
+static const struct mips_cpu_info *mips_cpu_info_from_name PARAMS ((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.
@@ -852,33 +870,34 @@ static boolean mips16_small, mips16_ext;
static segT pdr_seg;
#endif
-static char *
+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];
- switch (cpu)
- {
- case CPU_R2000: return "R2000";
- case CPU_R3000: return "R3000";
- case CPU_R3900: return "R3900";
- case CPU_R4000: return "R4000";
- case CPU_R4010: return "R4010";
- case CPU_VR4100: return "VR4100";
- case CPU_R4111: return "R4111";
- case CPU_R4300: return "R4300";
- case CPU_R4400: return "R4400";
- case CPU_R4600: return "R4600";
- case CPU_R4650: return "R4650";
- case CPU_R5000: return "R5000";
- case CPU_R6000: return "R6000";
- case CPU_R8000: return "R8000";
- case CPU_R10000: return "R10000";
- case CPU_4K: return "4K";
- default:
- sprintf (s, "%d", cpu);
- return s;
- }
+
+ ci = mips_cpu_info_from_cpu (cpu);
+ if (ci != NULL)
+ return (ci->name);
+
+ sprintf (s, "CPU#%d", cpu);
+ return s;
}
/* This function is called once, at assembler startup time. It should
@@ -887,13 +906,14 @@ mips_cpu_to_str (cpu)
void
md_begin ()
{
- boolean ok = false;
register const char *retval = NULL;
int i = 0;
const char *cpu;
char *a = NULL;
int broken = 0;
int mips_isa_from_cpu;
+ int target_cpu_had_mips16 = 0;
+ const struct mips_cpu_info *ci;
/* GP relative stuff not working for PE */
if (strncmp (TARGET_OS, "pe", 2) == 0
@@ -913,130 +933,52 @@ md_begin ()
cpu = a;
}
- if (mips_cpu < 0)
+ if (strncmp (cpu, "mips16", sizeof "mips16" - 1) == 0)
{
- /* Set mips_cpu based on TARGET_CPU, unless TARGET_CPU is
- just the generic 'mips', in which case set mips_cpu based
- on the given ISA, if any. */
-
- if (strcmp (cpu, "mips") == 0)
- {
- if (mips_opts.isa < 0)
- mips_cpu = CPU_R3000;
-
- else if (mips_opts.isa == 2)
- mips_cpu = CPU_R6000;
-
- else if (mips_opts.isa == 3)
- mips_cpu = CPU_R4000;
-
- else if (mips_opts.isa == 4)
- mips_cpu = CPU_R8000;
-
- else
- mips_cpu = CPU_R3000;
- }
-
- else if (strcmp (cpu, "r3900") == 0
- || strcmp (cpu, "mipstx39") == 0
- )
- mips_cpu = CPU_R3900;
-
- else if (strcmp (cpu, "r6000") == 0
- || strcmp (cpu, "mips2") == 0)
- mips_cpu = CPU_R6000;
-
- else if (strcmp (cpu, "mips64") == 0
- || strcmp (cpu, "r4000") == 0
- || strcmp (cpu, "mips3") == 0)
- mips_cpu = CPU_R4000;
-
- else if (strcmp (cpu, "r4400") == 0)
- mips_cpu = CPU_R4400;
-
- else if (strcmp (cpu, "mips64orion") == 0
- || strcmp (cpu, "r4600") == 0)
- mips_cpu = CPU_R4600;
-
- else if (strcmp (cpu, "r4650") == 0)
- mips_cpu = CPU_R4650;
-
- else if (strcmp (cpu, "mips64vr4300") == 0)
- mips_cpu = CPU_R4300;
-
- else if (strcmp (cpu, "mips64vr4111") == 0)
- mips_cpu = CPU_R4111;
-
- else if (strcmp (cpu, "mips64vr4100") == 0)
- mips_cpu = CPU_VR4100;
-
- else if (strcmp (cpu, "r4010") == 0)
- mips_cpu = CPU_R4010;
-
- else if (strcmp (cpu, "4Kc") == 0
- || strcmp (cpu, "4Kp") == 0
- || strcmp (cpu, "4Km") == 0)
- mips_cpu = CPU_4K;
-
- else if (strcmp (cpu, "r5000") == 0
- || strcmp (cpu, "mips64vr5000") == 0)
- mips_cpu = CPU_R5000;
-
- else if (strcmp (cpu, "r8000") == 0
- || strcmp (cpu, "mips4") == 0)
- mips_cpu = CPU_R8000;
-
- else if (strcmp (cpu, "r10000") == 0)
- mips_cpu = CPU_R10000;
-
- else if (strcmp (cpu, "mips16") == 0)
- mips_cpu = 0; /* FIXME */
-
- else
- mips_cpu = CPU_R3000;
+ target_cpu_had_mips16 = 1;
+ cpu += sizeof "mips16" - 1;
}
- if (mips_cpu == CPU_R3000
- || mips_cpu == CPU_R3900)
- mips_isa_from_cpu = 1;
-
- else if (mips_cpu == CPU_R6000
- || mips_cpu == CPU_R4010)
- mips_isa_from_cpu = 2;
-
- else if (mips_cpu == CPU_R4000
- || mips_cpu == CPU_VR4100
- || mips_cpu == CPU_R4111
- || mips_cpu == CPU_R4400
- || mips_cpu == CPU_R4300
- || mips_cpu == CPU_R4600
- || mips_cpu == CPU_R4650)
- mips_isa_from_cpu = 3;
-
- else if (mips_cpu == CPU_R5000
- || mips_cpu == CPU_R8000
- || mips_cpu == CPU_R10000)
- mips_isa_from_cpu = 4;
-
- else
- mips_isa_from_cpu = -1;
+ if (mips_opts.mips16 < 0)
+ mips_opts.mips16 = target_cpu_had_mips16;
- if (mips_opts.isa == -1)
+ /* At this point, mips_cpu will either be CPU_UNKNOWN if no CPU 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_cpu != CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN)
{
- if (mips_isa_from_cpu != -1)
- mips_opts.isa = mips_isa_from_cpu;
- else
- mips_opts.isa = 1;
+ /* We have it all. There's nothing to do. */
}
-
- if (mips_opts.mips16 < 0)
+ else if (mips_cpu != CPU_UNKNOWN && mips_opts.isa == ISA_UNKNOWN)
{
- if (strncmp (TARGET_CPU, "mips16", sizeof "mips16" - 1) == 0)
- mips_opts.mips16 = 1;
- else
- mips_opts.mips16 = 0;
+ /* We have CPU, we need ISA. */
+ ci = mips_cpu_info_from_cpu (mips_cpu);
+ assert (ci != NULL);
+ mips_opts.isa = ci->isa;
+ }
+ else if (mips_cpu == CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN)
+ {
+ /* We have ISA, we need default CPU. */
+ ci = mips_cpu_info_from_isa (mips_opts.isa);
+ assert (ci != NULL);
+ mips_cpu = ci->cpu;
+ }
+ else
+ {
+ /* We need to set both ISA and CPU 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_cpu = ci->cpu;
}
+ ci = mips_cpu_info_from_cpu (mips_cpu);
+ assert (ci != NULL);
+ mips_isa_from_cpu = ci->isa;
+
/* End of TARGET_CPU processing, get rid of malloced memory
if necessary. */
cpu = NULL;
@@ -1046,7 +988,7 @@ md_begin ()
a = NULL;
}
- if (mips_opts.isa == 1 && mips_trap)
+ if (mips_opts.isa == ISA_MIPS1 && mips_trap)
as_bad (_("trap exception not supported at ISA 1"));
/* Set the EABI kind based on the ISA before the user gets
@@ -1057,37 +999,14 @@ md_begin ()
&& 0 == strcmp (mips_abi_string,"eabi"))
mips_eabi64 = 1;
- if (mips_cpu != 0 && mips_cpu != -1)
- {
- ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, mips_cpu);
-
- /* 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 != -1
- && ! ISA_HAS_64BIT_REGS (mips_opts.isa)
- && ISA_HAS_64BIT_REGS (mips_isa_from_cpu))
- mips_32bitmode = 1;
- }
- else
- {
- switch (mips_opts.isa)
- {
- case 1:
- ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, CPU_R3000);
- break;
- case 2:
- ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, CPU_R6000);
- break;
- case 3:
- ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, CPU_R4000);
- break;
- case 4:
- ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, CPU_R8000);
- break;
- }
- }
+ /* 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 (! ok)
+ if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, mips_cpu))
as_warn (_("Could not set architecture and machine"));
file_mips_isa = mips_opts.isa;
@@ -1549,7 +1468,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
&& ISA_HAS_COPROC_DELAYS (mips_opts.isa)
&& (((prev_pinfo & INSN_COPROC_MOVE_DELAY)
&& ! cop_interlocks)
- || (mips_opts.isa == 1
+ || (mips_opts.isa == ISA_MIPS1
&& (prev_pinfo & INSN_COPROC_MEMORY_DELAY))))
{
/* A generic coprocessor delay. The previous instruction
@@ -2083,7 +2002,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
&& ! gpr_interlocks
&& (prev_pinfo & INSN_LOAD_MEMORY_DELAY))
|| (! mips_opts.mips16
- && mips_opts.isa == 1
+ && mips_opts.isa == ISA_MIPS1
/* Itbl support may require additional care here. */
&& (prev_pinfo & INSN_COPROC_MEMORY_DELAY))
/* We can not swap with a branch instruction. */
@@ -2419,7 +2338,7 @@ mips_emit_delays (insns)
&& (prev_insn.insn_mo->pinfo
& INSN_LOAD_MEMORY_DELAY))
|| (! mips_opts.mips16
- && mips_opts.isa == 1
+ && mips_opts.isa == ISA_MIPS1
&& (prev_insn.insn_mo->pinfo
& INSN_COPROC_MEMORY_DELAY)))
{
@@ -5421,7 +5340,7 @@ macro (ip)
s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));
if (strcmp (s, ".lit8") == 0)
{
- if (mips_opts.isa != 1)
+ if (mips_opts.isa != ISA_MIPS1)
{
macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",
"T,o(b)", treg, (int) BFD_RELOC_MIPS_LITERAL, GP);
@@ -5446,7 +5365,7 @@ macro (ip)
macro_build_lui ((char *) NULL, &icnt, &offset_expr, AT);
}
- if (mips_opts.isa != 1)
+ if (mips_opts.isa != ISA_MIPS1)
{
macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",
"T,o(b)", treg, (int) BFD_RELOC_LO16, AT);
@@ -5473,7 +5392,7 @@ macro (ip)
to adjust when loading from memory. */
r = BFD_RELOC_LO16;
dob:
- assert (mips_opts.isa == 1);
+ assert (mips_opts.isa == ISA_MIPS1);
macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
target_big_endian ? treg + 1 : treg,
(int) r, breg);
@@ -5512,7 +5431,7 @@ macro (ip)
}
/* Itbl support may require additional care here. */
coproc = 1;
- if (mips_opts.isa != 1)
+ if (mips_opts.isa != ISA_MIPS1)
{
s = "ldc1";
goto ld;
@@ -5529,7 +5448,7 @@ macro (ip)
return;
}
- if (mips_opts.isa != 1)
+ if (mips_opts.isa != ISA_MIPS1)
{
s = "sdc1";
goto st;
@@ -6157,7 +6076,7 @@ macro2 (ip)
as_bad (_("opcode not supported on this processor"));
return;
}
- assert (mips_opts.isa == 1);
+ assert (mips_opts.isa == ISA_MIPS1);
/* Even on a big endian machine $fn comes before $fn+1. We have
to adjust when storing to memory. */
macro_build ((char *) NULL, &icnt, &offset_expr, "swc1", "T,o(b)",
@@ -6466,7 +6385,7 @@ macro2 (ip)
case M_TRUNCWS:
case M_TRUNCWD:
- assert (mips_opts.isa == 1);
+ assert (mips_opts.isa == ISA_MIPS1);
sreg = (ip->insn_opcode >> 11) & 0x1f; /* floating reg */
dreg = (ip->insn_opcode >> 06) & 0x1f; /* floating reg */
@@ -7146,8 +7065,9 @@ mips_ip (str, ip)
{
static char buf[100];
sprintf (buf,
- _("opcode not supported on this processor: %s (MIPS%d)"),
- mips_cpu_to_str (mips_cpu), mips_opts.isa);
+ _("opcode not supported on this processor: %s (%s)"),
+ mips_cpu_to_str (mips_cpu),
+ mips_isa_to_str (mips_opts.isa));
insn_error = buf;
return;
@@ -8964,9 +8884,6 @@ struct option md_longopts[] =
{"no-construct-floats", no_argument, NULL, OPTION_NO_CONSTRUCT_FLOATS},
#define OPTION_MIPS32 (OPTION_MD_BASE + 28)
{"mips32", no_argument, NULL, OPTION_MIPS32},
-#define OPTION_NO_MIPS32 (OPTION_MD_BASE + 29)
- {"no-mips32", no_argument, NULL, OPTION_NO_MIPS32},
-
#ifdef OBJ_ELF
#define OPTION_ELF_BASE (OPTION_MD_BASE + 35)
#define OPTION_CALL_SHARED (OPTION_ELF_BASE + 0)
@@ -9037,154 +8954,39 @@ md_parse_option (c, arg)
break;
case OPTION_MIPS1:
- mips_opts.isa = 1;
+ mips_opts.isa = ISA_MIPS1;
break;
case OPTION_MIPS2:
- mips_opts.isa = 2;
+ mips_opts.isa = ISA_MIPS2;
break;
case OPTION_MIPS3:
- mips_opts.isa = 3;
+ mips_opts.isa = ISA_MIPS3;
break;
case OPTION_MIPS4:
- mips_opts.isa = 4;
+ mips_opts.isa = ISA_MIPS4;
+ break;
+
+ case OPTION_MIPS32:
+ mips_opts.isa = ISA_MIPS32;
break;
case OPTION_MCPU:
{
- char *p;
-
- /* Identify the processor type */
- p = arg;
- if (strcmp (p, "default") == 0
- || strcmp (p, "DEFAULT") == 0)
- mips_cpu = -1;
+ /* Identify the processor type. */
+ if (strcasecmp (arg, "default") == 0)
+ mips_cpu = CPU_UNKNOWN;
else
{
- int sv = 0;
-
- /* We need to cope with the various "vr" prefixes for the 4300
- processor. */
- if (*p == 'v' || *p == 'V')
- {
- sv = 1;
- p++;
- }
-
- if (*p == 'r' || *p == 'R')
- p++;
-
- mips_cpu = -1;
- switch (*p)
- {
- case '1':
- if (strcmp (p, "10000") == 0
- || strcmp (p, "10k") == 0
- || strcmp (p, "10K") == 0)
- mips_cpu = CPU_R10000;
- break;
-
- case '2':
- if (strcmp (p, "2000") == 0
- || strcmp (p, "2k") == 0
- || strcmp (p, "2K") == 0)
- mips_cpu = CPU_R2000;
- break;
-
- case '3':
- if (strcmp (p, "3000") == 0
- || strcmp (p, "3k") == 0
- || strcmp (p, "3K") == 0)
- mips_cpu = CPU_R3000;
- else if (strcmp (p, "3900") == 0)
- mips_cpu = CPU_R3900;
- break;
-
- case '4':
- if (strcmp (p, "4000") == 0
- || strcmp (p, "4k") == 0
- || strcmp (p, "4K") == 0)
- mips_cpu = CPU_R4000;
- else if (strcmp (p, "4100") == 0)
- mips_cpu = CPU_VR4100;
- else if (strcmp (p, "4111") == 0)
- mips_cpu = CPU_R4111;
- else if (strcmp (p, "4300") == 0)
- mips_cpu = CPU_R4300;
- else if (strcmp (p, "4400") == 0)
- mips_cpu = CPU_R4400;
- else if (strcmp (p, "4600") == 0)
- mips_cpu = CPU_R4600;
- else if (strcmp (p, "4650") == 0)
- mips_cpu = CPU_R4650;
- else if (strcmp (p, "4010") == 0)
- mips_cpu = CPU_R4010;
- else if (strcmp (p, "4Kc") == 0
- || strcmp (p, "4Kp") == 0
- || strcmp (p, "4Km") == 0)
- mips_cpu = CPU_MIPS32;
- break;
-
- case '5':
- if (strcmp (p, "5000") == 0
- || strcmp (p, "5k") == 0
- || strcmp (p, "5K") == 0)
- mips_cpu = CPU_R5000;
- break;
-
- case '6':
- if (strcmp (p, "6000") == 0
- || strcmp (p, "6k") == 0
- || strcmp (p, "6K") == 0)
- mips_cpu = CPU_R6000;
- break;
-
- case '8':
- if (strcmp (p, "8000") == 0
- || strcmp (p, "8k") == 0
- || strcmp (p, "8K") == 0)
- mips_cpu = CPU_R8000;
- break;
-
- case 'o':
- if (strcmp (p, "orion") == 0)
- mips_cpu = CPU_R4600;
- break;
-
- case 'm':
- case 'M':
- switch (atoi (p + 1))
- {
- case 5200:
- case 5230:
- case 5231:
- case 5261:
- case 5721:
- case 7000:
- mips_cpu = CPU_R5000;
- break;
- default:
- break;
- }
- }
-
- if (sv
- && (mips_cpu != CPU_R4300
- && mips_cpu != CPU_VR4100
- && mips_cpu != CPU_R4111
- && mips_cpu != CPU_R5000))
- {
- as_bad (_("ignoring invalid leading 'v' in -mcpu=%s switch"), arg);
- return 0;
- }
+ const struct mips_cpu_info *ci;
- if (mips_cpu == -1)
- {
- as_bad (_("invalid architecture -mcpu=%s"), arg);
- return 0;
- }
+ ci = mips_cpu_info_from_name (arg);
+ if (ci == NULL || ci->is_isa)
+ as_bad (_("invalid architecture -mcpu=%s"), arg);
+ else
+ mips_cpu = ci->cpu;
}
}
break;
@@ -9210,13 +9012,6 @@ md_parse_option (c, arg)
case OPTION_NO_M4100:
break;
- case OPTION_MIPS32:
- mips_cpu = CPU_MIPS32;
- break;
-
- case OPTION_NO_MIPS32:
- break;
-
case OPTION_M3900:
mips_cpu = CPU_R3900;
break;
@@ -9411,6 +9206,7 @@ MIPS options:\n\
-mips2 generate MIPS ISA II instructions\n\
-mips3 generate MIPS ISA III instructions\n\
-mips4 generate MIPS ISA IV instructions\n\
+-mips32 generate MIPS32 ISA instructions\n\
-mcpu=CPU generate code for CPU, where CPU is one of:\n"));
first = 1;
@@ -9430,9 +9226,7 @@ MIPS options:\n\
show (stream, "6000", &column, &first);
show (stream, "8000", &column, &first);
show (stream, "10000", &column, &first);
- show (stream, "4Kc", &column, &first);
- show (stream, "4Kp", &column, &first);
- show (stream, "4Km", &column, &first);
+ show (stream, "mips32-4k", &column, &first);
fputc ('\n', stream);
fprintf (stream, _("\
@@ -9448,9 +9242,6 @@ MIPS options:\n\
show (stream, "4650", &column, &first);
fputc ('\n', stream);
- fprintf (stream, _("\
--mips32 generate MIPS32 instructions\n"));
-
fprintf(stream, _("\
-mips16 generate mips16 instructions\n\
-no-mips16 do not generate mips16 instructions\n"));
@@ -10441,12 +10232,18 @@ s_mipsset (x)
/* Permit the user to change the ISA on the fly. Needless to
say, misuse can cause serious problems. */
isa = atoi (name + 4);
- if (isa == 0)
- mips_opts.isa = file_mips_isa;
- else if (isa < 1 || isa > 4)
- as_bad (_("unknown ISA level"));
- else
- mips_opts.isa = isa;
+ switch (isa)
+ {
+ case 0: mips_opts.isa = file_mips_isa; break;
+ case 1: mips_opts.isa = ISA_MIPS1; break;
+ case 2: mips_opts.isa = ISA_MIPS2; break;
+ case 3: mips_opts.isa = ISA_MIPS3; break;
+ case 4: mips_opts.isa = ISA_MIPS4; break;
+ case 32: mips_opts.isa = ISA_MIPS32; break;
+ default:
+ as_bad (_("unknown ISA level"));
+ break;
+ }
}
else if (strcmp (name, "autoextend") == 0)
mips_opts.noautoextend = 0;
@@ -12092,3 +11889,179 @@ s_loc (x)
symbolP->sy_segment = now_seg;
}
#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.
+
+ Case is ignored in comparison, so put the canonical entry in the
+ appropriate case but everything else in lower case to ease eye pain. */
+static const struct mips_cpu_info mips_cpu_info_table[] =
+{
+ /* MIPS1 ISA */
+ { "MIPS1", 1, ISA_MIPS1, CPU_R3000, },
+ { "mips", 1, ISA_MIPS1, CPU_R3000, },
+
+ /* MIPS2 ISA */
+ { "MIPS2", 1, ISA_MIPS2, CPU_R6000, },
+
+ /* MIPS3 ISA */
+ { "MIPS3", 1, ISA_MIPS3, CPU_R4000, },
+
+ /* MIPS4 ISA */
+ { "MIPS4", 1, ISA_MIPS4, CPU_R8000, },
+
+ /* MIPS32 ISA */
+ { "MIPS32", 1, ISA_MIPS32, CPU_MIPS32, },
+ { "Generic-MIPS32", 0, ISA_MIPS32, CPU_MIPS32, },
+
+ /* XXX for now, MIPS64 -> MIPS3 because of history */
+ { "MIPS64", 1, ISA_MIPS3, CPU_R4000 }, /* XXX! */
+
+ /* 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, },
+
+ /* 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, },
+ { "r5230", 0, ISA_MIPS4, CPU_R5000, },
+ { "r5231", 0, ISA_MIPS4, CPU_R5000, },
+ { "r5261", 0, ISA_MIPS4, CPU_R5000, },
+ { "r5721", 0, ISA_MIPS4, CPU_R5000, },
+ { "r5k", 0, ISA_MIPS4, CPU_R5000, },
+ { "r7000", 0, ISA_MIPS4, CPU_R5000, },
+
+ /* MIPS32 4K CPU */
+ { "MIPS32-4K", 0, ISA_MIPS32, CPU_MIPS32_4K, },
+ { "4kc", 0, ISA_MIPS32, CPU_MIPS32_4K, },
+ { "4km", 0, ISA_MIPS32, CPU_MIPS32_4K, },
+ { "4kp", 0, ISA_MIPS32, CPU_MIPS32_4K, },
+ { "mips32-4kc", 0, ISA_MIPS32, CPU_MIPS32_4K, },
+ { "mips32-4km", 0, ISA_MIPS32, CPU_MIPS32_4K, },
+ { "mips32-4kp", 0, ISA_MIPS32, CPU_MIPS32_4K, },
+
+ /* End marker. */
+ { NULL, 0, 0, 0, },
+};
+
+static const struct mips_cpu_info *
+mips_cpu_info_from_name (name)
+ const char *name;
+{
+ int i;
+
+ 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]);
+
+ return (NULL);
+}
+
+static const struct mips_cpu_info *
+mips_cpu_info_from_isa (isa)
+ int isa;
+{
+ int i;
+
+ 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)
+ return (&mips_cpu_info_table[i]);
+
+ return (NULL);
+}
+
+static const struct mips_cpu_info *
+mips_cpu_info_from_cpu (cpu)
+ int cpu;
+{
+ int i;
+
+ 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]);
+
+ return (NULL);
+}